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; length: Word;
_type: Word _type: Word
end; end;
ElnaTreeExpressionList = record
expression: ^ElnaTreeBinaryExpression;
next: Word
end;
ElnaTreeCall = record
kind: ElnaTreeKind;
next: Word;
callee: ^ElnaTreeVariableExpression;
arguments: ^ElnaTreeExpressionList;
count: Word
end;
(* Symbol table information. *) (* Symbol table information. *)
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info); ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
@@ -2226,52 +2237,20 @@ begin
return first_instruction return first_instruction
end; 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); proc elna_parser_call(callee: Word);
var var
parsed_expression: Word; result: ^ElnaTreeCall;
result: ^ElnaTreeStatement;
argument_number: Word; argument_number: Word;
token_kind: Word; token_kind: Word;
argument_entry: ^ElnaTreeExpressionList;
begin begin
result := malloc(_call_size()); result := malloc(#size(ElnaTreeCall));
result^.kind := ElnaTreeKind.call; result^.kind := ElnaTreeKind.call;
result^.next := nil; result^.next := nil;
result^.arguments := nil;
argument_number := 1; argument_number := 1;
_call_set_name(result, callee); result^.callee := callee;
_elna_lexer_read_token(@token_kind); _elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token(); _elna_lexer_skip_token();
@@ -2283,8 +2262,16 @@ begin
end; end;
.elna_parser_call_loop; .elna_parser_call_loop;
parsed_expression := elna_parser_binary_expression(); if result^.arguments = nil then
_call_set_argument(result, argument_number, parsed_expression); 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; argument_number := argument_number + 1;
_elna_lexer_read_token(@token_kind); _elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token(); _elna_lexer_skip_token();
@@ -2294,17 +2281,14 @@ begin
end; end;
.elna_parser_call_end; .elna_parser_call_end;
(* Set the trailing argument to nil. *) (* Save the number of arguments. *)
_call_set_argument(result, argument_number, nil); result^.count := argument_number - 1;
return result return result
end; 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 var
argument_count: Word;
name_length: Word;
name: Word;
parsed_expression: ^ElnaTreeVariableExpression; parsed_expression: ^ElnaTreeVariableExpression;
instruction: Word; instruction: Word;
first_instruction: Word; first_instruction: Word;
@@ -2312,28 +2296,19 @@ var
argument_type: Word; argument_type: Word;
argument_value: Word; argument_value: Word;
argument_length: Word; argument_length: Word;
arguments_operand: Word; arguments_operand: ^ElnaTacOperand;
call_instruction: Word; call_instruction: Word;
argument_entry: ^ElnaTreeExpressionList;
name_buffer: Word; name_buffer: Word;
argument_count: Word;
begin begin
parsed_expression := _call_get_name(parsed_call); parsed_expression := parsed_call^.callee;
name := parsed_expression^.name; first_instruction := nil;
name_length := parsed_expression^.length; arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
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);
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call); 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, 1, ElnaTacKind.symbol, parsed_expression^.name, parsed_expression^.length);
elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacKind.list, arguments_operand, argument_count); 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); elna_tac_instruction_set_operand(call_instruction, 3, ElnaTacKind.pseudo, "$unary", 6);
operand_type^ := ElnaTacKind.pseudo; operand_type^ := ElnaTacKind.pseudo;
@@ -2341,22 +2316,21 @@ begin
operand_length^ := 6; operand_length^ := 6;
argument_count := 0; argument_count := 0;
argument_entry := parsed_call^.arguments;
.elna_tac_call_loop; .elna_tac_call_loop;
parsed_expression := _call_get_argument(parsed_call, argument_count + 1); if argument_entry <> nil then
if parsed_expression = 0 then
goto elna_tac_call_finalize
else
argument_type := 0; argument_type := 0;
argument_value := 0; argument_value := 0;
argument_length := 0; argument_length := 0;
instruction := elna_tac_binary_expression(parsed_expression, symbol_table, @argument_type, @argument_value, @argument_length); instruction := elna_tac_binary_expression(argument_entry^.expression, symbol_table,
if first_instruction = 0 then @argument_type, @argument_value, @argument_length);
if first_instruction = nil then
first_instruction := instruction first_instruction := instruction
else else
elna_instruction_list_concatenate(current_instruction, instruction) elna_instruction_list_concatenate(current_instruction, instruction)
end; end;
if instruction <> 0 then if instruction <> nil then
current_instruction := instruction current_instruction := instruction
end; end;
@@ -2373,18 +2347,15 @@ begin
end; end;
current_instruction := instruction; current_instruction := instruction;
arguments_operand^ := ElnaTacKind.pseudo; arguments_operand^.kind := ElnaTacKind.pseudo;
arguments_operand := arguments_operand + 4; arguments_operand^.value := name_buffer;
arguments_operand^ := name_buffer; arguments_operand^.length := 4;
arguments_operand := arguments_operand + 4; arguments_operand := arguments_operand + #size(ElnaTacOperand);
arguments_operand^ := 4;
arguments_operand := arguments_operand + 4;
argument_entry := argument_entry^.next;
argument_count := argument_count + 1; argument_count := argument_count + 1;
goto elna_tac_call_loop goto elna_tac_call_loop
end; end;
.elna_tac_call_finalize;
if first_instruction = nil then if first_instruction = nil then
first_instruction := call_instruction first_instruction := call_instruction
else else
@@ -4184,19 +4155,16 @@ begin
elna_type_binary_expression(parser_node^.returned, symbol_table) elna_type_binary_expression(parser_node^.returned, symbol_table)
end; end;
proc elna_type_call(parser_node: Word, symbol_table: Word); proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: Word);
var var
current_argument: Word; argument_tree: ^ElnaTreeExpressionList;
argument_tree: Word;
begin begin
current_argument := 1; argument_tree := parser_node^.arguments;
.elna_type_call_argument; .elna_type_call_argument;
argument_tree := _call_get_argument(parser_node, current_argument);
if argument_tree <> nil then if argument_tree <> nil then
elna_type_binary_expression(argument_tree, symbol_table); elna_type_binary_expression(argument_tree^.expression, symbol_table);
current_argument := current_argument + 1; argument_tree := argument_tree^.next;
goto elna_type_call_argument goto elna_type_call_argument
end end