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