Extract simple expression parser
This commit is contained in:
@@ -1598,8 +1598,8 @@ begin
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
if token_kind <> _lexer_token_kind_assignment() then
|
||||
(* Else we assume this is a zeroed 81920 bytes big array. *)
|
||||
_write_z(" .zero 81920\0")
|
||||
(* Else we assume this is a zeroed 102400 bytes big array. *)
|
||||
_write_z(" .zero 102400\0")
|
||||
else
|
||||
(* Skip the assignment sign with surrounding whitespaces. *)
|
||||
_lexer_skip_token();
|
||||
@@ -3038,7 +3038,7 @@ begin
|
||||
|
||||
.start_read;
|
||||
(* Second argument is buffer size. Modifying update the source_code definition. *)
|
||||
last_read := _read_file(offset, 81920);
|
||||
last_read := _read_file(offset, 102400);
|
||||
if last_read > 0 then
|
||||
offset := offset + last_read;
|
||||
goto .start_read
|
||||
|
@@ -128,10 +128,14 @@ type
|
||||
_goto,
|
||||
eof
|
||||
);
|
||||
NodeKind := (
|
||||
NodeKind = (
|
||||
integer_literal,
|
||||
string_literal,
|
||||
character_literal
|
||||
character_literal,
|
||||
variable_expression,
|
||||
field_access_expression,
|
||||
dereference_expression,
|
||||
unary_expression
|
||||
);
|
||||
|
||||
const
|
||||
@@ -195,6 +199,7 @@ var
|
||||
proc _string_length(string: Word);
|
||||
var
|
||||
counter: Word;
|
||||
current_byte: Word;
|
||||
begin
|
||||
(* Reset the counter. *)
|
||||
counter := 0;
|
||||
@@ -202,7 +207,8 @@ begin
|
||||
.string_length_loop;
|
||||
string := string + 1;
|
||||
|
||||
if _load_byte(string) <> '"' then
|
||||
current_byte := _load_byte(string);
|
||||
if current_byte <> '"' then
|
||||
counter := counter + 1;
|
||||
goto string_length_loop
|
||||
end;
|
||||
@@ -228,8 +234,8 @@ begin
|
||||
result := compiler_strings_length;
|
||||
|
||||
.add_string_loop;
|
||||
if _load_byte(contents) <> '"' then
|
||||
current_byte := _load_byte(contents);
|
||||
current_byte := _load_byte(contents);
|
||||
if current_byte <> '"' then
|
||||
_store_byte(current_byte, compiler_strings_position);
|
||||
compiler_strings_position := compiler_strings_position + 1;
|
||||
contents := contents + 1;
|
||||
@@ -547,7 +553,8 @@ begin
|
||||
memory_free_pointer := memory_free_pointer + 12;
|
||||
|
||||
integer_token := _lexer_global_get_start();
|
||||
integer_length := _lexer_global_get_end() - integer_token;
|
||||
integer_length := _lexer_global_get_end();
|
||||
integer_length := integer_length - integer_token;
|
||||
_lexer_skip_token();
|
||||
|
||||
_node_set_kind(result, NodeKind.integer_literal);
|
||||
@@ -600,7 +607,8 @@ begin
|
||||
memory_free_pointer := memory_free_pointer + 12;
|
||||
|
||||
character := _lexer_global_get_start();
|
||||
character_length := _lexer_global_get_end() - character;
|
||||
character_length := _lexer_global_get_end();
|
||||
character_length := character_length - character;
|
||||
_lexer_skip_token();
|
||||
|
||||
_node_set_kind(result, NodeKind.character_literal);
|
||||
@@ -623,54 +631,82 @@ begin
|
||||
_write_c('\n');
|
||||
end;
|
||||
|
||||
proc _compile_variable_expression();
|
||||
proc _variable_expression_size();
|
||||
return 12
|
||||
end;
|
||||
|
||||
proc _variable_expression_get_name(this: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _variable_expression_set_name(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _variable_expression_get_length(this: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _variable_expression_set_length(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _allocate(size: Word);
|
||||
var
|
||||
result: Word;
|
||||
begin
|
||||
result := memory_free_pointer;
|
||||
memory_free_pointer := memory_free_pointer + size;
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _parse_variable_expression();
|
||||
var
|
||||
name: Word;
|
||||
lookup_result: Word;
|
||||
name_token: Word;
|
||||
result: Word;
|
||||
memory_size: Word;
|
||||
begin
|
||||
name := _lexer_global_get_start();
|
||||
name_token := _lexer_global_get_end() - name;
|
||||
lookup_result := _symbol_table_lookup(@symbol_table_global, name, name_token);
|
||||
name_token := _lexer_global_get_end();
|
||||
name_token := name_token - name;
|
||||
_lexer_skip_token();
|
||||
|
||||
memory_size := _variable_expression_size();
|
||||
result := _allocate(memory_size);
|
||||
|
||||
_node_set_kind(result, NodeKind.variable_expression);
|
||||
_variable_expression_set_name(result, name);
|
||||
_variable_expression_set_length(result, name_token);
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _compile_variable_expression(variable_expression: Word);
|
||||
var
|
||||
name: Word;
|
||||
name_token: Word;
|
||||
lookup_result: Word;
|
||||
begin
|
||||
name := _variable_expression_get_name(variable_expression);
|
||||
name_token := _variable_expression_get_length(variable_expression);
|
||||
|
||||
lookup_result := _symbol_table_lookup(@symbol_table_local, name, name_token);
|
||||
if lookup_result <> 0 then
|
||||
_compile_enumeration_value(lookup_result)
|
||||
_compile_local_designator(lookup_result)
|
||||
else
|
||||
_compile_designator();
|
||||
_write_z("\tlw t0, (t0)\n\0")
|
||||
_compile_global_designator(variable_expression)
|
||||
end
|
||||
end;
|
||||
|
||||
(**
|
||||
* Compiled take address expression, starting with an "@" sign.
|
||||
*)
|
||||
proc _compile_address_expression();
|
||||
begin
|
||||
_lexer_skip_token();
|
||||
_compile_designator()
|
||||
end;
|
||||
|
||||
(**
|
||||
* Compile unary negation, "-" sign.
|
||||
*)
|
||||
proc _compile_negate_expression();
|
||||
begin
|
||||
_lexer_skip_token();
|
||||
_compile_term();
|
||||
_write_z("\tneg t0, t0\n\0")
|
||||
end;
|
||||
|
||||
(* Compile unary negation, "~" sign. *)
|
||||
proc _compile_not_expression();
|
||||
var
|
||||
token_kind: Word;
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
_lexer_skip_token();
|
||||
_compile_term();
|
||||
_write_z("\tnot t0, t0\n\0")
|
||||
end;
|
||||
|
||||
proc _string_literal_node_size();
|
||||
return 12
|
||||
end;
|
||||
@@ -698,14 +734,16 @@ var
|
||||
length: Word;
|
||||
token_start: Word;
|
||||
result: Word;
|
||||
memory_size: Word;
|
||||
begin
|
||||
result := memory_free_pointer;
|
||||
memory_free_pointer := memory_free_pointer + _string_literal_node_size();
|
||||
memory_size := _string_literal_node_size();
|
||||
result := _allocate(memory_size);
|
||||
|
||||
token_start := _lexer_global_get_start();
|
||||
length := _string_length(token_start);
|
||||
_lexer_skip_token();
|
||||
|
||||
_node_set_kind(result, NodeKind.string_literal);
|
||||
_string_literal_node_set_value(result, token_start);
|
||||
_string_literal_node_set_length(result, length);
|
||||
|
||||
@@ -731,48 +769,206 @@ begin
|
||||
_write_z("\tadd t0, t0, t1\n\0")
|
||||
end;
|
||||
|
||||
proc _compile_term();
|
||||
proc _parse_simple_expression();
|
||||
var
|
||||
current_character: Word;
|
||||
token_kind: Word;
|
||||
parser_node: Word;
|
||||
token_kind: Word;
|
||||
begin
|
||||
parser_node := 0;
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
if token_kind = LexerTokenKind.character then
|
||||
parser_node := _parse_character_literal();
|
||||
_compile_character_literal(parser_node)
|
||||
elsif token_kind = LexerTokenKind.string then
|
||||
parser_node := _parse_string_literal();
|
||||
_compile_string_literal(parser_node)
|
||||
parser_node := _parse_character_literal()
|
||||
elsif token_kind = LexerTokenKind.integer then
|
||||
parser_node := _parse_integer_literal();
|
||||
_compile_integer_literal(parser_node)
|
||||
elsif token_kind = LexerTokenKind.at then
|
||||
_compile_address_expression()
|
||||
elsif token_kind = LexerTokenKind.minus then
|
||||
_compile_negate_expression()
|
||||
elsif token_kind = LexerTokenKind.not then
|
||||
_compile_not_expression()
|
||||
parser_node := _parse_integer_literal()
|
||||
elsif token_kind = LexerTokenKind.string then
|
||||
parser_node := _parse_string_literal()
|
||||
elsif token_kind = LexerTokenKind.identifier then
|
||||
current_character := _lexer_global_get_start();
|
||||
current_character := _load_byte(current_character);
|
||||
|
||||
(* This is a call if the statement starts with an underscore. *)
|
||||
if current_character = '_' then
|
||||
_compile_call();
|
||||
_write_z("\tmv t0, a0\n\0")
|
||||
else
|
||||
_compile_variable_expression()
|
||||
if current_character <> '_' then
|
||||
parser_node := _parse_variable_expression()
|
||||
end
|
||||
end;
|
||||
return parser_node
|
||||
end;
|
||||
|
||||
proc _dereference_expression_size();
|
||||
return 8
|
||||
end;
|
||||
|
||||
proc _dereference_expression_get_pointer(this: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _dereference_expression_set_pointer(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _parse_dereference_expression(simple_expression: Word);
|
||||
var
|
||||
result: Word;
|
||||
memory_size: Word;
|
||||
begin
|
||||
memory_size := _dereference_expression_size();
|
||||
result := _allocate(memory_size);
|
||||
|
||||
_node_set_kind(result, NodeKind.dereference_expression);
|
||||
_dereference_expression_set_pointer(result, simple_expression);
|
||||
_lexer_skip_token();
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _parse_designator();
|
||||
var
|
||||
simple_expression: Word;
|
||||
token_kind: Word;
|
||||
begin
|
||||
simple_expression := _parse_simple_expression();
|
||||
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
if token_kind = LexerTokenKind.hat then
|
||||
simple_expression := _parse_dereference_expression(simple_expression)
|
||||
elsif token_kind = LexerTokenKind.dot then
|
||||
simple_expression := _parse_field_access_expression(simple_expression)
|
||||
end;
|
||||
return simple_expression
|
||||
end;
|
||||
|
||||
proc _compile_simple_expression(parser_node: Word);
|
||||
var
|
||||
is_address: Word;
|
||||
node_kind: Word;
|
||||
begin
|
||||
is_address := 0;
|
||||
node_kind := _node_get_kind(parser_node);
|
||||
|
||||
if node_kind = NodeKind.character_literal then
|
||||
_compile_character_literal(parser_node)
|
||||
elsif node_kind = NodeKind.string_literal then
|
||||
_compile_string_literal(parser_node)
|
||||
elsif node_kind = NodeKind.integer_literal then
|
||||
_compile_integer_literal(parser_node)
|
||||
else
|
||||
_compile_variable_expression(parser_node);
|
||||
is_address := 1
|
||||
end;
|
||||
return is_address
|
||||
end;
|
||||
|
||||
proc _unary_expression_size();
|
||||
return 12
|
||||
end;
|
||||
|
||||
proc _unary_expression_get_operand(this: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _unary_expression_set_operand(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _unary_expression_get_operator(this: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _unary_expression_set_operator(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _parse_unary_expression();
|
||||
var
|
||||
token_kind: Word;
|
||||
result: Word;
|
||||
memory_size: Word;
|
||||
operand: Word;
|
||||
operator: Word;
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
operator := 0;
|
||||
|
||||
if token_kind = LexerTokenKind.at then
|
||||
operator := '@';
|
||||
elsif token_kind = LexerTokenKind.minus then
|
||||
operator := '-';
|
||||
elsif token_kind = LexerTokenKind.not then
|
||||
operator := '~';
|
||||
end;
|
||||
if operator <> 0 then
|
||||
_lexer_skip_token();
|
||||
end;
|
||||
result := _parse_designator();
|
||||
|
||||
if operator <> 0 then
|
||||
operand := result;
|
||||
memory_size := _unary_expression_size();
|
||||
result := _allocate(memory_size);
|
||||
|
||||
_node_set_kind(result, NodeKind.unary_expression);
|
||||
_unary_expression_set_operand(result, operand);
|
||||
_unary_expression_set_operator(result, operator)
|
||||
end;
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _compile_unary_expression(parser_node: Word);
|
||||
var
|
||||
current_character: Word;
|
||||
token_kind: Word;
|
||||
expression_kind: Word;
|
||||
operator: Word;
|
||||
operand: Word;
|
||||
begin
|
||||
operator := 0;
|
||||
operand := 0;
|
||||
|
||||
expression_kind := _node_get_kind(parser_node);
|
||||
|
||||
if expression_kind = NodeKind.unary_expression then
|
||||
operator := _unary_expression_get_operator(parser_node);
|
||||
operand := _unary_expression_get_operand(parser_node)
|
||||
else
|
||||
operand := parser_node
|
||||
end;
|
||||
|
||||
if operator = '@' then
|
||||
_compile_designator(operand)
|
||||
elsif _compile_designator(operand) then
|
||||
_write_z("\tlw t0, (t0) # Designator is an address.\n\0")
|
||||
end;
|
||||
if operator = '-' then
|
||||
_write_z("\tneg t0, t0\n\0")
|
||||
elsif operator = '~' then
|
||||
_write_z("\tnot t0, t0\n\0")
|
||||
end
|
||||
end;
|
||||
|
||||
proc _compile_binary_rhs();
|
||||
var
|
||||
parser_node: Word;
|
||||
begin
|
||||
(* Save the value of the left expression on the stack. *)
|
||||
_write_z("\tsw t0, 64(sp)\n\0");
|
||||
_compile_term();
|
||||
parser_node := _parse_unary_expression();
|
||||
_compile_unary_expression(parser_node);
|
||||
|
||||
(* Load the left expression from the stack; *)
|
||||
_write_z("\tlw t1, 64(sp)\n\0")
|
||||
@@ -781,8 +977,22 @@ end;
|
||||
proc _compile_expression();
|
||||
var
|
||||
token_kind: Word;
|
||||
current_byte: Word;
|
||||
parser_node: Word;
|
||||
begin
|
||||
_compile_term();
|
||||
_lexer_read_token(@token_kind);
|
||||
if token_kind = LexerTokenKind.identifier then
|
||||
current_byte := _lexer_global_get_start();
|
||||
current_byte := _load_byte(current_byte);
|
||||
|
||||
if current_byte = '_' then
|
||||
_compile_call();
|
||||
_write_z("\tmv t0, a0\n\0");
|
||||
goto compile_expression_end
|
||||
end
|
||||
end;
|
||||
parser_node := _parse_unary_expression();
|
||||
_compile_unary_expression(parser_node);
|
||||
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
@@ -885,7 +1095,8 @@ var
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name;
|
||||
argument_count := 0;
|
||||
|
||||
(* Skip the identifier and left paren. *)
|
||||
@@ -964,7 +1175,8 @@ begin
|
||||
_lexer_read_token(@token_kind)
|
||||
end;
|
||||
next_token := _lexer_global_get_start();
|
||||
next_length := _lexer_global_get_end() - next_token;
|
||||
next_length := _lexer_global_get_end();
|
||||
next_length := next_length - next_token;
|
||||
|
||||
_write_z("\tj .\0");
|
||||
|
||||
@@ -979,28 +1191,64 @@ begin
|
||||
_write_z("\taddi t0, sp, \0");
|
||||
variable_offset := _parameter_info_get_offset(symbol);
|
||||
_write_i(variable_offset);
|
||||
_write_c('\n');
|
||||
_lexer_skip_token()
|
||||
_write_c('\n')
|
||||
end;
|
||||
|
||||
proc _compile_global_designator();
|
||||
proc _compile_global_designator(variable_expression: Word);
|
||||
var
|
||||
name: Word;
|
||||
token_kind: Word;
|
||||
token_length: Word;
|
||||
begin
|
||||
_write_z("\tla t0, \0");
|
||||
|
||||
_lexer_read_token(@token_kind);
|
||||
name := _lexer_global_get_start();
|
||||
token_length := _lexer_global_get_end() - name;
|
||||
_write_s(name, token_length);
|
||||
_lexer_skip_token();
|
||||
name := _variable_expression_get_name(variable_expression);
|
||||
token_length := _variable_expression_get_length(variable_expression);
|
||||
|
||||
_write_s(name, token_length);
|
||||
_write_c('\n')
|
||||
end;
|
||||
|
||||
proc _compile_enumeration_value(symbol: Word);
|
||||
proc _field_access_expression_size();
|
||||
return 16
|
||||
end;
|
||||
|
||||
proc _field_access_expression_get_aggregate(this: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _field_access_expression_set_aggregate(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 4;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _field_access_expression_get_field(this: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _field_access_expression_set_field(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 8;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _field_access_expression_get_length(this: Word);
|
||||
begin
|
||||
this := this + 12;
|
||||
return this^
|
||||
end;
|
||||
|
||||
proc _field_access_expression_set_length(this: Word, value: Word);
|
||||
begin
|
||||
this := this + 12;
|
||||
this^ := value
|
||||
end;
|
||||
|
||||
proc _compile_enumeration_value(field_access_expression: Word);
|
||||
var
|
||||
enumeration_type: Word;
|
||||
members: Word;
|
||||
@@ -1011,20 +1259,22 @@ var
|
||||
member_name: Word;
|
||||
member_length: Word;
|
||||
counter: Word;
|
||||
symbol: Word;
|
||||
begin
|
||||
symbol := _field_access_expression_get_aggregate(field_access_expression);
|
||||
value_name := _variable_expression_get_name(symbol);
|
||||
name_length := _variable_expression_get_length(symbol);
|
||||
|
||||
symbol := _symbol_table_lookup(@symbol_table_global, value_name, name_length);
|
||||
|
||||
enumeration_type := _type_info_get_type(symbol);
|
||||
members := _enumeration_type_get_members(enumeration_type);
|
||||
members_length := _enumeration_type_get_length(enumeration_type);
|
||||
|
||||
(* Skip enumeration type name and dot. Read the enumeration value. *)
|
||||
_lexer_skip_token();
|
||||
_lexer_read_token(@token_type);
|
||||
_lexer_skip_token();
|
||||
_lexer_read_token(@token_type);
|
||||
|
||||
value_name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - value_name;
|
||||
_lexer_skip_token();
|
||||
value_name := _field_access_expression_get_field(field_access_expression);
|
||||
name_length := _field_access_expression_get_length(field_access_expression);
|
||||
counter := 1;
|
||||
|
||||
.compile_enumeration_value_members;
|
||||
@@ -1032,7 +1282,8 @@ begin
|
||||
member_name := members^;
|
||||
member_length := _load_word(members + 4);
|
||||
|
||||
if _lexer_compare_keyword(value_name, name_length, member_name, member_length) = 0 then
|
||||
if _lexer_compare_keyword(value_name, name_length, member_name, member_length) then
|
||||
else
|
||||
members_length := members_length - 1;
|
||||
members := members + 8;
|
||||
counter := counter + 1;
|
||||
@@ -1044,35 +1295,64 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
proc _compile_designator();
|
||||
proc _parse_field_access_expression(aggregate: Word);
|
||||
var
|
||||
token_kind: Word;
|
||||
name: Word;
|
||||
name_token: Word;
|
||||
result: Word;
|
||||
memory_size: Word;
|
||||
begin
|
||||
(* Skip dot. Read the enumeration value. *)
|
||||
_lexer_skip_token();
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
name := _lexer_global_get_start();
|
||||
name_token := _lexer_global_get_end();
|
||||
name_token := name_token - name;
|
||||
_lexer_skip_token();
|
||||
memory_size := _field_access_expression_size();
|
||||
result := _allocate(memory_size);
|
||||
|
||||
_node_set_kind(result, NodeKind.field_access_expression);
|
||||
_field_access_expression_set_aggregate(result, aggregate);
|
||||
_field_access_expression_set_field(result, name);
|
||||
_field_access_expression_set_length(result, name_token);
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _compile_designator(parser_node: Word);
|
||||
var
|
||||
name_token: Word;
|
||||
lookup_result: Word;
|
||||
token_kind: Word;
|
||||
name: Word;
|
||||
parser_node: Word;
|
||||
is_address: Word;
|
||||
node_kind: Word;
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
name := _lexer_global_get_start();
|
||||
name_token := _lexer_global_get_end() - name;
|
||||
lookup_result := _symbol_table_lookup(@symbol_table_local, name, name_token);
|
||||
is_address := 1;
|
||||
node_kind := _node_get_kind(parser_node);
|
||||
|
||||
if lookup_result <> 0 then
|
||||
_compile_local_designator(lookup_result)
|
||||
else
|
||||
_compile_global_designator()
|
||||
end;
|
||||
_lexer_read_token(@token_kind);
|
||||
if token_kind = LexerTokenKind.hat then
|
||||
_lexer_skip_token();
|
||||
if node_kind = NodeKind.dereference_expression then
|
||||
parser_node := _dereference_expression_get_pointer(parser_node);
|
||||
_compile_simple_expression(parser_node);
|
||||
_write_z("\tlw t0, (t0)\n\0")
|
||||
end
|
||||
elsif node_kind = NodeKind.field_access_expression then
|
||||
_compile_enumeration_value(parser_node);
|
||||
is_address := 0
|
||||
else
|
||||
is_address := _compile_simple_expression(parser_node)
|
||||
end;
|
||||
return is_address
|
||||
end;
|
||||
|
||||
proc _compile_assignment();
|
||||
var
|
||||
token_kind: Word;
|
||||
begin
|
||||
_compile_designator();
|
||||
token_kind := _parse_designator();
|
||||
_compile_designator(token_kind);
|
||||
|
||||
(* Save the assignee address on the stack. *)
|
||||
_write_z("\tsw t0, 60(sp)\n\0");
|
||||
@@ -1082,6 +1362,7 @@ begin
|
||||
_lexer_skip_token();
|
||||
|
||||
(* Compile the assignment. *)
|
||||
_lexer_read_token(@token_kind);
|
||||
_compile_expression();
|
||||
|
||||
_write_z("\tlw t1, 60(sp)\n\tsw t0, (t1)\n\0")
|
||||
@@ -1182,7 +1463,8 @@ begin
|
||||
_lexer_skip_token();
|
||||
_lexer_read_token(@token_kind);
|
||||
name := _lexer_global_get_start();
|
||||
label_token := _lexer_global_get_end() - name;
|
||||
label_token := _lexer_global_get_end();
|
||||
label_token := label_token - name;
|
||||
_write_c('.');
|
||||
_write_s(name, label_token);
|
||||
_write_z(":\n\0");
|
||||
@@ -1315,7 +1597,8 @@ begin
|
||||
member_count := member_count + 1;
|
||||
|
||||
enumeration_name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - enumeration_name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - enumeration_name;
|
||||
|
||||
_store_word(enumeration_name, memory_free_pointer);
|
||||
memory_free_pointer := memory_free_pointer + 4;
|
||||
@@ -1362,7 +1645,8 @@ begin
|
||||
if token_kind = LexerTokenKind.identifier then
|
||||
(* Named type. *)
|
||||
type_name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - type_name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - type_name;
|
||||
result := _symbol_table_lookup(@symbol_table_global, type_name, name_length);
|
||||
result := _type_info_get_type(result);
|
||||
|
||||
@@ -1473,7 +1757,8 @@ begin
|
||||
(* Read the parameter name. *)
|
||||
_lexer_read_token(@token_kind);
|
||||
name_position := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name_position;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name_position;
|
||||
_lexer_skip_token();
|
||||
|
||||
(* Skip colon and space in front of the type expression. *)
|
||||
@@ -1535,7 +1820,8 @@ var
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
name_position := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name_position;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name_position;
|
||||
_lexer_skip_token();
|
||||
|
||||
(* Read and skip variable name, colon and the space *)
|
||||
@@ -1590,7 +1876,8 @@ begin
|
||||
|
||||
_lexer_read_token(@token_kind);
|
||||
name_pointer := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name_pointer;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name_pointer;
|
||||
|
||||
(* Write .type _procedure_name, @function. *)
|
||||
_write_z(".type \0");
|
||||
@@ -1689,14 +1976,20 @@ begin
|
||||
_lexer_skip_token();
|
||||
_write_z("\n\t.word \0");
|
||||
_lexer_read_token(@token_kind);
|
||||
token_start := _lexer_global_get_start();
|
||||
_write_s(token_start, _lexer_global_get_end() - token_start);
|
||||
_lexer_skip_token();
|
||||
|
||||
token_start := _lexer_global_get_start();
|
||||
length := _lexer_global_get_end();
|
||||
length := length - token_start;
|
||||
_write_s(token_start, length);
|
||||
|
||||
_lexer_skip_token();
|
||||
goto compile_global_initializer_end
|
||||
elsif token_kind = LexerTokenKind.integer then
|
||||
_write_z("\n\t.word \0");
|
||||
_write_s(token_start, _lexer_global_get_end() - token_start);
|
||||
|
||||
length := _lexer_global_get_end();
|
||||
length := length - token_start;
|
||||
_write_s(token_start, length);
|
||||
_lexer_skip_token();
|
||||
|
||||
goto compile_global_initializer_end
|
||||
@@ -1727,7 +2020,8 @@ var
|
||||
token_kind: Word;
|
||||
begin
|
||||
name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name;
|
||||
|
||||
_write_z(".type \0");
|
||||
_write_s(name, name_length);
|
||||
@@ -1756,7 +2050,8 @@ var
|
||||
type_info: Word;
|
||||
begin
|
||||
type_name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - type_name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - type_name;
|
||||
|
||||
_lexer_skip_token();
|
||||
_lexer_read_token(@token_kind);
|
||||
@@ -1829,7 +2124,8 @@ var
|
||||
begin
|
||||
_lexer_read_token(@token_kind);
|
||||
name := _lexer_global_get_start();
|
||||
name_length := _lexer_global_get_end() - name;
|
||||
name_length := _lexer_global_get_end();
|
||||
name_length := name_length - name;
|
||||
|
||||
_write_z(".type \0");
|
||||
_write_s(name, name_length);
|
||||
@@ -1847,8 +2143,8 @@ begin
|
||||
_lexer_read_token(@token_kind);
|
||||
|
||||
if token_kind <> LexerTokenKind.assignment then
|
||||
(* Else we assume this is a zeroed 81920 bytes big array. *)
|
||||
_write_z(" .zero 81920\0")
|
||||
(* Else we assume this is a zeroed 102400 bytes big array. *)
|
||||
_write_z(" .zero 102400\0")
|
||||
else
|
||||
(* Skip the assignment sign with surrounding whitespaces. *)
|
||||
_lexer_skip_token();
|
||||
@@ -1993,7 +2289,7 @@ begin
|
||||
goto symbol_table_lookup_repeat
|
||||
end;
|
||||
(* If names don't match, exit and return nil. *)
|
||||
if _memcmp(symbol_name, current_name, name_length) <> 0 then
|
||||
if _memcmp(symbol_name, current_name, name_length) then
|
||||
goto symbol_table_lookup_repeat
|
||||
end;
|
||||
(* Otherwise, the symbol is found. *)
|
||||
@@ -2248,7 +2544,8 @@ begin
|
||||
column_position := character_class - 1;
|
||||
column_position := column_position * 8;
|
||||
|
||||
target := _lexer_get_transition_table() + row_position;
|
||||
target := _lexer_get_transition_table();
|
||||
target := target + row_position;
|
||||
|
||||
return target + column_position
|
||||
end;
|
||||
@@ -2439,7 +2736,11 @@ end;
|
||||
* and 22 columns (character classes), so 2992 = 8 * 17 * 22.
|
||||
*)
|
||||
proc _lexer_global_state();
|
||||
return _lexer_get_transition_table() + 2992
|
||||
var
|
||||
result: Word;
|
||||
begin
|
||||
result := _lexer_get_transition_table();
|
||||
return result + 2992
|
||||
end;
|
||||
|
||||
(**
|
||||
@@ -2449,7 +2750,8 @@ proc _lexer_global_get_start();
|
||||
var
|
||||
target: Word;
|
||||
begin
|
||||
target := _lexer_global_state() + 4;
|
||||
target := _lexer_global_state();
|
||||
target := target + 4;
|
||||
return target^
|
||||
end;
|
||||
|
||||
@@ -2460,8 +2762,9 @@ proc _lexer_global_set_start(new_start: Word);
|
||||
var
|
||||
target: Word;
|
||||
begin
|
||||
target := _lexer_global_state() + 4;
|
||||
_store_word(new_start, target)
|
||||
target := _lexer_global_state();
|
||||
target := target + 4;
|
||||
target^ := new_start
|
||||
end;
|
||||
|
||||
(**
|
||||
@@ -2471,7 +2774,8 @@ proc _lexer_global_get_end();
|
||||
var
|
||||
target: Word;
|
||||
begin
|
||||
target := _lexer_global_state() + 8;
|
||||
target := _lexer_global_state();
|
||||
target := target + 8;
|
||||
return target^
|
||||
end;
|
||||
|
||||
@@ -2482,8 +2786,9 @@ proc _lexer_global_set_end(new_start: Word);
|
||||
var
|
||||
target: Word;
|
||||
begin
|
||||
target := _lexer_global_state() + 8;
|
||||
_store_word(new_start, target)
|
||||
target := _lexer_global_state();
|
||||
target := target + 8;
|
||||
target^ := new_start
|
||||
end;
|
||||
|
||||
proc _lexer_transition_get_action(transition: Word);
|
||||
@@ -2555,7 +2860,8 @@ begin
|
||||
result := 0;
|
||||
|
||||
if lhs_length = rhs_length then
|
||||
result := _memcmp(lhs_pointer, rhs_pointer, lhs_length) = 0
|
||||
result := _memcmp(lhs_pointer, rhs_pointer, lhs_length);
|
||||
result := result = 0
|
||||
end;
|
||||
return result
|
||||
end;
|
||||
@@ -2568,35 +2874,35 @@ begin
|
||||
result := LexerTokenKind.identifier;
|
||||
token_length := position_end - position_start;
|
||||
|
||||
if _lexer_compare_keyword(position_start, token_length, "const", 5) = 1 then
|
||||
if _lexer_compare_keyword(position_start, token_length, "const", 5) then
|
||||
result := LexerTokenKind._const
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "var", 3) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "var", 3) then
|
||||
result := LexerTokenKind._var
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "proc", 4) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "proc", 4) then
|
||||
result := LexerTokenKind._proc
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "type", 4) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "type", 4) then
|
||||
result := LexerTokenKind._type
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "begin", 5) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "begin", 5) then
|
||||
result := LexerTokenKind._begin
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "end", 3) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "end", 3) then
|
||||
result := LexerTokenKind._end
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "return", 6) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "return", 6) then
|
||||
result := LexerTokenKind._return
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "goto", 4) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "goto", 4) then
|
||||
result := LexerTokenKind._goto
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "if", 2) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "if", 2) then
|
||||
result := LexerTokenKind._if
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "while", 5) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "while", 5) then
|
||||
result := LexerTokenKind._while
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "then", 4) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "then", 4) then
|
||||
result := LexerTokenKind._then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "else", 4) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "else", 4) then
|
||||
result := LexerTokenKind._else
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "elsif", 5) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "elsif", 5) then
|
||||
result := LexerTokenKind._elsif
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "or", 2) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "or", 2) then
|
||||
result := LexerTokenKind._or
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "xor", 2) = 1 then
|
||||
elsif _lexer_compare_keyword(position_start, token_length, "xor", 2) then
|
||||
result := LexerTokenKind._xor
|
||||
end;
|
||||
return result
|
||||
@@ -2779,8 +3085,11 @@ begin
|
||||
end;
|
||||
|
||||
proc _lexer_advance_token(kind: Word);
|
||||
var
|
||||
result_state: Word;
|
||||
begin
|
||||
if _lexer_execute_transition(kind) <> LexerState.finish then
|
||||
result_state := _lexer_execute_transition(kind);
|
||||
if result_state <> LexerState.finish then
|
||||
_lexer_advance_token(kind)
|
||||
end
|
||||
end;
|
||||
@@ -2821,7 +3130,7 @@ begin
|
||||
|
||||
.start_read;
|
||||
(* Second argument is buffer size. Modifying update the source_code definition. *)
|
||||
last_read := _read_file(offset, 81920);
|
||||
last_read := _read_file(offset, 102400);
|
||||
if last_read > 0 then
|
||||
offset := offset + last_read;
|
||||
goto start_read
|
||||
|
Reference in New Issue
Block a user