Implement shift operators
This commit is contained in:
		| @@ -1012,6 +1012,10 @@ namespace boot | ||||
|                 return "or"; | ||||
|             case binary_operator::exclusive_disjunction: | ||||
|                 return "xor"; | ||||
|             case binary_operator::shift_left: | ||||
|                 return "<<"; | ||||
|             case binary_operator::shift_right: | ||||
|                 return ">>"; | ||||
|         } | ||||
|         __builtin_unreachable(); | ||||
|     }; | ||||
|   | ||||
| @@ -137,9 +137,6 @@ return                  { | ||||
| cast                    { | ||||
|                             return yy::parser::make_CAST(this->location); | ||||
|                         } | ||||
| sizeof                  { | ||||
|                             return yy::parser::make_SIZEOF(this->location); | ||||
|                         } | ||||
| defer                   { | ||||
|                             return yy::parser::make_DEFER(this->location); | ||||
|                         } | ||||
| @@ -232,6 +229,12 @@ defer                   { | ||||
| \]                      { | ||||
|                             return yy::parser::make_RIGHT_SQUARE(this->location); | ||||
|                         } | ||||
| \<\<                    { | ||||
|                             return yy::parser::make_SHIFT_LEFT(this->location); | ||||
|                         } | ||||
| \>\>                    { | ||||
|                             return yy::parser::make_SHIFT_RIGHT(this->location); | ||||
|                         } | ||||
| \>=                     { | ||||
|                             return yy::parser::make_GREATER_EQUAL(this->location); | ||||
|                         } | ||||
|   | ||||
| @@ -85,7 +85,7 @@ along with GCC; see the file COPYING3.  If not see | ||||
| %token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION | ||||
| %token BEGIN_BLOCK END_BLOCK EXTERN DEFER | ||||
| %token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA | ||||
| %token AND OR NOT CAST SIZEOF | ||||
| %token AND OR NOT CAST SHIFT_LEFT SHIFT_RIGHT | ||||
| %token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS | ||||
| %token PLUS MINUS MULTIPLICATION DIVISION REMAINDER | ||||
| %token ASSIGNMENT COLON HAT AT NIL ARROW | ||||
| @@ -344,6 +344,16 @@ expression: | ||||
|             $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, | ||||
|                 elna::boot::binary_operator::exclusive_disjunction); | ||||
|         } | ||||
|     | expression SHIFT_LEFT expression | ||||
|         { | ||||
|             $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, | ||||
|                 elna::boot::binary_operator::shift_left); | ||||
|         } | ||||
|     | expression SHIFT_RIGHT expression | ||||
|         { | ||||
|             $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, | ||||
|                 elna::boot::binary_operator::shift_right); | ||||
|         } | ||||
| unary: | ||||
|     AT operand | ||||
|         { | ||||
| @@ -448,7 +458,7 @@ variable_declarations: | ||||
|     | variable_declaration { $$.emplace_back(std::move($1)); } | ||||
| variable_part: | ||||
|     /* no variable declarations */ {} | ||||
|     | VAR variable_declarations SEMICOLON { std::swap($$, $2); } | ||||
|     | VAR variable_declarations { std::swap($$, $2); } | ||||
| constant_definition: identifier_definition EQUALS literal | ||||
|         { | ||||
|             $$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1.first, $1.second, $3); | ||||
|   | ||||
| @@ -575,10 +575,11 @@ namespace gcc | ||||
|         } | ||||
|         if (left_type != right_type | ||||
|                 && !are_compatible_pointers(left_type, right) | ||||
|                 && !are_compatible_pointers(right_type, left)) | ||||
|                 && !are_compatible_pointers(right_type, left) | ||||
|                 && !(is_integral_type(left_type) && right_type == elna_word_type_node)) | ||||
|         { | ||||
|             error_at(expression_location, | ||||
|                     "invalid operands of type %s and %s for operator %s", | ||||
|                     "invalid operands of type '%s' and '%s' for operator %s", | ||||
|                     print_type(left_type).c_str(), print_type(right_type).c_str(), | ||||
|                     boot::print_binary_operator(expression->operation())); | ||||
|             this->current_expression = error_mark_node; | ||||
| @@ -628,6 +629,16 @@ namespace gcc | ||||
|             case boot::binary_operator::not_equals: | ||||
|                 this->current_expression = build_equality_operation(expression, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::shift_left: | ||||
|                 this->current_expression = build_binary_operation( | ||||
|                         is_numeric_type(left_type) && right_type == elna_word_type_node, | ||||
|                         expression, LSHIFT_EXPR, left, right, left_type); | ||||
|                 break; | ||||
|             case boot::binary_operator::shift_right: | ||||
|                 this->current_expression = build_binary_operation( | ||||
|                         is_numeric_type(left_type) && right_type == elna_word_type_node, | ||||
|                         expression, RSHIFT_EXPR, left, right, left_type); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -195,7 +195,7 @@ namespace gcc | ||||
|         else | ||||
|         { | ||||
|             error_at(expression_location, | ||||
|                     "invalid operands of type %s and %s for operator %s", | ||||
|                     "invalid operands of type '%s' and '%s' for operator %s", | ||||
|                     print_type(left_type).c_str(), print_type(right_type).c_str(), | ||||
|                     elna::boot::print_binary_operator(expression->operation())); | ||||
|             return error_mark_node; | ||||
|   | ||||
| @@ -42,7 +42,9 @@ namespace boot | ||||
|         greater_equal, | ||||
|         disjunction, | ||||
|         conjunction, | ||||
|         exclusive_disjunction | ||||
|         exclusive_disjunction, | ||||
|         shift_left, | ||||
|         shift_right | ||||
|     }; | ||||
|  | ||||
|     enum class unary_operator | ||||
|   | ||||
							
								
								
									
										28
									
								
								source.elna
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								source.elna
									
									
									
									
									
								
							| @@ -173,7 +173,7 @@ end | ||||
| proc write_i(value: Int); | ||||
| var | ||||
|   digit: Int, n: Word, | ||||
|   buffer: array 10 of Char; | ||||
|   buffer: array 10 of Char | ||||
| begin | ||||
|   n := 10u; | ||||
|  | ||||
| @@ -230,7 +230,7 @@ end | ||||
|  | ||||
| proc string_dup(origin: String) -> String; | ||||
| var | ||||
|   copy: pointer to Char; | ||||
|   copy: pointer to Char | ||||
| begin | ||||
|   copy := cast(malloc(origin.length): pointer to Char); | ||||
|   strncpy(copy, origin.ptr, origin.length); | ||||
| @@ -244,7 +244,7 @@ end | ||||
|  | ||||
| proc make_position() -> Position; | ||||
| var | ||||
|   result: Position; | ||||
|   result: Position | ||||
| begin | ||||
|   return Position(1u, 1u) | ||||
| end | ||||
| @@ -253,7 +253,7 @@ proc read_source(filename: pointer to Char, result: pointer to String) -> Bool; | ||||
| var | ||||
|   input_file: pointer to FILE, | ||||
|   source_size: Int, | ||||
|   input: pointer to Byte; | ||||
|   input: pointer to Byte | ||||
| begin | ||||
|   input_file := fopen(filename, "rb\0".ptr); | ||||
|  | ||||
| @@ -349,7 +349,7 @@ end | ||||
|  | ||||
| proc lex_identifier(source_code: pointer to SourceCode, token_content: pointer to String); | ||||
| var | ||||
|   content_length: Word; | ||||
|   content_length: Word | ||||
| begin | ||||
|   content_length := 0u; | ||||
|   token_content^ := source_code^.text; | ||||
| @@ -363,7 +363,7 @@ end | ||||
|  | ||||
| proc lex_comment(source_code: pointer to SourceCode, token_content: pointer to String) -> Bool; | ||||
| var | ||||
|   content_length: Word; | ||||
|   content_length: Word | ||||
| begin | ||||
|   content_length := 0u; | ||||
|   token_content^ := source_code^.text; | ||||
| @@ -401,7 +401,7 @@ var | ||||
|   token_end: pointer to Char, | ||||
|   constructed_string: pointer to Char, | ||||
|   token_length: Word, | ||||
|   is_valid: Bool; | ||||
|   is_valid: Bool | ||||
| begin | ||||
|   token_end := input; | ||||
|  | ||||
| @@ -439,7 +439,7 @@ end | ||||
| proc print_tokens(tokens: pointer to Token, tokens_size: Word); | ||||
| var | ||||
|   current_token: pointer to Token, | ||||
|   i: Word; | ||||
|   i: Word | ||||
| begin | ||||
|   i := 0u; | ||||
|   while i < tokens_size do | ||||
| @@ -583,7 +583,7 @@ end | ||||
|  | ||||
| proc categorize_identifier(token_content: String) -> Token; | ||||
| var | ||||
|   current_token: Token; | ||||
|   current_token: Token | ||||
| begin | ||||
|   if "if" = token_content then | ||||
| 	current_token.kind := TOKEN_IF | ||||
| @@ -662,7 +662,7 @@ var | ||||
|   current_token: pointer to Token, | ||||
|   token_length: Word, | ||||
|   first_char: Char, | ||||
|   token_content: String; | ||||
|   token_content: String | ||||
| begin | ||||
|   tokens_size^ := 0u; | ||||
|   tokens := nil; | ||||
| @@ -827,7 +827,7 @@ end | ||||
| proc parse_constant_definition(tokens: pointer to pointer to Token, | ||||
|     tokens_size: pointer to Word) -> pointer to ConstantDefinition; | ||||
| var | ||||
|   result: pointer to ConstantDefinition; | ||||
|   result: pointer to ConstantDefinition | ||||
| begin | ||||
|   result := cast(calloc(1u, ConstantDefinition.size): pointer to ConstantDefinition); | ||||
|  | ||||
| @@ -851,7 +851,7 @@ end | ||||
| proc parse_program(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Program; | ||||
| var | ||||
|   result: pointer to Program, | ||||
|   current_constant: pointer to pointer to ConstantDefinition; | ||||
|   current_constant: pointer to pointer to ConstantDefinition | ||||
| begin | ||||
|   result := cast(calloc(1u, Program.size): pointer to Program); | ||||
|  | ||||
| @@ -885,7 +885,7 @@ proc parse_command_line*(argc: Int, argv: pointer to pointer to Char) -> pointer | ||||
| var | ||||
|   parameter: pointer to pointer to Char, | ||||
|   i: Int, | ||||
|   result: pointer to CommandLine; | ||||
|   result: pointer to CommandLine | ||||
| begin | ||||
|   i := 1; | ||||
|   result := cast(malloc(CommandLine.size): pointer to CommandLine); | ||||
| @@ -927,7 +927,7 @@ var | ||||
|   tokens: pointer to Token, | ||||
|   tokens_size: Word, | ||||
|   source_code: SourceCode, | ||||
|   command_line: pointer to CommandLine; | ||||
|   command_line: pointer to CommandLine | ||||
| begin | ||||
|   command_line := parse_command_line(argc, argv); | ||||
|   if command_line = nil then | ||||
|   | ||||
		Reference in New Issue
	
	Block a user