Use operand record in TAC expression visitor
This commit is contained in:
19
Rakefile
19
Rakefile
@@ -38,11 +38,20 @@ desc 'Convert previous stage language into the current stage language'
|
||||
task :convert do
|
||||
File.open('boot/stage20/cl.elna', 'w') do |current_stage|
|
||||
File.readlines('boot/stage19/cl.elna').each do |line|
|
||||
if line.include? "_assign_at(@classification, 1, ElnaLexerClass.eof)"
|
||||
current_stage << "\tclassification[1] := ElnaLexerClass.eof;\n"
|
||||
else
|
||||
current_stage << line
|
||||
end
|
||||
current_stage << line
|
||||
end
|
||||
current_stage << <<~FUN
|
||||
|
||||
proc f(m: ElnaInstructionModule);
|
||||
begin
|
||||
end;
|
||||
|
||||
proc g();
|
||||
var
|
||||
x: ElnaInstructionModule;
|
||||
begin
|
||||
f(x)
|
||||
end;
|
||||
FUN
|
||||
end
|
||||
end
|
||||
|
||||
@@ -252,7 +252,8 @@ type
|
||||
length: Word;
|
||||
body: Word;
|
||||
temporaries: Word;
|
||||
parameters: Word
|
||||
parameters: Word;
|
||||
return_type: ^ElnaTreeNode
|
||||
end;
|
||||
ElnaTreeTypeDeclaration = record
|
||||
kind: ElnaTreeKind;
|
||||
@@ -528,7 +529,7 @@ type
|
||||
allocate_stack,
|
||||
ret
|
||||
);
|
||||
ElnaRtlKind = (register, immediate, symbol, pseudo, offset, pseudo_mem);
|
||||
ElnaRtlKind = (register, immediate, symbol, pseudo, offset);
|
||||
ElnaRtlOperand = record
|
||||
kind: ElnaRtlKind;
|
||||
value: Word;
|
||||
@@ -1008,17 +1009,15 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction);
|
||||
proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||
var
|
||||
argument_count: Word;
|
||||
current_argument: ^ElnaTacOperand;
|
||||
argument_type: Word;
|
||||
argument_value: Word;
|
||||
argument_length: Word;
|
||||
argument_move: ^ElnaRtlInstruction;
|
||||
current_register: Word;
|
||||
first_instruction: Word;
|
||||
current_instruction: Word;
|
||||
variable_info: ^ElnaRtlInfo;
|
||||
begin
|
||||
current_register := 0;
|
||||
first_instruction := nil;
|
||||
@@ -1031,15 +1030,12 @@ begin
|
||||
if argument_count > 0 then
|
||||
argument_count := argument_count - 1;
|
||||
|
||||
argument_type := current_argument^.kind;
|
||||
argument_value := current_argument^.value;
|
||||
argument_length := current_argument^.length;
|
||||
current_argument := current_argument + #size(ElnaTacOperand);
|
||||
|
||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
|
||||
elna_rtl_instruction_set_operand(argument_move, 2, argument_type, argument_value, argument_length);
|
||||
|
||||
if current_argument^.kind = ElnaTacKind.pseudo then
|
||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
|
||||
elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo,
|
||||
current_argument^.value, current_argument^.length)
|
||||
end;
|
||||
if first_instruction = nil then
|
||||
first_instruction := argument_move
|
||||
else
|
||||
@@ -1047,6 +1043,7 @@ begin
|
||||
end;
|
||||
current_instruction := argument_move;
|
||||
|
||||
current_argument := current_argument + #size(ElnaTacOperand);
|
||||
current_register := current_register + 1;
|
||||
|
||||
goto elna_rtl_call_loop
|
||||
@@ -1119,7 +1116,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc elna_rtl_instruction(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction);
|
||||
proc elna_rtl_instruction(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||
var
|
||||
result: ^ElnaRtlInstruction;
|
||||
operands: ^ElnaRtlInstruction;
|
||||
@@ -1140,7 +1137,7 @@ begin
|
||||
elsif tac_instruction^.operator = ElnaTacOperator.store then
|
||||
result := elna_rtl_store(tac_instruction, next_instruction)
|
||||
elsif tac_instruction^.operator = ElnaTacOperator.proc_call then
|
||||
result := elna_rtl_call(tac_instruction, next_instruction)
|
||||
result := elna_rtl_call(tac_instruction, next_instruction, variable_map)
|
||||
elsif tac_instruction^.operator = ElnaTacOperator.subtract then
|
||||
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub)
|
||||
elsif tac_instruction^.operator = ElnaTacOperator.multiply then
|
||||
@@ -1591,7 +1588,7 @@ begin
|
||||
_write_c('\n')
|
||||
end;
|
||||
|
||||
proc elna_rtl_instructions(instruction: ^ElnaTacInstruction);
|
||||
proc elna_rtl_instructions(instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||
var
|
||||
last_copy: ^ElnaRtlInstruction;
|
||||
current_copy: ^ElnaRtlInstruction;
|
||||
@@ -1599,7 +1596,7 @@ var
|
||||
first_copy: ^ElnaRtlInstruction;
|
||||
begin
|
||||
if instruction <> nil then
|
||||
first_copy := elna_rtl_instruction(instruction, @current_copy);
|
||||
first_copy := elna_rtl_instruction(instruction, @current_copy, variable_map);
|
||||
instruction := instruction^.next
|
||||
else
|
||||
first_copy := nil;
|
||||
@@ -1608,7 +1605,7 @@ begin
|
||||
.elna_rtl_instructions_start;
|
||||
|
||||
if instruction <> nil then
|
||||
next_copy := elna_rtl_instruction(instruction, @last_copy);
|
||||
next_copy := elna_rtl_instruction(instruction, @last_copy, variable_map);
|
||||
|
||||
instruction := instruction^.next;
|
||||
current_copy^.next := next_copy;
|
||||
@@ -2874,10 +2871,10 @@ begin
|
||||
elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
|
||||
elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacKind.symbol, condition_label, 0);
|
||||
|
||||
elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||
|
||||
instruction := elna_tac_statements(parser_node^.statements, symbol_table);
|
||||
if instruction <> 0 then
|
||||
if instruction <> nil then
|
||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
current_instruction := instruction
|
||||
end;
|
||||
@@ -3563,10 +3560,16 @@ begin
|
||||
_elna_lexer_skip_token();
|
||||
result^.parameters := parameter_head;
|
||||
|
||||
(* Skip semicolon and newline. *)
|
||||
(* Skip semicolon or arrow. *)
|
||||
_elna_lexer_read_token(@token_kind);
|
||||
_elna_lexer_skip_token();
|
||||
|
||||
if token_kind = ElnaLexerKind.arrow then
|
||||
result^.return_type := elna_parser_type_expression()
|
||||
else
|
||||
result^.return_type := nil
|
||||
end;
|
||||
|
||||
parameter_head := elna_parser_var_part();
|
||||
result^.temporaries := parameter_head;
|
||||
|
||||
@@ -3713,17 +3716,17 @@ begin
|
||||
pseudo_symbol^.allocated := false;
|
||||
|
||||
if elna_type_is_aggregate(variable_info^.variable_type) then
|
||||
long_word := malloc(#size(ElnaRtlTypeWord));
|
||||
long_word^.kind := ElnaRtlTypeKind.long_word;
|
||||
long_word^.size := variable_info^.variable_type^.size;
|
||||
|
||||
pseudo_symbol^.rtl_type = long_word
|
||||
else
|
||||
byte_array := malloc(#size(ElnaRtlTypeByteArray));
|
||||
byte_array^.kind := ElnaRtlTypeKind.byte_array;
|
||||
byte_array^.size := variable_info^.variable_type^.size;
|
||||
|
||||
pseudo_symbol^.rtl_type = byte_array
|
||||
pseudo_symbol^.rtl_type := byte_array
|
||||
else
|
||||
long_word := malloc(#size(ElnaRtlTypeWord));
|
||||
long_word^.kind := ElnaRtlTypeKind.long_word;
|
||||
long_word^.size := variable_info^.variable_type^.size;
|
||||
|
||||
pseudo_symbol^.rtl_type := long_word
|
||||
end;
|
||||
elna_symbol_table_enter(variable_map, current_entry^.name, current_entry^.length, pseudo_symbol);
|
||||
|
||||
@@ -3749,9 +3752,9 @@ begin
|
||||
result^.length := tac_declaration^.length;
|
||||
|
||||
parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count);
|
||||
body := elna_rtl_instructions(tac_declaration^.body);
|
||||
result^.body := elna_instruction_list_concatenate(parameters, body);
|
||||
result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table);
|
||||
body := elna_rtl_instructions(tac_declaration^.body, result^.variable_map);
|
||||
result^.body := elna_instruction_list_concatenate(parameters, body);
|
||||
|
||||
return result
|
||||
end;
|
||||
@@ -5039,7 +5042,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_keyword(position_start: Word, position_end: Word);
|
||||
proc elna_lexer_classify_keyword(position_start: Word, position_end: Word);
|
||||
var
|
||||
result: Word;
|
||||
token_length: Word;
|
||||
@@ -5095,7 +5098,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_finalize(start_position: Word);
|
||||
proc elna_lexer_classify_finalize(start_position: Word);
|
||||
var
|
||||
character: Word;
|
||||
result: Word;
|
||||
@@ -5119,7 +5122,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_single(start_position: Word);
|
||||
proc elna_lexer_classify_single(start_position: Word);
|
||||
var
|
||||
character: Word;
|
||||
result: Word;
|
||||
@@ -5161,7 +5164,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_composite(start_position: Word, one_before_last: Word);
|
||||
proc elna_lexer_classify_composite(start_position: Word, one_before_last: Word);
|
||||
var
|
||||
first_character: Word;
|
||||
last_character: Word;
|
||||
@@ -5182,12 +5185,14 @@ begin
|
||||
if last_character = '=' then
|
||||
result := ElnaLexerKind.greater_equal
|
||||
end
|
||||
elsif first_character = '-' then
|
||||
result := ElnaLexerKind.arrow
|
||||
end;
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_delimited(start_position: Word, end_position: Word);
|
||||
proc elna_lexer_classify_delimited(start_position: Word, end_position: Word);
|
||||
var
|
||||
token_length: Word;
|
||||
delimiter: Word;
|
||||
@@ -5206,7 +5211,7 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc _elna_lexer_classify_integer(start_position: Word, end_position: Word);
|
||||
proc elna_lexer_classify_integer(start_position: Word, end_position: Word);
|
||||
return ElnaLexerKind.integer
|
||||
end;
|
||||
|
||||
@@ -5223,29 +5228,29 @@ begin
|
||||
elsif action_to_perform = ElnaLexerAction.single then
|
||||
lexer_state.finish := lexer_state.finish + 1;
|
||||
|
||||
intermediate := _elna_lexer_classify_single(lexer_state.start);
|
||||
intermediate := elna_lexer_classify_single(lexer_state.start);
|
||||
kind^ := intermediate
|
||||
elsif action_to_perform = ElnaLexerAction.eof then
|
||||
intermediate := ElnaLexerKind.eof;
|
||||
kind^ := intermediate
|
||||
elsif action_to_perform = ElnaLexerAction.finalize then
|
||||
intermediate := _elna_lexer_classify_finalize(lexer_state.start);
|
||||
intermediate := elna_lexer_classify_finalize(lexer_state.start);
|
||||
kind^ := intermediate
|
||||
elsif action_to_perform = ElnaLexerAction.composite then
|
||||
intermediate := _elna_lexer_classify_composite(lexer_state.start, lexer_state.finish);
|
||||
intermediate := elna_lexer_classify_composite(lexer_state.start, lexer_state.finish);
|
||||
kind^ := intermediate;
|
||||
|
||||
lexer_state.finish := lexer_state.finish + 1
|
||||
elsif action_to_perform = ElnaLexerAction.key_id then
|
||||
intermediate := _elna_lexer_classify_keyword(lexer_state.start, lexer_state.finish);
|
||||
intermediate := elna_lexer_classify_keyword(lexer_state.start, lexer_state.finish);
|
||||
kind^ := intermediate
|
||||
elsif action_to_perform = ElnaLexerAction.integer then
|
||||
intermediate := _elna_lexer_classify_integer(lexer_state.start, lexer_state.finish);
|
||||
intermediate := elna_lexer_classify_integer(lexer_state.start, lexer_state.finish);
|
||||
kind^ := intermediate
|
||||
elsif action_to_perform = ElnaLexerAction.delimited then
|
||||
lexer_state.finish := lexer_state.finish + 1;
|
||||
|
||||
intermediate := _elna_lexer_classify_delimited(lexer_state.start, lexer_state.finish);
|
||||
intermediate := elna_lexer_classify_delimited(lexer_state.start, lexer_state.finish);
|
||||
kind^ := intermediate
|
||||
end
|
||||
end;
|
||||
|
||||
5309
boot/stage20/cl.elna
Normal file
5309
boot/stage20/cl.elna
Normal file
File diff suppressed because it is too large
Load Diff
0
boot/stage20/linker.arg
Normal file
0
boot/stage20/linker.arg
Normal file
Reference in New Issue
Block a user