Set expression type for enumeration values
This commit is contained in:
@@ -24,6 +24,10 @@ type
|
||||
ElnaTreeNode = record
|
||||
kind: Word
|
||||
end;
|
||||
ElnaTreeExpression = record
|
||||
kind: Word;
|
||||
type_decoration: Word
|
||||
end;
|
||||
ElnaTreeIntegerLiteral = record
|
||||
kind: Word;
|
||||
type_decoration: Word;
|
||||
@@ -1581,7 +1585,7 @@ begin
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.integer_literal);
|
||||
ElnaTreeIntegerLiteral_set_value(result, integer_token);
|
||||
ElnaTreeIntegerLiteral_set_length(result, integer_length);
|
||||
ElnaTreeIntegerLiteral_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -1594,7 +1598,7 @@ begin
|
||||
|
||||
result := malloc(ElnaTreeNilLiteral_size());
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.null);
|
||||
ElnaTreeIntegerLiteral_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -1633,7 +1637,7 @@ begin
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.character_literal);
|
||||
ElnaTreeIntegerLiteral_set_value(result, character);
|
||||
ElnaTreeIntegerLiteral_set_length(result, character_length);
|
||||
ElnaTreeIntegerLiteral_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -1662,7 +1666,7 @@ begin
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_expression);
|
||||
ElnaTreeVariableExpression_set_name(result, name_pointer);
|
||||
ElnaTreeVariableExpression_set_length(result, name_length);
|
||||
ElnaTreeVariableExpression_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -1704,7 +1708,7 @@ begin
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.string_literal);
|
||||
ElnaTreeStringLiteral_set_value(result, token_start);
|
||||
ElnaTreeStringLiteral_set_length(result, length);
|
||||
ElnaTreeIntegerLiteral_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -1767,7 +1771,7 @@ begin
|
||||
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.dereference_expression);
|
||||
ElnaTreeDereferenceExpression_set_pointer(result, simple_expression);
|
||||
ElnaTreeDereferenceExpression_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
_elna_lexer_skip_token();
|
||||
|
||||
return result
|
||||
@@ -1842,7 +1846,7 @@ begin
|
||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.unary_expression);
|
||||
ElnaTreeUnaryExpression_set_operand(result, operand);
|
||||
ElnaTreeUnaryExpression_set_operator(result, operator);
|
||||
ElnaTreeUnaryExpression_set_type_decoration(result, nil)
|
||||
ElnaTreeExpression_set_type_decoration(result, nil)
|
||||
end;
|
||||
|
||||
return result
|
||||
@@ -1986,7 +1990,7 @@ begin
|
||||
ElnaTreeBinaryExpression_set_lhs(result, lhs_node);
|
||||
ElnaTreeBinaryExpression_set_rhs(result, rhs_node);
|
||||
ElnaTreeBinaryExpression_set_operator(result, token_kind);
|
||||
ElnaTreeBinaryExpression_set_type_decoration(result, nil)
|
||||
ElnaTreeExpression_set_type_decoration(result, nil)
|
||||
else
|
||||
result := lhs_node
|
||||
end;
|
||||
@@ -2368,7 +2372,7 @@ begin
|
||||
operand_value^ := counter;
|
||||
operand_length^ := 0
|
||||
end;
|
||||
return 0
|
||||
return nil
|
||||
end;
|
||||
|
||||
proc elna_parser_field_access_expression(aggregate: Word);
|
||||
@@ -2392,7 +2396,7 @@ begin
|
||||
ElnaTreeFieldAccessExpression_set_aggregate(result, aggregate);
|
||||
ElnaTreeFieldAccessExpression_set_field(result, name_pointer);
|
||||
ElnaTreeFieldAccessExpression_set_length(result, name_length);
|
||||
ElnaTreeFieldAccessExpression_set_type_decoration(result, nil);
|
||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -2401,8 +2405,12 @@ proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Wor
|
||||
var
|
||||
parser_node: Word;
|
||||
node_kind: Word;
|
||||
expression_type: Word;
|
||||
first_instruction: Word;
|
||||
last_instruction: Word;
|
||||
|
||||
name_pointer: Word;
|
||||
name_length: Word;
|
||||
begin
|
||||
node_kind := ElnaTreeNode_get_kind(parser_node);
|
||||
|
||||
@@ -2421,7 +2429,26 @@ begin
|
||||
is_address^ := 2;
|
||||
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
||||
elsif node_kind = ElnaTreeKind.field_access_expression then
|
||||
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
|
||||
expression_type := ElnaTreeExpression_get_type_decoration(parser_node);
|
||||
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
||||
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
||||
|
||||
if expression_type = nil then
|
||||
(* Stub for record field access. Always generate nil for field access expression until it is implemented. *)
|
||||
|
||||
(* Debug. Error stream output.
|
||||
_syscall(2, name_pointer, name_length, 0, 0, 0, 64);
|
||||
printf("# there %.*s %i\n\0", name_length, name_pointer, expression_type);
|
||||
fflush(0); *)
|
||||
|
||||
operand_type^ := ElnaTacOperand.immediate;
|
||||
operand_value^ := 0;
|
||||
operand_length^ := 0;
|
||||
|
||||
first_instruction := nil
|
||||
else
|
||||
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length)
|
||||
end;
|
||||
is_address^ := 0
|
||||
elsif node_kind = ElnaTreeKind.call then
|
||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
||||
@@ -3241,8 +3268,9 @@ end;
|
||||
(**
|
||||
* Parameters:
|
||||
* parameter_index - Parameter index.
|
||||
* parameter_type - Parameter type.
|
||||
*)
|
||||
proc _parameter_info_create(parameter_index: Word);
|
||||
proc _parameter_info_create(parameter_index: Word, parameter_type: Word);
|
||||
var
|
||||
offset: Word;
|
||||
result: Word;
|
||||
@@ -3253,6 +3281,7 @@ begin
|
||||
(* Calculate the stack offset: 104 - (4 * parameter_counter) *)
|
||||
offset := parameter_index * 4;
|
||||
_parameter_info_set_offset(result, 104 - offset);
|
||||
_parameter_info_set_variable_type(result, parameter_type);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -3270,9 +3299,10 @@ end;
|
||||
|
||||
(**
|
||||
* Parameters:
|
||||
* temporary_index - Parameter index.
|
||||
* temporary_index - Local variable index.
|
||||
* temporary_type - Local variable type.
|
||||
*)
|
||||
proc _temporary_info_create(temporary_index: Word);
|
||||
proc _temporary_info_create(temporary_index: Word, temporary_type: Word);
|
||||
var
|
||||
result: Word;
|
||||
begin
|
||||
@@ -3281,6 +3311,7 @@ begin
|
||||
|
||||
(* Calculate the stack offset: 4 * variable_counter. *)
|
||||
_temporary_info_set_offset(result, temporary_index * 4);
|
||||
_parameter_info_set_variable_type(result, temporary_type);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -3309,11 +3340,15 @@ var
|
||||
name_length: Word;
|
||||
info: Word;
|
||||
name_position: Word;
|
||||
variable_type: Word;
|
||||
begin
|
||||
name_position := _declaration_get_name(parser_node);
|
||||
name_length := _declaration_get_length(parser_node);
|
||||
|
||||
info := _parameter_info_create(parameter_index);
|
||||
variable_type := _variable_declaration_get__type(parser_node);
|
||||
variable_type := elna_name_type_expression(variable_type);
|
||||
|
||||
info := _parameter_info_create(parameter_index, variable_type);
|
||||
_symbol_table_enter(symbol_table, name_position, name_length, info)
|
||||
end;
|
||||
|
||||
@@ -3326,11 +3361,15 @@ var
|
||||
name_length: Word;
|
||||
info: Word;
|
||||
name_position: Word;
|
||||
variable_type: Word;
|
||||
begin
|
||||
name_position := _declaration_get_name(parser_node);
|
||||
name_length := _declaration_get_length(parser_node);
|
||||
|
||||
info := _temporary_info_create(variable_index);
|
||||
variable_type := _variable_declaration_get__type(parser_node);
|
||||
variable_type := elna_name_type_expression(variable_type);
|
||||
|
||||
info := _temporary_info_create(variable_index, variable_type);
|
||||
_symbol_table_enter(symbol_table, name_position, name_length, info)
|
||||
end;
|
||||
|
||||
@@ -4191,7 +4230,7 @@ begin
|
||||
goto elna_type_if_statement_conditionals
|
||||
end;
|
||||
block := _if_statement_get__else(parser_node);
|
||||
if block <> 0 then
|
||||
if block <> nil then
|
||||
elna_type_statements(block, symbol_table)
|
||||
end
|
||||
end;
|
||||
@@ -4230,8 +4269,8 @@ begin
|
||||
lhs := _assign_statement_get_assignee(parser_node);
|
||||
rhs := _assign_statement_get_assignment(parser_node);
|
||||
|
||||
elna_type_designator(parser_node, symbol_table);
|
||||
elna_type_binary_expression(parser_node, symbol_table)
|
||||
elna_type_designator(lhs, symbol_table);
|
||||
elna_type_binary_expression(rhs, symbol_table)
|
||||
end;
|
||||
|
||||
proc elna_type_statement(parser_node: Word, symbol_table: Word);
|
||||
@@ -4271,7 +4310,7 @@ begin
|
||||
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
|
||||
symbol_type := _type_info_get__type(symbol_info);
|
||||
|
||||
ElnaTreeCharacterLiteral_set_type_decoration(parser_node, symbol_type)
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, symbol_type)
|
||||
end;
|
||||
|
||||
proc elna_type_integer_literal(parser_node: Word);
|
||||
@@ -4282,7 +4321,7 @@ begin
|
||||
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
|
||||
symbol_type := _type_info_get__type(symbol_info);
|
||||
|
||||
ElnaTreeIntegerLiteral_set_type_decoration(parser_node, symbol_type)
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, symbol_type)
|
||||
end;
|
||||
|
||||
proc elna_type_string_literal(parser_node: Word);
|
||||
@@ -4293,7 +4332,7 @@ begin
|
||||
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
|
||||
symbol_type := _type_info_get__type(symbol_info);
|
||||
|
||||
ElnaTreeStringLiteral_set_type_decoration(parser_node, symbol_type)
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, symbol_type)
|
||||
end;
|
||||
|
||||
proc elna_type_nil_literal(parser_node: Word);
|
||||
@@ -4304,7 +4343,7 @@ begin
|
||||
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
|
||||
symbol_type := _type_info_get__type(symbol_info);
|
||||
|
||||
ElnaTreeNilLiteral_set_type_decoration(parser_node, symbol_type)
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, symbol_type)
|
||||
end;
|
||||
|
||||
proc elna_type_variable_expression(parser_node: Word, symbol_table: Word);
|
||||
@@ -4313,6 +4352,7 @@ var
|
||||
name_pointer: Word;
|
||||
name_length: Word;
|
||||
variable_kind: Word;
|
||||
variable_type: Word;
|
||||
begin
|
||||
name_pointer := ElnaTreeVariableExpression_get_name(parser_node);
|
||||
name_length := ElnaTreeVariableExpression_get_length(parser_node);
|
||||
@@ -4322,13 +4362,15 @@ begin
|
||||
if variable_info = nil then
|
||||
variable_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length)
|
||||
end;
|
||||
variable_kind := _info_get_kind(variable_info);
|
||||
variable_type := nil;
|
||||
|
||||
(* Debug. Error stream output.
|
||||
_syscall(2, name_pointer, name_length, 0, 0, 0, 64);
|
||||
printf("# here %p %.*s\n\0", variable_info, name_length, name_pointer);
|
||||
fflush(0)
|
||||
|
||||
variable_kind := _info_get_kind(variable_info) *)
|
||||
if variable_kind = InfoKind.parameter_info then
|
||||
variable_type := _parameter_info_get_variable_type(variable_info)
|
||||
elsif variable_kind = InfoKind.temporary_info then
|
||||
variable_type := _temporary_info_get_variable_type(variable_info)
|
||||
end;
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, variable_type)
|
||||
end;
|
||||
|
||||
proc elna_type_simple_expression(parser_node: Word, symbol_table: Word);
|
||||
@@ -4353,11 +4395,57 @@ end;
|
||||
proc elna_type_designator(parser_node: Word, symbol_table: Word);
|
||||
var
|
||||
expression_kind: Word;
|
||||
designator_base: Word;
|
||||
base_type: Word;
|
||||
type_kind: Word;
|
||||
name_pointer: Word;
|
||||
name_length: Word;
|
||||
symbol_info: Word;
|
||||
begin
|
||||
expression_kind := ElnaTreeNode_get_kind(parser_node);
|
||||
|
||||
if expression_kind = ElnaTreeKind.dereference_expression then
|
||||
designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
||||
elna_type_simple_expression(designator_base, symbol_table);
|
||||
|
||||
base_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||
type_kind := ElnaType_get_kind(base_type);
|
||||
|
||||
(* If check for compatibility, should be removed later. *)
|
||||
if type_kind = TypeKind.pointer then
|
||||
base_type := ElnaTypePointer_get_base(base_type)
|
||||
end;
|
||||
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, base_type)
|
||||
elsif expression_kind = ElnaTreeKind.field_access_expression then
|
||||
base_type := nil;
|
||||
designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node);
|
||||
|
||||
(* Check whether the field access is an enumeration value. *)
|
||||
if ElnaTreeNode_get_kind(designator_base) = ElnaTreeKind.variable_expression then
|
||||
name_pointer := ElnaTreeVariableExpression_get_name(designator_base);
|
||||
name_length := ElnaTreeVariableExpression_get_length(designator_base);
|
||||
|
||||
symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
|
||||
if symbol_info <> nil then
|
||||
type_kind := _info_get_kind(symbol_info);
|
||||
|
||||
if type_kind = InfoKind.type_info then
|
||||
base_type := _type_info_get__type(symbol_info)
|
||||
end
|
||||
end
|
||||
end;
|
||||
(* If the base_type is still nil this is record field access. *)
|
||||
if base_type = nil then
|
||||
(* elna_type_simple_expression(designator_base, symbol_table);
|
||||
base_type := ElnaTreeExpression_get_type_decoration(designator_base); *)
|
||||
else
|
||||
end;
|
||||
|
||||
(* Change my type. *)
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, base_type)
|
||||
elsif expression_kind = ElnaTreeKind.call then
|
||||
elna_type_call(parser_node, symbol_table)
|
||||
else
|
||||
elna_type_simple_expression(parser_node, symbol_table)
|
||||
end
|
||||
@@ -4366,10 +4454,17 @@ end;
|
||||
proc elna_type_unary_expression(parser_node: Word, symbol_table: Word);
|
||||
var
|
||||
expression_kind: Word;
|
||||
unary_operand: Word;
|
||||
operand_type: Word;
|
||||
begin
|
||||
expression_kind := ElnaTreeNode_get_kind(parser_node);
|
||||
|
||||
if expression_kind = ElnaTreeKind.unary_expression then
|
||||
unary_operand := ElnaTreeUnaryExpression_get_operand(parser_node);
|
||||
elna_type_designator(unary_operand, symbol_table);
|
||||
|
||||
operand_type := ElnaTreeExpression_get_type_decoration(unary_operand);
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, operand_type)
|
||||
else
|
||||
elna_type_designator(parser_node, symbol_table)
|
||||
end
|
||||
@@ -4378,10 +4473,21 @@ end;
|
||||
proc elna_type_binary_expression(parser_node: Word, symbol_table: Word);
|
||||
var
|
||||
expression_kind: Word;
|
||||
binary_operand: Word;
|
||||
operand_type: Word;
|
||||
begin
|
||||
expression_kind := ElnaTreeNode_get_kind(parser_node);
|
||||
|
||||
if expression_kind = ElnaTreeKind.binary_expression then
|
||||
binary_operand := ElnaTreeBinaryExpression_get_rhs(parser_node);
|
||||
elna_type_unary_expression(binary_operand, symbol_table);
|
||||
|
||||
binary_operand := ElnaTreeBinaryExpression_get_lhs(parser_node);
|
||||
elna_type_unary_expression(binary_operand, symbol_table);
|
||||
|
||||
operand_type := ElnaTreeExpression_get_type_decoration(binary_operand);
|
||||
|
||||
ElnaTreeExpression_set_type_decoration(parser_node, operand_type)
|
||||
else
|
||||
elna_type_unary_expression(parser_node, symbol_table)
|
||||
end
|
||||
@@ -4412,16 +4518,23 @@ var
|
||||
begin
|
||||
current_part := _module_declaration_get_types(parser_node);
|
||||
.elna_name_module_declaration_type;
|
||||
if current_part <> 0 then
|
||||
if current_part <> nil then
|
||||
elna_name_type_declaration(current_part);
|
||||
current_part := _declaration_get_next(current_part);
|
||||
|
||||
goto elna_name_module_declaration_type
|
||||
end;
|
||||
current_part := _module_declaration_get_globals(parser_node);
|
||||
.elna_name_module_declaration_global;
|
||||
if current_part <> nil then
|
||||
elna_name_procedure_temporary(current_part, 0, @symbol_table_global);
|
||||
current_part := _declaration_get_next(current_part);
|
||||
|
||||
goto elna_name_module_declaration_global
|
||||
end;
|
||||
current_part := _module_declaration_get_procedures(parser_node);
|
||||
.elna_name_module_declaration_procedure;
|
||||
if current_part <> 0 then
|
||||
if current_part <> nil then
|
||||
elna_name_procedure_declaration(current_part);
|
||||
current_part := _declaration_get_next(current_part);
|
||||
|
||||
|
||||
5537
boot/stage17/cl.elna
Normal file
5537
boot/stage17/cl.elna
Normal file
File diff suppressed because it is too large
Load Diff
0
boot/stage17/linker.arg
Normal file
0
boot/stage17/linker.arg
Normal file
Reference in New Issue
Block a user