Allow parsing multiple designator expressions in a row
This commit is contained in:
@@ -1789,14 +1789,18 @@ var
|
|||||||
begin
|
begin
|
||||||
simple_expression := elna_parser_simple_expression();
|
simple_expression := elna_parser_simple_expression();
|
||||||
|
|
||||||
|
.elna_parser_designator_loop;
|
||||||
_elna_lexer_read_token(@token_kind);
|
_elna_lexer_read_token(@token_kind);
|
||||||
|
|
||||||
if token_kind = ElnaLexerKind.hat then
|
if token_kind = ElnaLexerKind.hat then
|
||||||
simple_expression := elna_parser_dereference_expression(simple_expression)
|
simple_expression := elna_parser_dereference_expression(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
elsif token_kind = ElnaLexerKind.dot then
|
elsif token_kind = ElnaLexerKind.dot then
|
||||||
simple_expression := elna_parser_field_access_expression(simple_expression)
|
simple_expression := elna_parser_field_access_expression(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
elsif token_kind = ElnaLexerKind.left_paren then
|
elsif token_kind = ElnaLexerKind.left_paren then
|
||||||
simple_expression := elna_parser_call(simple_expression)
|
simple_expression := elna_parser_call(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
end;
|
end;
|
||||||
return simple_expression
|
return simple_expression
|
||||||
end;
|
end;
|
||||||
@@ -2414,12 +2418,21 @@ var
|
|||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
last_instruction: Word;
|
last_instruction: Word;
|
||||||
type_kind: Word;
|
type_kind: Word;
|
||||||
|
designator_base: Word;
|
||||||
|
aggregate_type: Word;
|
||||||
|
name_pointer: Word;
|
||||||
|
name_length: Word;
|
||||||
|
field_name_pointer: Word;
|
||||||
|
field_name_length: Word;
|
||||||
|
field_count: Word;
|
||||||
|
current_field: Word;
|
||||||
|
field_offset: Word;
|
||||||
begin
|
begin
|
||||||
node_kind := ElnaTreeNode_get_kind(parser_node);
|
node_kind := ElnaTreeNode_get_kind(parser_node);
|
||||||
|
|
||||||
if node_kind = ElnaTreeKind.dereference_expression then
|
if node_kind = ElnaTreeKind.dereference_expression then
|
||||||
parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
||||||
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
|
first_instruction := _elna_tac_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
@@ -2436,17 +2449,42 @@ begin
|
|||||||
type_kind := ElnaType_get_kind(expression_type);
|
type_kind := ElnaType_get_kind(expression_type);
|
||||||
|
|
||||||
if type_kind = ElnaTypeKind.enumeration then
|
if type_kind = ElnaTypeKind.enumeration then
|
||||||
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length)
|
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
|
||||||
|
is_address^ := 0
|
||||||
else
|
else
|
||||||
(* Stub for record field access. Always generate nil for field access expression until it is implemented. *)
|
designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node);
|
||||||
|
first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
|
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
|
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
||||||
|
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
||||||
|
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
field_count := ElnaTypeRecord_get_length(aggregate_type);
|
||||||
operand_value^ := 0;
|
current_field := ElnaTypeRecord_get_members(aggregate_type);
|
||||||
|
field_offset := 0;
|
||||||
|
|
||||||
|
.elna_tac_designator_field;
|
||||||
|
|
||||||
|
field_name_pointer := ElnaTypeField_get_name(current_field);
|
||||||
|
field_name_length := ElnaTypeField_get_length(current_field);
|
||||||
|
|
||||||
|
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then
|
||||||
|
field_count := field_count - 1;
|
||||||
|
current_field := current_field + ElnaTypeField_size();
|
||||||
|
field_offset := field_offset + 4;
|
||||||
|
goto elna_tac_designator_field
|
||||||
|
end;
|
||||||
|
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^);
|
||||||
|
|
||||||
|
operand_type^ := ElnaTacOperand.temporary;
|
||||||
|
operand_value^ := 6;
|
||||||
operand_length^ := 0;
|
operand_length^ := 0;
|
||||||
|
|
||||||
first_instruction := nil
|
is_address^ := 1;
|
||||||
|
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
||||||
end;
|
end;
|
||||||
is_address^ := 0
|
|
||||||
elsif node_kind = ElnaTreeKind.call then
|
elsif node_kind = ElnaTreeKind.call then
|
||||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
||||||
|
|
||||||
@@ -4411,7 +4449,7 @@ begin
|
|||||||
|
|
||||||
if expression_kind = ElnaTreeKind.dereference_expression then
|
if expression_kind = ElnaTreeKind.dereference_expression then
|
||||||
designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
||||||
elna_type_simple_expression(designator_base, symbol_table);
|
elna_type_designator(designator_base, symbol_table);
|
||||||
|
|
||||||
base_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
base_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
type_kind := ElnaType_get_kind(base_type);
|
type_kind := ElnaType_get_kind(base_type);
|
||||||
@@ -4442,7 +4480,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
(* If the base_type is still nil this is record field access. *)
|
(* If the base_type is still nil this is record field access. *)
|
||||||
if base_type = nil then
|
if base_type = nil then
|
||||||
elna_type_simple_expression(designator_base, symbol_table);
|
elna_type_designator(designator_base, symbol_table);
|
||||||
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
||||||
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
||||||
@@ -4455,12 +4493,12 @@ begin
|
|||||||
field_name_pointer := ElnaTypeField_get_name(current_field);
|
field_name_pointer := ElnaTypeField_get_name(current_field);
|
||||||
field_name_length := ElnaTypeField_get_length(current_field);
|
field_name_length := ElnaTypeField_get_length(current_field);
|
||||||
|
|
||||||
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then
|
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then
|
||||||
(* Debug. Error stream output.
|
(* Debug. Error stream output.
|
||||||
_syscall(2, name_pointer, name_length, 0, 0, 0, 64); *)
|
_syscall(2, name_pointer, name_length, 0, 0, 0, 64);
|
||||||
printf("# if %.*s\n\0", name_length, name_pointer);
|
printf("# if %.*s\n\0", name_length, name_pointer);
|
||||||
fflush(0)
|
fflush(0) *)
|
||||||
else
|
|
||||||
field_count := field_count - 1;
|
field_count := field_count - 1;
|
||||||
current_field := current_field + ElnaTypeField_size();
|
current_field := current_field + ElnaTypeField_size();
|
||||||
goto elna_type_designator_field
|
goto elna_type_designator_field
|
||||||
|
|||||||
@@ -938,19 +938,19 @@ end;
|
|||||||
|
|
||||||
proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word);
|
proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word);
|
||||||
var
|
var
|
||||||
lhs: Word;
|
lhs: ^ElnaInstructionList;
|
||||||
rhs: Word;
|
rhs: ^ElnaInstructionList;
|
||||||
begin
|
begin
|
||||||
lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2);
|
lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2);
|
||||||
rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3);
|
rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3);
|
||||||
|
|
||||||
next_instruction^ := ElnaInstructionList_get_next(lhs);
|
next_instruction^ := lhs^.next;
|
||||||
if next_instruction^ = 0 then
|
if next_instruction^ = 0 then
|
||||||
ElnaInstructionList_set_next(lhs, rhs)
|
lhs^.next := rhs
|
||||||
else
|
else
|
||||||
ElnaInstructionList_set_next(next_instruction^, rhs)
|
next_instruction^^ := rhs
|
||||||
end;
|
end;
|
||||||
next_instruction^ := ElnaInstructionList_get_next(rhs);
|
next_instruction^ := rhs^.next;
|
||||||
if next_instruction^ = 0 then
|
if next_instruction^ = 0 then
|
||||||
next_instruction^ := rhs
|
next_instruction^ := rhs
|
||||||
end;
|
end;
|
||||||
@@ -1040,12 +1040,12 @@ end;
|
|||||||
|
|
||||||
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
|
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: ^ElnaInstructionList;
|
||||||
instruction_size: Word;
|
instruction_size: Word;
|
||||||
instruction_kind: Word;
|
instruction_kind: Word;
|
||||||
operand_type: Word;
|
operand_type: Word;
|
||||||
operand_value: Word;
|
operand_value: Word;
|
||||||
operands: Word;
|
operands: ^ElnaInstructionList;
|
||||||
intermediate_instruction: Word;
|
intermediate_instruction: Word;
|
||||||
begin
|
begin
|
||||||
instruction_size := elna_rtl_instruction_size();
|
instruction_size := elna_rtl_instruction_size();
|
||||||
@@ -1101,7 +1101,7 @@ begin
|
|||||||
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
|
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
|
||||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
result := operands;
|
result := operands;
|
||||||
operands := ElnaInstructionList_get_next(result);
|
operands := result^.next;
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
|
||||||
@@ -1214,11 +1214,11 @@ begin
|
|||||||
|
|
||||||
if operand_type = ElnaTacOperand.temporary then
|
if operand_type = ElnaTacOperand.temporary then
|
||||||
result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value);
|
result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value);
|
||||||
next_instruction^ := ElnaInstructionList_get_next(result)
|
next_instruction^ := result^.next
|
||||||
elsif operand_type = ElnaTacOperand.stack then
|
elsif operand_type = ElnaTacOperand.stack then
|
||||||
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
||||||
result := operands;
|
result := operands;
|
||||||
operands := ElnaInstructionList_get_next(result);
|
operands := result^.next;
|
||||||
|
|
||||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
_elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0);
|
_elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0);
|
||||||
@@ -1413,7 +1413,7 @@ begin
|
|||||||
_write_c('\n')
|
_write_c('\n')
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_instructions(instruction: Word);
|
proc elna_rtl_instructions(instruction: ^ElnaInstructionList);
|
||||||
var
|
var
|
||||||
current_copy: Word;
|
current_copy: Word;
|
||||||
next_copy: Word;
|
next_copy: Word;
|
||||||
@@ -1422,7 +1422,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
first_copy := elna_rtl_instruction(instruction, @current_copy);
|
first_copy := elna_rtl_instruction(instruction, @current_copy);
|
||||||
instruction := ElnaInstructionList_get_next(instruction)
|
instruction := instruction^.next
|
||||||
else
|
else
|
||||||
first_copy := 0;
|
first_copy := 0;
|
||||||
current_copy := 0
|
current_copy := 0
|
||||||
@@ -1432,7 +1432,7 @@ begin
|
|||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
next_copy := elna_rtl_instruction(instruction, @last_copy);
|
next_copy := elna_rtl_instruction(instruction, @last_copy);
|
||||||
|
|
||||||
instruction := ElnaInstructionList_get_next(instruction);
|
instruction := instruction^.next;
|
||||||
ElnaInstructionList_set_next(current_copy, next_copy);
|
ElnaInstructionList_set_next(current_copy, next_copy);
|
||||||
current_copy := last_copy;
|
current_copy := last_copy;
|
||||||
goto elna_rtl_instructions_start
|
goto elna_rtl_instructions_start
|
||||||
@@ -1441,120 +1441,96 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_instructions(instruction: Word);
|
proc _elna_writer_instructions(instruction: ^ElnaInstructionList);
|
||||||
begin
|
begin
|
||||||
.elna_writer_instructions_start;
|
.elna_writer_instructions_start;
|
||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
_elna_writer_instruction(instruction);
|
_elna_writer_instruction(instruction);
|
||||||
instruction := ElnaInstructionList_get_next(instruction);
|
instruction := instruction^.next;
|
||||||
goto elna_writer_instructions_start
|
goto elna_writer_instructions_start
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_procedure(procedure: Word);
|
proc _elna_writer_procedure(procedure: ^ElnaInstructionDeclaration);
|
||||||
var
|
|
||||||
name_pointer: Word;
|
|
||||||
name_length: Word;
|
|
||||||
body_statements: Word;
|
|
||||||
has_stack: Word;
|
|
||||||
begin
|
begin
|
||||||
.elna_writer_procedure_loop;
|
.elna_writer_procedure_loop;
|
||||||
name_pointer := ElnaInstructionDeclaration_get_name(procedure);
|
|
||||||
name_length := ElnaInstructionDeclaration_get_length(procedure);
|
|
||||||
body_statements := ElnaInstructionDeclaration_get_body(procedure);
|
|
||||||
has_stack := ElnaInstructionDeclaration_get_stack(procedure);
|
|
||||||
|
|
||||||
(* Write .type _procedure_name, @function. *)
|
(* Write .type _procedure_name, @function. *)
|
||||||
_write_z(".type \0");
|
_write_z(".type \0");
|
||||||
|
|
||||||
_write_s(name_pointer, name_length);
|
_write_s(procedure^.name, procedure^.length);
|
||||||
_write_z(", @function\n\0");
|
_write_z(", @function\n\0");
|
||||||
|
|
||||||
(* Write procedure label, _procedure_name: *)
|
(* Write procedure label, _procedure_name: *)
|
||||||
_write_s(name_pointer, name_length);
|
_write_s(procedure^.name, procedure^.length);
|
||||||
_write_z(":\n\0");
|
_write_z(":\n\0");
|
||||||
|
|
||||||
(* Write the prologue. *)
|
(* Write the prologue. *)
|
||||||
if has_stack then
|
if procedure^.stack then
|
||||||
_write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\n\0")
|
_write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\n\0")
|
||||||
end;
|
end;
|
||||||
_elna_writer_instructions(body_statements);
|
_elna_writer_instructions(procedure^.body);
|
||||||
(* Write the epilogue. *)
|
(* Write the epilogue. *)
|
||||||
if has_stack then
|
if procedure^.stack then
|
||||||
_write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\n\0")
|
_write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\n\0")
|
||||||
end;
|
end;
|
||||||
_write_z("\tret\n\0");
|
_write_z("\tret\n\0");
|
||||||
|
|
||||||
procedure := ElnaInstructionList_get_next(procedure);
|
procedure := procedure^.next;
|
||||||
if procedure <> 0 then
|
if procedure <> 0 then
|
||||||
goto elna_writer_procedure_loop
|
goto elna_writer_procedure_loop
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_variable(variable: Word);
|
proc _elna_writer_variable(variable: ^ElnaInstructionDeclaration);
|
||||||
var
|
|
||||||
name: Word;
|
|
||||||
name_length: Word;
|
|
||||||
size: Word;
|
|
||||||
begin
|
begin
|
||||||
.elna_writer_variable_loop;
|
.elna_writer_variable_loop;
|
||||||
if variable <> 0 then
|
if variable <> 0 then
|
||||||
name := ElnaInstructionDeclaration_get_name(variable);
|
|
||||||
name_length := ElnaInstructionDeclaration_get_length(variable);
|
|
||||||
size := ElnaInstructionDeclaration_get_body(variable);
|
|
||||||
|
|
||||||
_write_z(".type \0");
|
_write_z(".type \0");
|
||||||
_write_s(name, name_length);
|
_write_s(variable^.name, variable^.length);
|
||||||
_write_z(", @object\n\0");
|
_write_z(", @object\n\0");
|
||||||
|
|
||||||
_write_s(name, name_length);
|
_write_s(variable^.name, variable^.length);
|
||||||
_write_c(':');
|
_write_c(':');
|
||||||
|
|
||||||
_write_z(" .zero \0");
|
_write_z(" .zero \0");
|
||||||
_write_i(size);
|
_write_i(variable^.body);
|
||||||
|
|
||||||
_write_c('\n');
|
_write_c('\n');
|
||||||
variable := ElnaInstructionList_get_next(variable);
|
variable := variable^.next;
|
||||||
|
|
||||||
goto elna_writer_variable_loop
|
goto elna_writer_variable_loop
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_module_declaration(tac_module: Word);
|
proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule);
|
||||||
var
|
var
|
||||||
code_part: Word;
|
code_part: Word;
|
||||||
data_part: Word;
|
data_part: Word;
|
||||||
current_part: Word;
|
|
||||||
begin
|
begin
|
||||||
current_part := ElnaInstructionModule_get_data(tac_module);
|
data_part := elna_rtl_globals(tac_module^.data);
|
||||||
data_part := elna_rtl_globals(current_part);
|
code_part := elna_rtl_procedures(tac_module^.code);
|
||||||
|
|
||||||
current_part := ElnaInstructionModule_get_code(tac_module);
|
|
||||||
code_part := elna_rtl_procedures(current_part);
|
|
||||||
|
|
||||||
return elna_instruction_module_create(data_part, code_part)
|
return elna_instruction_module_create(data_part, code_part)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_module(pair: Word);
|
proc _elna_writer_module(pair: ^ElnaInstructionModule);
|
||||||
var
|
var
|
||||||
compiler_strings_copy: Word;
|
compiler_strings_copy: Word;
|
||||||
compiler_strings_end: Word;
|
compiler_strings_end: Word;
|
||||||
current_byte: Word;
|
current_byte: Word;
|
||||||
current_part: Word;
|
|
||||||
begin
|
begin
|
||||||
_write_z(".globl main\n\n\0");
|
_write_z(".globl main\n\n\0");
|
||||||
_write_z(".section .data\n\0");
|
_write_z(".section .data\n\0");
|
||||||
|
|
||||||
current_part := ElnaInstructionModule_get_data(pair);
|
_elna_writer_variable(pair^.data);
|
||||||
_elna_writer_variable(current_part);
|
|
||||||
|
|
||||||
_write_z(".section .text\n\n\0");
|
_write_z(".section .text\n\n\0");
|
||||||
_write_z(".type _syscall, @function\n_syscall:\n\tmv a7, a6\n\tecall\n\tret\n\n\0");
|
_write_z(".type _syscall, @function\n_syscall:\n\tmv a7, a6\n\tecall\n\tret\n\n\0");
|
||||||
_write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0");
|
_write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0");
|
||||||
_write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0");
|
_write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0");
|
||||||
|
|
||||||
current_part := ElnaInstructionModule_get_code(pair);
|
_elna_writer_procedure(pair^.code);
|
||||||
_elna_writer_procedure(current_part);
|
|
||||||
|
|
||||||
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
|
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
|
||||||
_write_c('"');
|
_write_c('"');
|
||||||
@@ -1578,43 +1554,44 @@ proc elna_parser_integer_literal();
|
|||||||
var
|
var
|
||||||
integer_token: Word;
|
integer_token: Word;
|
||||||
integer_length: Word;
|
integer_length: Word;
|
||||||
result: Word;
|
result: ^ElnaTreeIntegerLiteral;
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaTreeIntegerLiteral_size());
|
result := malloc(ElnaTreeIntegerLiteral_size());
|
||||||
|
|
||||||
|
(* TODO: Convert the integer string to a number. *)
|
||||||
integer_token := _elna_lexer_global_get_start();
|
integer_token := _elna_lexer_global_get_start();
|
||||||
integer_length := _elna_lexer_global_get_end();
|
integer_length := _elna_lexer_global_get_end();
|
||||||
integer_length := integer_length - integer_token;
|
integer_length := integer_length - integer_token;
|
||||||
_elna_lexer_skip_token();
|
_elna_lexer_skip_token();
|
||||||
|
|
||||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.integer_literal);
|
result^.kind := ElnaTreeKind.integer_literal;
|
||||||
ElnaTreeIntegerLiteral_set_value(result, integer_token);
|
result^.value := integer_token;
|
||||||
ElnaTreeIntegerLiteral_set_length(result, integer_length);
|
result^.length := integer_length;
|
||||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
result^.type_decoration := nil;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_nil_literal();
|
proc elna_parser_nil_literal();
|
||||||
var
|
var
|
||||||
result: Word;
|
result: ^ElnaTreeNilLiteral;
|
||||||
begin
|
begin
|
||||||
_elna_lexer_skip_token();
|
_elna_lexer_skip_token();
|
||||||
|
|
||||||
result := malloc(ElnaTreeNilLiteral_size());
|
result := malloc(ElnaTreeNilLiteral_size());
|
||||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.null);
|
result^.kind := ElnaTreeKind.null;
|
||||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
result^.type_decoration := nil;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_integer_literal(integer_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc _elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ := ElnaTreeIntegerLiteral_get_value(integer_literal_node);
|
operand_value^ := integer_literal_node^.value;
|
||||||
operand_length^ := ElnaTreeIntegerLiteral_get_length(integer_literal_node);
|
operand_length^ := integer_literal_node^.length;
|
||||||
|
|
||||||
return 0
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc _elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
@@ -1623,14 +1600,14 @@ begin
|
|||||||
operand_value^ := 0;
|
operand_value^ := 0;
|
||||||
operand_length^ := 0;
|
operand_length^ := 0;
|
||||||
|
|
||||||
return 0
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_character_literal();
|
proc elna_parser_character_literal();
|
||||||
var
|
var
|
||||||
character: Word;
|
character: Word;
|
||||||
character_length: Word;
|
character_length: Word;
|
||||||
result: Word;
|
result: ^ElnaTreeIntegerLiteral;
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaTreeCharacterLiteral_size());
|
result := malloc(ElnaTreeCharacterLiteral_size());
|
||||||
|
|
||||||
@@ -1639,28 +1616,28 @@ begin
|
|||||||
character_length := character_length - character;
|
character_length := character_length - character;
|
||||||
_elna_lexer_skip_token();
|
_elna_lexer_skip_token();
|
||||||
|
|
||||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.character_literal);
|
result^.kind := ElnaTreeKind.character_literal;
|
||||||
ElnaTreeIntegerLiteral_set_value(result, character);
|
result^.value := character;
|
||||||
ElnaTreeIntegerLiteral_set_length(result, character_length);
|
result^.length := character_length;
|
||||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
result^.type_decoration := nil;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_character_literal(character_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc _elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ :=ElnaTreeCharacterLiteral_get_value(character_literal_node);
|
operand_value^ := character_literal_node^.value;
|
||||||
operand_length^ := ElnaTreeCharacterLiteral_get_length(character_literal_node);
|
operand_length^ := character_literal_node^.length;
|
||||||
|
|
||||||
return 0
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_variable_expression();
|
proc elna_parser_variable_expression();
|
||||||
var
|
var
|
||||||
name_pointer: Word;
|
name_pointer: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
result: Word;
|
result: ^ElnaTreeVariableExpression;
|
||||||
begin
|
begin
|
||||||
name_pointer := _elna_lexer_global_get_start();
|
name_pointer := _elna_lexer_global_get_start();
|
||||||
name_length := _elna_lexer_global_get_end() - name_pointer;
|
name_length := _elna_lexer_global_get_end() - name_pointer;
|
||||||
@@ -1668,34 +1645,29 @@ begin
|
|||||||
|
|
||||||
result := malloc(ElnaTreeVariableExpression_size());
|
result := malloc(ElnaTreeVariableExpression_size());
|
||||||
|
|
||||||
ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_expression);
|
result^.kind := ElnaTreeKind.variable_expression;
|
||||||
ElnaTreeVariableExpression_set_name(result, name_pointer);
|
result^.name := name_pointer;
|
||||||
ElnaTreeVariableExpression_set_length(result, name_length);
|
result^.length := name_length;
|
||||||
ElnaTreeExpression_set_type_decoration(result, nil);
|
result^.type_decoration := nil;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
name_pointer: Word;
|
lookup_result: ^_parameter_info;
|
||||||
name_length: Word;
|
|
||||||
lookup_result: Word;
|
|
||||||
begin
|
begin
|
||||||
name_pointer := ElnaTreeVariableExpression_get_name(variable_expression);
|
lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length);
|
||||||
name_length := ElnaTreeVariableExpression_get_length(variable_expression);
|
if lookup_result <> nil then
|
||||||
|
|
||||||
lookup_result := _symbol_table_lookup(symbol_table, name_pointer, name_length);
|
|
||||||
if lookup_result <> 0 then
|
|
||||||
operand_type^ := ElnaTacOperand.stack;
|
operand_type^ := ElnaTacOperand.stack;
|
||||||
operand_value^ := _parameter_info_get_offset(lookup_result);
|
operand_value^ := lookup_result^.offset;
|
||||||
operand_length^ := 0
|
operand_length^ := 0
|
||||||
else
|
else
|
||||||
operand_type^ := ElnaTacOperand.symbol;
|
operand_type^ := ElnaTacOperand.symbol;
|
||||||
operand_value^ := name_pointer;
|
operand_value^ := variable_expression^.name;
|
||||||
operand_length^ := name_length
|
operand_length^ := variable_expression^.length
|
||||||
end;
|
end;
|
||||||
return 0
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_string_literal();
|
proc elna_parser_string_literal();
|
||||||
@@ -1789,14 +1761,18 @@ var
|
|||||||
begin
|
begin
|
||||||
simple_expression := elna_parser_simple_expression();
|
simple_expression := elna_parser_simple_expression();
|
||||||
|
|
||||||
|
.elna_parser_designator_loop;
|
||||||
_elna_lexer_read_token(@token_kind);
|
_elna_lexer_read_token(@token_kind);
|
||||||
|
|
||||||
if token_kind = ElnaLexerKind.hat then
|
if token_kind = ElnaLexerKind.hat then
|
||||||
simple_expression := elna_parser_dereference_expression(simple_expression)
|
simple_expression := elna_parser_dereference_expression(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
elsif token_kind = ElnaLexerKind.dot then
|
elsif token_kind = ElnaLexerKind.dot then
|
||||||
simple_expression := elna_parser_field_access_expression(simple_expression)
|
simple_expression := elna_parser_field_access_expression(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
elsif token_kind = ElnaLexerKind.left_paren then
|
elsif token_kind = ElnaLexerKind.left_paren then
|
||||||
simple_expression := elna_parser_call(simple_expression)
|
simple_expression := elna_parser_call(simple_expression);
|
||||||
|
goto elna_parser_designator_loop
|
||||||
end;
|
end;
|
||||||
return simple_expression
|
return simple_expression
|
||||||
end;
|
end;
|
||||||
@@ -2414,12 +2390,21 @@ var
|
|||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
last_instruction: Word;
|
last_instruction: Word;
|
||||||
type_kind: Word;
|
type_kind: Word;
|
||||||
|
designator_base: Word;
|
||||||
|
aggregate_type: Word;
|
||||||
|
name_pointer: Word;
|
||||||
|
name_length: Word;
|
||||||
|
field_name_pointer: Word;
|
||||||
|
field_name_length: Word;
|
||||||
|
field_count: Word;
|
||||||
|
current_field: Word;
|
||||||
|
field_offset: Word;
|
||||||
begin
|
begin
|
||||||
node_kind := ElnaTreeNode_get_kind(parser_node);
|
node_kind := ElnaTreeNode_get_kind(parser_node);
|
||||||
|
|
||||||
if node_kind = ElnaTreeKind.dereference_expression then
|
if node_kind = ElnaTreeKind.dereference_expression then
|
||||||
parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
||||||
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
|
first_instruction := _elna_tac_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
@@ -2436,17 +2421,42 @@ begin
|
|||||||
type_kind := ElnaType_get_kind(expression_type);
|
type_kind := ElnaType_get_kind(expression_type);
|
||||||
|
|
||||||
if type_kind = ElnaTypeKind.enumeration then
|
if type_kind = ElnaTypeKind.enumeration then
|
||||||
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length)
|
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
|
||||||
|
is_address^ := 0
|
||||||
else
|
else
|
||||||
(* Stub for record field access. Always generate nil for field access expression until it is implemented. *)
|
designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node);
|
||||||
|
first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
|
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
|
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
||||||
|
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
||||||
|
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
field_count := ElnaTypeRecord_get_length(aggregate_type);
|
||||||
operand_value^ := 0;
|
current_field := ElnaTypeRecord_get_members(aggregate_type);
|
||||||
|
field_offset := 0;
|
||||||
|
|
||||||
|
.elna_tac_designator_field;
|
||||||
|
|
||||||
|
field_name_pointer := ElnaTypeField_get_name(current_field);
|
||||||
|
field_name_length := ElnaTypeField_get_length(current_field);
|
||||||
|
|
||||||
|
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then
|
||||||
|
field_count := field_count - 1;
|
||||||
|
current_field := current_field + ElnaTypeField_size();
|
||||||
|
field_offset := field_offset + 4;
|
||||||
|
goto elna_tac_designator_field
|
||||||
|
end;
|
||||||
|
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0);
|
||||||
|
_elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^);
|
||||||
|
|
||||||
|
operand_type^ := ElnaTacOperand.temporary;
|
||||||
|
operand_value^ := 6;
|
||||||
operand_length^ := 0;
|
operand_length^ := 0;
|
||||||
|
|
||||||
first_instruction := nil
|
is_address^ := 1;
|
||||||
|
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
||||||
end;
|
end;
|
||||||
is_address^ := 0
|
|
||||||
elsif node_kind = ElnaTreeKind.call then
|
elsif node_kind = ElnaTreeKind.call then
|
||||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
||||||
|
|
||||||
@@ -3505,40 +3515,28 @@ begin
|
|||||||
return first_instruction
|
return first_instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_global_declaration(tac_declaration: Word);
|
proc elna_rtl_global_declaration(tac_declaration: ^ElnaInstructionDeclaration);
|
||||||
var
|
var
|
||||||
name: Word;
|
result: ElnaInstructionDeclaration;
|
||||||
length: Word;
|
|
||||||
body: Word;
|
|
||||||
result: Word;
|
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaInstructionDeclaration_size());
|
result := malloc(ElnaInstructionDeclaration_size());
|
||||||
name := ElnaInstructionDeclaration_get_name(tac_declaration);
|
|
||||||
length := ElnaInstructionDeclaration_get_length(tac_declaration);
|
|
||||||
body := ElnaInstructionDeclaration_get_body(tac_declaration);
|
|
||||||
|
|
||||||
ElnaInstructionList_set_next(result, 0);
|
result^.next := 0;
|
||||||
ElnaInstructionDeclaration_set_name(result, name);
|
result^.name := tac_declaration^.name;
|
||||||
ElnaInstructionDeclaration_set_length(result, length);
|
result^.length := tac_declaration^.length;
|
||||||
ElnaInstructionDeclaration_set_body(result, body);
|
result^.body := tac_declaration^.body;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_procedure_declaration(tac_declaration: Word);
|
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration);
|
||||||
var
|
var
|
||||||
name: Word;
|
|
||||||
length: Word;
|
|
||||||
body: Word;
|
body: Word;
|
||||||
result: Word;
|
result: ^ElnaInstructionDeclaration;
|
||||||
return_instruction: Word;
|
return_instruction: Word;
|
||||||
has_stack: Word;
|
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaInstructionDeclaration_size());
|
result := malloc(ElnaInstructionDeclaration_size());
|
||||||
name := ElnaInstructionDeclaration_get_name(tac_declaration);
|
body := tac_declaration^.body;
|
||||||
length := ElnaInstructionDeclaration_get_length(tac_declaration);
|
|
||||||
has_stack := ElnaInstructionDeclaration_get_stack(tac_declaration);
|
|
||||||
body := ElnaInstructionDeclaration_get_body(tac_declaration);
|
|
||||||
body := elna_rtl_instructions(body);
|
body := elna_rtl_instructions(body);
|
||||||
|
|
||||||
return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
|
return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
|
||||||
@@ -3547,50 +3545,45 @@ begin
|
|||||||
return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
|
return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
|
||||||
elna_instruction_list_concatenate(body, return_instruction);
|
elna_instruction_list_concatenate(body, return_instruction);
|
||||||
|
|
||||||
ElnaInstructionList_set_next(result, 0);
|
result^.next := nil;
|
||||||
ElnaInstructionDeclaration_set_name(result, name);
|
result^.name := tac_declaration^.name;
|
||||||
ElnaInstructionDeclaration_set_length(result, length);
|
result^.length := tac_declaration^.length;
|
||||||
ElnaInstructionDeclaration_set_stack(result, has_stack);
|
result^.stack := tac_declaration^.stack;
|
||||||
ElnaInstructionDeclaration_set_body(result, body);
|
result^.body := body;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_procedure_declaration(parser_node: Word);
|
proc _elna_tac_procedure_declaration(parser_node: _procedure_declaration);
|
||||||
var
|
var
|
||||||
name_pointer: Word;
|
|
||||||
name_length: Word;
|
|
||||||
current_parameter: Word;
|
current_parameter: Word;
|
||||||
body: Word;
|
body: Word;
|
||||||
new_symbol_table: Word;
|
new_symbol_table: Word;
|
||||||
symbol_info: Word;
|
symbol_info: ^_procedure_info;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
result: Word;
|
result: ^ElnaInstructionDeclaration;
|
||||||
result_size: Word;
|
result_size: Word;
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaInstructionDeclaration_size());
|
result := malloc(ElnaInstructionDeclaration_size());
|
||||||
|
|
||||||
ElnaInstructionList_set_next(result, 0);
|
result^.next := nil;
|
||||||
ElnaInstructionDeclaration_set_stack(result, 1);
|
result^.stack := 1;
|
||||||
|
|
||||||
name_pointer := _declaration_get_name(parser_node);
|
result^.name := parser_node^.name;
|
||||||
name_length := _declaration_get_length(parser_node);
|
result^.length := parser_node^.length;
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_name(result, name_pointer);
|
symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
|
||||||
ElnaInstructionDeclaration_set_length(result, name_length);
|
new_symbol_table := symbol_info^.symbol_table;
|
||||||
|
|
||||||
symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
|
current_parameter := parser_node^.parameters;
|
||||||
new_symbol_table := _procedure_info_get_symbol_table(symbol_info);
|
|
||||||
|
|
||||||
current_parameter := _procedure_declaration_get_parameters(parser_node);
|
|
||||||
first_instruction := _elna_tac_parameters(current_parameter, new_symbol_table);
|
first_instruction := _elna_tac_parameters(current_parameter, new_symbol_table);
|
||||||
|
|
||||||
body := _procedure_declaration_get_body(parser_node);
|
body := _procedure_declaration_get_body(parser_node);
|
||||||
instruction := _elna_tac_statements(body, new_symbol_table);
|
instruction := _elna_tac_statements(body, new_symbol_table);
|
||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
|
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_body(result, first_instruction);
|
result^.body := first_instruction;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
@@ -3626,17 +3619,17 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_globals(tac_procedure: Word);
|
proc elna_rtl_globals(tac_procedure: ^ElnaInstructionList);
|
||||||
var
|
var
|
||||||
current_copy: Word;
|
current_copy: ^ElnaInstructionList;
|
||||||
next_copy: Word;
|
next_copy: Word;
|
||||||
first_copy: Word;
|
first_copy: ^ElnaInstructionList;
|
||||||
begin
|
begin
|
||||||
if tac_procedure <> 0 then
|
if tac_procedure <> 0 then
|
||||||
first_copy := elna_rtl_global_declaration(tac_procedure);
|
first_copy := elna_rtl_global_declaration(tac_procedure);
|
||||||
tac_procedure := ElnaInstructionList_get_next(tac_procedure)
|
tac_procedure := tac_procedure^.next
|
||||||
else
|
else
|
||||||
first_copy := 0;
|
first_copy := nil
|
||||||
end;
|
end;
|
||||||
current_copy := first_copy;
|
current_copy := first_copy;
|
||||||
|
|
||||||
@@ -3645,8 +3638,8 @@ begin
|
|||||||
if tac_procedure <> 0 then
|
if tac_procedure <> 0 then
|
||||||
next_copy := elna_rtl_global_declaration(tac_procedure);
|
next_copy := elna_rtl_global_declaration(tac_procedure);
|
||||||
|
|
||||||
tac_procedure := ElnaInstructionList_get_next(tac_procedure);
|
tac_procedure := tac_procedure^.next;
|
||||||
ElnaInstructionList_set_next(current_copy, next_copy);
|
current_copy^.next := next_copy;
|
||||||
current_copy := next_copy;
|
current_copy := next_copy;
|
||||||
goto elna_rtl_globals_start
|
goto elna_rtl_globals_start
|
||||||
end;
|
end;
|
||||||
@@ -3654,27 +3647,27 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_procedures(tac_procedure: Word);
|
proc elna_rtl_procedures(tac_procedure: ^ElnaInstructionList);
|
||||||
var
|
var
|
||||||
current_copy: Word;
|
current_copy: ^ElnaInstructionList;
|
||||||
next_copy: Word;
|
next_copy: Word;
|
||||||
first_copy: Word;
|
first_copy: ^ElnaInstructionList;
|
||||||
begin
|
begin
|
||||||
if tac_procedure <> 0 then
|
if tac_procedure <> nil then
|
||||||
first_copy := elna_rtl_procedure_declaration(tac_procedure);
|
first_copy := elna_rtl_procedure_declaration(tac_procedure);
|
||||||
tac_procedure := ElnaInstructionList_get_next(tac_procedure)
|
tac_procedure := tac_procedure^.next
|
||||||
else
|
else
|
||||||
first_copy := 0;
|
first_copy := nil;
|
||||||
end;
|
end;
|
||||||
current_copy := first_copy;
|
current_copy := first_copy;
|
||||||
|
|
||||||
.elna_rtl_procedures_start;
|
.elna_rtl_procedures_start;
|
||||||
|
|
||||||
if tac_procedure <> 0 then
|
if tac_procedure <> nil then
|
||||||
next_copy := elna_rtl_procedure_declaration(tac_procedure);
|
next_copy := elna_rtl_procedure_declaration(tac_procedure);
|
||||||
|
|
||||||
tac_procedure := ElnaInstructionList_get_next(tac_procedure);
|
tac_procedure := tac_procedure^.next;
|
||||||
ElnaInstructionList_set_next(current_copy, next_copy);
|
current_copy^.next := next_copy;
|
||||||
current_copy := next_copy;
|
current_copy := next_copy;
|
||||||
goto elna_rtl_procedures_start
|
goto elna_rtl_procedures_start
|
||||||
end;
|
end;
|
||||||
@@ -3682,10 +3675,10 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_procedures(parser_node: Word);
|
proc _elna_tac_procedures(parser_node: ^_declaration);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
current_procedure: Word;
|
current_procedure: ^ElnaInstructionList;
|
||||||
first_procedure: Word;
|
first_procedure: Word;
|
||||||
begin
|
begin
|
||||||
first_procedure := 0;
|
first_procedure := 0;
|
||||||
@@ -3698,11 +3691,11 @@ begin
|
|||||||
if first_procedure = 0 then
|
if first_procedure = 0 then
|
||||||
first_procedure := result
|
first_procedure := result
|
||||||
else
|
else
|
||||||
ElnaInstructionList_set_next(current_procedure, result)
|
current_procedure^.next := result
|
||||||
end;
|
end;
|
||||||
current_procedure := result;
|
current_procedure := result;
|
||||||
|
|
||||||
parser_node := _declaration_get_next(parser_node);
|
parser_node := parser_node^.next;
|
||||||
goto elna_tac_procedures_loop;
|
goto elna_tac_procedures_loop;
|
||||||
|
|
||||||
.elna_tac_procedures_end;
|
.elna_tac_procedures_end;
|
||||||
@@ -3757,16 +3750,16 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_name_type_declaration(parser_node: Word);
|
proc elna_name_type_declaration(parser_node: ^_type_declaration);
|
||||||
var
|
var
|
||||||
type_name: Word;
|
type_name: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
type_info: Word;
|
type_info: Word;
|
||||||
begin
|
begin
|
||||||
type_name := _declaration_get_name(parser_node);
|
type_name := parser_node^.name;
|
||||||
name_length := _declaration_get_length(parser_node);
|
name_length := parser_node^.length;
|
||||||
|
|
||||||
parser_node := _type_declaration_get__type(parser_node);
|
parser_node := parser_node^._type;
|
||||||
type_info := elna_name_type_expression(parser_node);
|
type_info := elna_name_type_expression(parser_node);
|
||||||
type_info := _type_info_create(type_info);
|
type_info := _type_info_create(type_info);
|
||||||
|
|
||||||
@@ -3843,32 +3836,32 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_variable_declaration(parser_tree: Word);
|
proc _elna_tac_variable_declaration(parser_tree: ^_variable_declaration);
|
||||||
var
|
var
|
||||||
name: Word;
|
name: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
variable_type: Word;
|
variable_type: ^ElnaTreeNamedTypeExpression;
|
||||||
result: Word;
|
result: ^ElnaInstructionDeclaration;
|
||||||
begin
|
begin
|
||||||
result := malloc(ElnaInstructionDeclaration_size());
|
result := malloc(ElnaInstructionDeclaration_size());
|
||||||
|
|
||||||
ElnaInstructionList_set_next(result, 0);
|
result^.next := nil;
|
||||||
|
|
||||||
name := _declaration_get_name(parser_tree);
|
name := parser_tree^.name;
|
||||||
name_length := _declaration_get_length(parser_tree);
|
name_length := parser_tree^.length;
|
||||||
variable_type := _variable_declaration_get__type(parser_tree);
|
variable_type := parser_tree^._type;
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_name(result, name);
|
result^.name := name;
|
||||||
ElnaInstructionDeclaration_set_length(result, name_length);
|
result^.length := name_length;
|
||||||
|
|
||||||
name := ElnaTreeNamedTypeExpression_get_name(variable_type);
|
name := variable_type^.name;
|
||||||
name_length := ElnaTreeNamedTypeExpression_get_length(variable_type);
|
name_length := variable_type^.length;
|
||||||
|
|
||||||
if string_compare("Array", 5, name, name_length) then
|
if string_compare("Array", 5, name, name_length) then
|
||||||
(* Else we assume this is a zeroed 4096 bytes big array. *)
|
(* Else we assume this is a zeroed 4096 bytes big array. *)
|
||||||
ElnaInstructionDeclaration_set_body(result, 4096)
|
result^.body := 4096
|
||||||
else
|
else
|
||||||
ElnaInstructionDeclaration_set_body(result, 4)
|
result^.body := 4
|
||||||
end;
|
end;
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
@@ -3937,11 +3930,10 @@ begin
|
|||||||
return first_result
|
return first_result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: Word, current_result: Word);
|
proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: ^ElnaTypeRecord, current_result: Word);
|
||||||
var
|
var
|
||||||
first_result: Word;
|
first_result: Word;
|
||||||
result: Word;
|
result: ^ElnaInstructionList;
|
||||||
type_size: Word;
|
|
||||||
new_name: Word;
|
new_name: Word;
|
||||||
new_length: Word;
|
new_length: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -3952,7 +3944,6 @@ begin
|
|||||||
first_result := malloc(ElnaInstructionDeclaration_size());
|
first_result := malloc(ElnaInstructionDeclaration_size());
|
||||||
result := 0;
|
result := 0;
|
||||||
|
|
||||||
type_size := ElnaType_get_size(type_representation);
|
|
||||||
new_length := name_length + 5;
|
new_length := name_length + 5;
|
||||||
new_name := malloc(new_length);
|
new_name := malloc(new_length);
|
||||||
|
|
||||||
@@ -3964,12 +3955,12 @@ begin
|
|||||||
|
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0);
|
||||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0);
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_representation^.size, 0);
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_body(first_result, instruction);
|
ElnaInstructionDeclaration_set_body(first_result, instruction);
|
||||||
|
|
||||||
field_count := ElnaTypeRecord_get_length(type_representation);
|
field_count := type_representation^.length;
|
||||||
field_pointer := ElnaTypeRecord_get_members(type_representation);
|
field_pointer := type_representation^.members;
|
||||||
field_offset := 0;
|
field_offset := 0;
|
||||||
current_result^ := first_result;
|
current_result^ := first_result;
|
||||||
|
|
||||||
@@ -3978,7 +3969,7 @@ begin
|
|||||||
result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset);
|
result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset);
|
||||||
|
|
||||||
ElnaInstructionList_set_next(current_result^, result);
|
ElnaInstructionList_set_next(current_result^, result);
|
||||||
current_result^ := ElnaInstructionList_get_next(result);
|
current_result^ := result^.next;
|
||||||
|
|
||||||
field_offset := field_offset + 4;
|
field_offset := field_offset + 4;
|
||||||
field_count := field_count - 1;
|
field_count := field_count - 1;
|
||||||
@@ -3989,17 +3980,15 @@ begin
|
|||||||
return first_result
|
return first_result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_type_part(parser_node: Word);
|
proc _elna_tac_type_part(parser_node: ^_declaration);
|
||||||
var
|
var
|
||||||
name_pointer: Word;
|
|
||||||
name_length: Word;
|
|
||||||
result: Word;
|
result: Word;
|
||||||
first_result: Word;
|
first_result: Word;
|
||||||
symbol: Word;
|
symbol: ^_type_info;
|
||||||
info_type: Word;
|
info_type: ^ElnaType;
|
||||||
type_kind: Word;
|
type_kind: Word;
|
||||||
current_result: Word;
|
current_result: ^ElnaInstructionList;
|
||||||
out_result: Word;
|
out_result: ^ElnaInstructionList;
|
||||||
begin
|
begin
|
||||||
first_result := 0;
|
first_result := 0;
|
||||||
|
|
||||||
@@ -4007,16 +3996,13 @@ begin
|
|||||||
if parser_node = 0 then
|
if parser_node = 0 then
|
||||||
goto elna_tac_type_part_end
|
goto elna_tac_type_part_end
|
||||||
end;
|
end;
|
||||||
|
symbol := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
|
||||||
|
|
||||||
name_pointer := _declaration_get_name(parser_node);
|
info_type := symbol^._type;
|
||||||
name_length := _declaration_get_length(parser_node);
|
type_kind := info_type^.kind;
|
||||||
symbol := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
|
|
||||||
|
|
||||||
info_type := _type_info_get__type(symbol);
|
|
||||||
type_kind := ElnaType_get_kind(info_type);
|
|
||||||
|
|
||||||
if type_kind = ElnaTypeKind._record then
|
if type_kind = ElnaTypeKind._record then
|
||||||
result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result)
|
result := _elna_tac_type_record(parser_node^.name, parser_node^.length, info_type, @out_result)
|
||||||
else
|
else
|
||||||
result := 0;
|
result := 0;
|
||||||
out_result := 0
|
out_result := 0
|
||||||
@@ -4025,10 +4011,10 @@ begin
|
|||||||
first_result := result;
|
first_result := result;
|
||||||
current_result := out_result
|
current_result := out_result
|
||||||
elsif result <> 0 then
|
elsif result <> 0 then
|
||||||
ElnaInstructionList_set_next(current_result, result);
|
current_result^.next := result;
|
||||||
current_result := out_result
|
current_result := out_result
|
||||||
end;
|
end;
|
||||||
parser_node := _declaration_get_next(parser_node);
|
parser_node := parser_node^.next;
|
||||||
goto elna_tac_type_part_loop;
|
goto elna_tac_type_part_loop;
|
||||||
|
|
||||||
.elna_tac_type_part_end;
|
.elna_tac_type_part_end;
|
||||||
@@ -4075,10 +4061,10 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_var_part(parser_node: Word);
|
proc _elna_tac_var_part(parser_node: ^_declaration);
|
||||||
var
|
var
|
||||||
node: Word;
|
node: Word;
|
||||||
current_variable: Word;
|
current_variable: ^ElnaInstructionList;
|
||||||
first_variable: Word;
|
first_variable: Word;
|
||||||
begin
|
begin
|
||||||
first_variable := 0;
|
first_variable := 0;
|
||||||
@@ -4091,11 +4077,11 @@ begin
|
|||||||
if first_variable = 0 then
|
if first_variable = 0 then
|
||||||
first_variable := node
|
first_variable := node
|
||||||
else
|
else
|
||||||
ElnaInstructionList_set_next(current_variable, node)
|
current_variable^.next := node
|
||||||
end;
|
end;
|
||||||
current_variable := node;
|
current_variable := node;
|
||||||
|
|
||||||
parser_node := _declaration_get_next(parser_node);
|
parser_node := parser_node^.next;
|
||||||
if parser_node <> 0 then
|
if parser_node <> 0 then
|
||||||
goto elna_tac_var_part_loop
|
goto elna_tac_var_part_loop
|
||||||
end;
|
end;
|
||||||
@@ -4136,33 +4122,28 @@ end;
|
|||||||
(**
|
(**
|
||||||
* Process the source code and print the generated code.
|
* Process the source code and print the generated code.
|
||||||
*)
|
*)
|
||||||
proc _elna_tac_module_declaration(parser_node: Word);
|
proc _elna_tac_module_declaration(parser_node: ^_module_declaration);
|
||||||
var
|
var
|
||||||
data_part: Word;
|
data_part: Word;
|
||||||
code_part: Word;
|
code_part: Word;
|
||||||
type_part: Word;
|
type_part: Word;
|
||||||
current_declaration: Word;
|
current_declaration: ^ElnaInstructionList;
|
||||||
next_declaration: Word;
|
next_declaration: Word;
|
||||||
begin
|
begin
|
||||||
type_part := _module_declaration_get_types(parser_node);
|
type_part := _elna_tac_type_part(parser_node^.types);
|
||||||
type_part := _elna_tac_type_part(type_part);
|
data_part := _elna_tac_var_part(parser_node^.globals);
|
||||||
|
code_part := _elna_tac_procedures(parser_node^.procedures);
|
||||||
data_part := _module_declaration_get_globals(parser_node);
|
|
||||||
data_part := _elna_tac_var_part(data_part);
|
|
||||||
|
|
||||||
code_part := _module_declaration_get_procedures(parser_node);
|
|
||||||
code_part := _elna_tac_procedures(code_part);
|
|
||||||
|
|
||||||
current_declaration := code_part;
|
current_declaration := code_part;
|
||||||
|
|
||||||
.elna_tac_module_declaration_types;
|
.elna_tac_module_declaration_types;
|
||||||
next_declaration := ElnaInstructionList_get_next(current_declaration);
|
next_declaration := current_declaration^.next;
|
||||||
if next_declaration <> 0 then
|
if next_declaration <> nil then
|
||||||
current_declaration := next_declaration;
|
current_declaration := next_declaration;
|
||||||
|
|
||||||
goto elna_tac_module_declaration_types
|
goto elna_tac_module_declaration_types
|
||||||
end;
|
end;
|
||||||
ElnaInstructionList_set_next(current_declaration, type_part);
|
current_declaration^.next := type_part;
|
||||||
|
|
||||||
return elna_instruction_module_create(data_part, code_part)
|
return elna_instruction_module_create(data_part, code_part)
|
||||||
end;
|
end;
|
||||||
@@ -4411,7 +4392,7 @@ begin
|
|||||||
|
|
||||||
if expression_kind = ElnaTreeKind.dereference_expression then
|
if expression_kind = ElnaTreeKind.dereference_expression then
|
||||||
designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node);
|
||||||
elna_type_simple_expression(designator_base, symbol_table);
|
elna_type_designator(designator_base, symbol_table);
|
||||||
|
|
||||||
base_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
base_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
type_kind := ElnaType_get_kind(base_type);
|
type_kind := ElnaType_get_kind(base_type);
|
||||||
@@ -4442,7 +4423,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
(* If the base_type is still nil this is record field access. *)
|
(* If the base_type is still nil this is record field access. *)
|
||||||
if base_type = nil then
|
if base_type = nil then
|
||||||
elna_type_simple_expression(designator_base, symbol_table);
|
elna_type_designator(designator_base, symbol_table);
|
||||||
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base);
|
||||||
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node);
|
||||||
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
name_length := ElnaTreeFieldAccessExpression_get_length(parser_node);
|
||||||
@@ -4455,12 +4436,12 @@ begin
|
|||||||
field_name_pointer := ElnaTypeField_get_name(current_field);
|
field_name_pointer := ElnaTypeField_get_name(current_field);
|
||||||
field_name_length := ElnaTypeField_get_length(current_field);
|
field_name_length := ElnaTypeField_get_length(current_field);
|
||||||
|
|
||||||
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then
|
if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then
|
||||||
(* Debug. Error stream output.
|
(* Debug. Error stream output.
|
||||||
_syscall(2, name_pointer, name_length, 0, 0, 0, 64); *)
|
_syscall(2, name_pointer, name_length, 0, 0, 0, 64);
|
||||||
printf("# if %.*s\n\0", name_length, name_pointer);
|
printf("# if %.*s\n\0", name_length, name_pointer);
|
||||||
fflush(0)
|
fflush(0) *)
|
||||||
else
|
|
||||||
field_count := field_count - 1;
|
field_count := field_count - 1;
|
||||||
current_field := current_field + ElnaTypeField_size();
|
current_field := current_field + ElnaTypeField_size();
|
||||||
goto elna_type_designator_field
|
goto elna_type_designator_field
|
||||||
@@ -5558,5 +5539,5 @@ proc f(x: ElnaTreeExpression);
|
|||||||
var
|
var
|
||||||
y: Word;
|
y: Word;
|
||||||
begin
|
begin
|
||||||
y := x.type_decoration
|
y := x.kind
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user