Implement shift operators
This commit is contained in:
parent
ee4ebf64b9
commit
82b3806fd2
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user