summaryrefslogtreecommitdiff
path: root/boot/stage16
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-11-25 08:03:05 +0100
committerEugen Wissner <belka@caraus.de>2025-11-25 08:03:05 +0100
commitc20d9b7240033b462b33030ba4946135bc7d7fef (patch)
tree1ef1f96a42999bebd8b9eb00d3480f776f591a04 /boot/stage16
parentc3eff02f8d610b6bd259eee672c044731df43d65 (diff)
downloadelna-c20d9b7240033b462b33030ba4946135bc7d7fef.tar.gz
Set expression type for enumeration values
Diffstat (limited to 'boot/stage16')
-rw-r--r--boot/stage16/cl.elna175
1 files changed, 144 insertions, 31 deletions
diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna
index 0a6d454..438c106 100644
--- a/boot/stage16/cl.elna
+++ b/boot/stage16/cl.elna
@@ -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);