Parse more than 7 procedure arguments

This commit is contained in:
2026-01-22 16:05:34 +01:00
parent ec83bbcc1e
commit f0f0f431ba

View File

@@ -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