Parse more than 7 procedure arguments
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user