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