summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-01-22 16:05:34 +0100
committerEugen Wissner <belka@caraus.de>2026-01-22 16:05:34 +0100
commitf0f0f431ba6d9a85c802c4d8f432f184376e34f0 (patch)
treef0beb8ddcd4d5161dc295e5065d9ec94ef6910dc
parentec83bbcc1ec1827b53106a3ac26c9122295e6369 (diff)
downloadelna-f0f0f431ba6d9a85c802c4d8f432f184376e34f0.tar.gz
Parse more than 7 procedure arguments
-rw-r--r--boot/stage19/cl.elna138
1 files changed, 53 insertions, 85 deletions
diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna
index c47b8e5..0f0b832 100644
--- a/boot/stage19/cl.elna
+++ b/boot/stage19/cl.elna
@@ -275,6 +275,17 @@ type
length: Word;
_type: Word
end;
+ ElnaTreeExpressionList = record
+ expression: ^ElnaTreeBinaryExpression;
+ next: Word
+ end;
+ ElnaTreeCall = record
+ kind: ElnaTreeKind;
+ next: Word;
+ callee: ^ElnaTreeVariableExpression;
+ arguments: ^ElnaTreeExpressionList;
+ count: Word
+ end;
(* Symbol table information. *)
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
@@ -2226,52 +2237,20 @@ begin
return first_instruction
end;
-(* 4 bytes node kind + 4 byte pointer to variable expression + 4 * 7 for arguments. *)
-proc _call_size();
- return 44
-end;
-
-proc _call_get_name(this: Word);
-begin
- this := this + 8;
- return this^
-end;
-
-proc _call_set_name(this: Word, value: Word);
-begin
- this := this + 8;
- this^ := value
-end;
-
-proc _call_get_argument(this: Word, n: Word);
-begin
- n := n * 4;
- this := this + 8;
- this := this + n;
- return this^
-end;
-
-proc _call_set_argument(this: Word, n: Word, value: Word);
-begin
- n := n * 4;
- this := this + 8;
- this := this + n;
- this^ := value
-end;
-
proc elna_parser_call(callee: Word);
var
- parsed_expression: Word;
- result: ^ElnaTreeStatement;
+ result: ^ElnaTreeCall;
argument_number: Word;
token_kind: Word;
+ argument_entry: ^ElnaTreeExpressionList;
begin
- result := malloc(_call_size());
+ result := malloc(#size(ElnaTreeCall));
result^.kind := ElnaTreeKind.call;
result^.next := nil;
+ result^.arguments := nil;
argument_number := 1;
- _call_set_name(result, callee);
+ result^.callee := callee;
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
@@ -2283,8 +2262,16 @@ begin
end;
.elna_parser_call_loop;
- parsed_expression := elna_parser_binary_expression();
- _call_set_argument(result, argument_number, parsed_expression);
+ if result^.arguments = nil then
+ result^.arguments := malloc(#size(ElnaTreeExpressionList));
+ argument_entry := result^.arguments
+ else
+ argument_entry^.next := malloc(#size(ElnaTreeExpressionList));
+ argument_entry := argument_entry^.next
+ end;
+ argument_entry^.next := nil;
+ argument_entry^.expression := elna_parser_binary_expression();
+
argument_number := argument_number + 1;
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
@@ -2294,17 +2281,14 @@ begin
end;
.elna_parser_call_end;
- (* Set the trailing argument to nil. *)
- _call_set_argument(result, argument_number, nil);
+ (* Save the number of arguments. *)
+ result^.count := argument_number - 1;
return result
end;
-proc elna_tac_call(parsed_call: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
+proc elna_tac_call(parsed_call: ^ElnaTreeCall, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- argument_count: Word;
- name_length: Word;
- name: Word;
parsed_expression: ^ElnaTreeVariableExpression;
instruction: Word;
first_instruction: Word;
@@ -2312,28 +2296,19 @@ var
argument_type: Word;
argument_value: Word;
argument_length: Word;
- arguments_operand: Word;
+ arguments_operand: ^ElnaTacOperand;
call_instruction: Word;
+ argument_entry: ^ElnaTreeExpressionList;
name_buffer: Word;
+ argument_count: Word;
begin
- parsed_expression := _call_get_name(parsed_call);
- name := parsed_expression^.name;
- name_length := parsed_expression^.length;
- argument_count := 0;
- first_instruction := 0;
-
- .elna_tac_call_count;
- parsed_expression := _call_get_argument(parsed_call, argument_count + 1);
-
- if parsed_expression <> nil ten
- argument_count := argument_count + 1;
- goto elna_tac_call_count
- end;
- arguments_operand := malloc(argument_count * 12);
+ parsed_expression := parsed_call^.callee;
+ first_instruction := nil;
+ arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
- elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.symbol, name, name_length);
- elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacKind.list, arguments_operand, argument_count);
+ elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.symbol, parsed_expression^.name, parsed_expression^.length);
+ elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacKind.list, arguments_operand, parsed_call^.count);
elna_tac_instruction_set_operand(call_instruction, 3, ElnaTacKind.pseudo, "$unary", 6);
operand_type^ := ElnaTacKind.pseudo;
@@ -2341,22 +2316,21 @@ begin
operand_length^ := 6;
argument_count := 0;
+ argument_entry := parsed_call^.arguments;
.elna_tac_call_loop;
- parsed_expression := _call_get_argument(parsed_call, argument_count + 1);
- if parsed_expression = 0 then
- goto elna_tac_call_finalize
- else
+ if argument_entry <> nil then
argument_type := 0;
argument_value := 0;
argument_length := 0;
- instruction := elna_tac_binary_expression(parsed_expression, symbol_table, @argument_type, @argument_value, @argument_length);
- if first_instruction = 0 then
+ instruction := elna_tac_binary_expression(argument_entry^.expression, symbol_table,
+ @argument_type, @argument_value, @argument_length);
+ if first_instruction = nil then
first_instruction := instruction
else
elna_instruction_list_concatenate(current_instruction, instruction)
end;
- if instruction <> 0 then
+ if instruction <> nil then
current_instruction := instruction
end;
@@ -2373,18 +2347,15 @@ begin
end;
current_instruction := instruction;
- arguments_operand^ := ElnaTacKind.pseudo;
- arguments_operand := arguments_operand + 4;
- arguments_operand^ := name_buffer;
- arguments_operand := arguments_operand + 4;
- arguments_operand^ := 4;
- arguments_operand := arguments_operand + 4;
+ arguments_operand^.kind := ElnaTacKind.pseudo;
+ arguments_operand^.value := name_buffer;
+ arguments_operand^.length := 4;
+ arguments_operand := arguments_operand + #size(ElnaTacOperand);
+ argument_entry := argument_entry^.next;
argument_count := argument_count + 1;
goto elna_tac_call_loop
end;
- .elna_tac_call_finalize;
-
if first_instruction = nil then
first_instruction := call_instruction
else
@@ -4184,19 +4155,16 @@ begin
elna_type_binary_expression(parser_node^.returned, symbol_table)
end;
-proc elna_type_call(parser_node: Word, symbol_table: Word);
+proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: Word);
var
- current_argument: Word;
- argument_tree: Word;
+ argument_tree: ^ElnaTreeExpressionList;
begin
- current_argument := 1;
+ argument_tree := parser_node^.arguments;
.elna_type_call_argument;
- argument_tree := _call_get_argument(parser_node, current_argument);
-
if argument_tree <> nil then
- elna_type_binary_expression(argument_tree, symbol_table);
- current_argument := current_argument + 1;
+ elna_type_binary_expression(argument_tree^.expression, symbol_table);
+ argument_tree := argument_tree^.next;
goto elna_type_call_argument
end