Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/codegen'
Browse files Browse the repository at this point in the history
  • Loading branch information
loumadev committed Dec 4, 2023
2 parents 6b682f0 + 7c043ae commit 938ffe3
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 61 deletions.
6 changes: 2 additions & 4 deletions include/compiler/codegen/Codegen.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file include/compiler/codegen/Codegen.h
* @author Author Name <xlogin00@stud.fit.vutbr.cz>
* @brief This file is part of the IFJ23 project.
* @author Jaroslav Novotny <xnovot2r@stud.fit.vutbr.cz>
* @brief Header containing function definitions for code generator.
* @copyright Copyright (c) 2023
*/

Expand All @@ -21,8 +21,6 @@ enum Frame {
typedef struct Codegen {
Analyser *analyser;
enum Frame frame;
enum BuiltInType lastPushedType;
bool containsReturns;
} Codegen;

void Codegen_constructor(Codegen *codegen, Analyser *analyser);
Expand Down
6 changes: 4 additions & 2 deletions include/compiler/codegen/Instruction.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file include/compiler/codegen/Instruction.h
* @author Author Name <xlogin00@stud.fit.vutbr.cz>
* @brief This file is part of the IFJ23 project.
* @author Jaroslav Novotny <xnovot2r@stud.fit.vutbr.cz>
* @brief Header containing function definitions for instruction set.
* @copyright Copyright (c) 2023
*/

Expand Down Expand Up @@ -192,6 +192,8 @@ void Instruction_move_bool_id(enum Frame destinationScope, size_t id, bool value

void Instruction_add_int(enum Frame destinationScope, char *destination, enum Frame sourceScope, char *source, int value);

void Instruction_add_int_id(enum Frame destinationScope, size_t destination, enum Frame sourceScope, size_t source, int value);

#endif // INSTRUCTION_H

/** End of file include/compiler/codegen/Instruction.h **/
82 changes: 70 additions & 12 deletions src/compiler/codegen/Codegen.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file src/compiler/codegen/Codegen.c
* @author Author Name <xlogin00@stud.fit.vutbr.cz>
* @brief This file is part of the IFJ23 project.
* @author Jaroslav Novotny <xnovot2r@stud.fit.vutbr.cz>
* @brief Implementation of code generation.
* @copyright Copyright (c) 2023
*/

Expand Down Expand Up @@ -48,7 +48,8 @@ void __Codegen_evaluateBlock(Codegen *codegen, BlockASTNode *block);
void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *functionCall);
void __Codegen_evaluateStatement(Codegen *codegen, StatementASTNode *statementAstNode);
void __Codegen_evaluateReturnStatement(Codegen *codegen, ReturnStatementASTNode *returnStatement);
void __Codegen_evaluateBindingCondition(Codegen *codegen, const OptionalBindingConditionASTNode *optionalBindingCondition);
void __Codegen_evaluateBindingCondition(Codegen *codegen, OptionalBindingConditionASTNode *optionalBindingCondition);
//void __Codegen_evaluateForStatement(Codegen *codegen, ForStatementASTNode *forStatement);

// Optimalizations
void __Codegen_generateCoalescing();
Expand Down Expand Up @@ -433,6 +434,21 @@ void __Codegen_evaluateStatement(Codegen *codegen, StatementASTNode *statementAs
ExpressionStatementASTNode *expressionStatement = (ExpressionStatementASTNode*)statementAstNode;
__Codegen_evaluateExpressionStatement(codegen, expressionStatement);
} break;
case NODE_FOR_STATEMENT: {
// ForStatementASTNode *forStatement = (ForStatementASTNode*)statementAstNode;
// __Codegen_evaluateForStatement(codegen, forStatement);
fassertf("[Codegen] For statement not implemented.");
} break;
case NODE_BREAK_STATEMENT: {
fassertf("[Codegen] Break statement outside of loop.");
// BreakStatementASTNode *breakStatement = (BreakStatementASTNode*)statementAstNode;
// __Codegen_evaluateBreakStatement(codegen, breakStatement);
} break;
case NODE_CONTINUE_STATEMENT: {
fassertf("[Codegen] Continue statement outside of loop.");
// ContinueStatementASTNode *continueStatement = (ContinueStatementASTNode*)statementAstNode;
// __Codegen_evaluateContinueStatement(codegen, continueStatement);
} break;
case NODE_FUNCTION_DECLARATION: {
// Declarations are generated at the beginning of the file
} break;
Expand All @@ -441,7 +457,7 @@ void __Codegen_evaluateStatement(Codegen *codegen, StatementASTNode *statementAs
}
}

void __Codegen_evaluateBindingCondition(Codegen *codegen, const OptionalBindingConditionASTNode *optionalBindingCondition) {
void __Codegen_evaluateBindingCondition(Codegen *codegen, OptionalBindingConditionASTNode *optionalBindingCondition) {
Instruction_defvar(optionalBindingCondition->id->id, codegen->frame);
Instruction_move_id(codegen->frame, optionalBindingCondition->id->id, FRAME_GLOBAL, optionalBindingCondition->fromId);
Instruction_pushs_var(optionalBindingCondition->fromId, codegen->frame);
Expand Down Expand Up @@ -873,25 +889,28 @@ void __Codegen_resolveBuiltInFunction(Codegen *codegen, FunctionCallASTNode *fun
void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *functionCall) {
Array *arguments = functionCall->argumentList->arguments;

Instruction_createframe();

FunctionDeclaration *functionDeclaration = Analyser_getFunctionById(codegen->analyser, functionCall->id->id);
assertf(functionDeclaration != NULL, "Could not find function declaration with id %ld", functionCall->id->id);

Array *parameters = functionDeclaration->node->parameterList->parameters;

for(size_t i = 0; i < arguments->size; ++i) {
ArgumentASTNode *argument = Array_get(arguments, i);
ParameterASTNode *parameter = Array_get(parameters, i);
size_t parameterId = parameter->internalId->id;

Instruction_defvar(parameterId, FRAME_TEMPORARY);

__Codegen_evaluateExpression(codegen, argument->expression);

Instruction_pops(parameterId, FRAME_TEMPORARY);
}

Instruction_createframe();

for(int i = arguments->size - 1; i > -1 ; --i) {
ParameterASTNode *parameter = Array_get(parameters, i);
size_t parameterId = parameter->internalId->id;

Instruction_defvar(parameterId, FRAME_TEMPORARY);
Instruction_pops(parameterId, FRAME_TEMPORARY);
}


if(functionDeclaration->returnType.type != TYPE_VOID) {
Instruction_defretvar(functionCall->id->id, FRAME_TEMPORARY);
}
Expand All @@ -903,4 +922,43 @@ void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *funct
}
}

void __Codegen_evaluateForStatement(Codegen *codegen, ForStatementASTNode *forStatement) {
Instruction_label("for_cycle");

__Codegen_evaluateExpression(codegen, forStatement->range->start);
Instruction_defvar(forStatement->iterator->id, codegen->frame);
Instruction_pops(forStatement->iterator->id, codegen->frame);

Instruction_defvar_where("for_end", codegen->frame);
__Codegen_evaluateExpression(codegen, forStatement->range->end);
Instruction_pops_where("for_end", codegen->frame);

Instruction_jump("for_cycle_test");

Instruction_label("for_cycle_iterate");
// Increment iterator
Instruction_add_int_id(codegen->frame, forStatement->iterator->id, codegen->frame, forStatement->iterator->id, 1);

Instruction_label("for_cycle_test");
if(forStatement->range->operator == OPERATOR_LESS) {
Instruction_pushs_var(forStatement->iterator->id, codegen->frame);
Instruction_pushs_var_named("for_end", codegen->frame);
Instruction_lts();
} else {
Instruction_pushs_var(forStatement->iterator->id, codegen->frame);
Instruction_pushs_var_named("for_end", codegen->frame);
Instruction_gts();
Instruction_nots();
}

Instruction_pushs_bool(true);
Instruction_jump_ifeqs("for_cycle_end");

Instruction_label("for_cycle_start");
__Codegen_evaluateBlock(codegen, forStatement->body);
Instruction_jump("for_cycle_iterate");

Instruction_label("for_cycle_end");
}

/** End of file src/compiler/codegen/Codegen.c **/
94 changes: 51 additions & 43 deletions src/compiler/codegen/Instruction.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file src/compiler/codegen/Instruction.c
* @author Author Name <xlogin00@stud.fit.vutbr.cz>
* @brief This file is part of the IFJ23 project.
* @author Jaroslav Novotny <xnovot2r@stud.fit.vutbr.cz>
* @brief Implementation of instruction set.
* @copyright Copyright (c) 2023
*/

Expand Down Expand Up @@ -34,8 +34,12 @@ void __Instruction_escape_string(String *string) {
String_constructor(&buffer, "");

for(size_t i = 0; i < string->length; i++) {
char c = string->value[i];
if(c <= 32 || c == 35 || c == 92) {
unsigned char c = string->value[i];
if(c < 10) {
String *replacement = String_fromFormat("\\00%d", c);
String_append(&buffer, replacement->value);
String_free(replacement);
} else if(c <= 32 || c == 35 || c == 92) {
String *replacement = String_fromFormat("\\0%d", c);
String_append(&buffer, replacement->value);
String_free(replacement);
Expand Down Expand Up @@ -189,7 +193,7 @@ void Instruction_divs() {
}

void Instruction_idivs() {
INSTRUCTION_NULLARY("IDIVS")
INSTRUCTION_NULLARY("IDIVS")
}

void Instruction_lts() {
Expand Down Expand Up @@ -238,117 +242,121 @@ void Instruction_strlen(enum Frame resultScope, char *result, char *input, enum
}

void Instruction_int2char(enum Frame resultScope, char *result, enum Frame inputScope, char *input) {
fprintf(stdout, "INT2CHAR %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input);
fprintf(stdout, "INT2CHAR %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input);
}

void Instruction_stri2int(enum Frame resultScope, char *result, enum Frame inputScope, char *input, int index) {
fprintf(stdout, "STRI2INT %s@$%s %s@$%s int@%d\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input, index);
fprintf(stdout, "STRI2INT %s@$%s %s@$%s int@%d\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input, index);
}

void Instruction_label(char *label) {
fprintf(stdout, "LABEL $%s\n", label);
fprintf(stdout, "LABEL $%s\n", label);
}

void Instruction_jump_ifeqs_chr_end(){
fprintf(stdout, "JUMPIFEQS $chr_empty\n");
void Instruction_jump_ifeqs_chr_end() {
fprintf(stdout, "JUMPIFEQS $chr_empty\n");
}

void Instruction_jump(char *label) {
fprintf(stdout, "JUMP $%s\n", label);
fprintf(stdout, "JUMP $%s\n", label);
}

void Instruction_move_vars(enum Frame destinationScope, char* destination, enum Frame sourceScope, char* source) {
fprintf(stdout, "MOVE %s@$%s %s@$%s\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source);
void Instruction_move_vars(enum Frame destinationScope, char *destination, enum Frame sourceScope, char *source) {
fprintf(stdout, "MOVE %s@$%s %s@$%s\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source);
}

void Instruction_popframe() {
INSTRUCTION_NULLARY("POPFRAME")
INSTRUCTION_NULLARY("POPFRAME")
}

void Instruction_call(char *label) {
fprintf(stdout, "CALL $%s\n", label);
fprintf(stdout, "CALL $%s\n", label);
}

void Instruction_createframe() {
INSTRUCTION_NULLARY("CREATEFRAME")
INSTRUCTION_NULLARY("CREATEFRAME")
}

void Instruction_jump_ifeqs(char *label) {
fprintf(stdout, "JUMPIFEQS $%s\n", label);
fprintf(stdout, "JUMPIFEQS $%s\n", label);
}

void Instruction_getchar(enum Frame resultScope, char *result, enum Frame inputScope, char *input, enum Frame indexScope, char *index){
fprintf(stdout, "GETCHAR %s@$%s %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input, __Instruction_getFrame(indexScope), index);
void Instruction_getchar(enum Frame resultScope, char *result, enum Frame inputScope, char *input, enum Frame indexScope, char *index) {
fprintf(stdout, "GETCHAR %s@$%s %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(inputScope), input, __Instruction_getFrame(indexScope), index);
}

void Instruction_concat(enum Frame resultScope, char *result, enum Frame input1Scope, char *input1, enum Frame input2Scope, char *input2){
fprintf(stdout, "CONCAT %s@$%s %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(input1Scope), input1, __Instruction_getFrame(input2Scope), input2);
void Instruction_concat(enum Frame resultScope, char *result, enum Frame input1Scope, char *input1, enum Frame input2Scope, char *input2) {
fprintf(stdout, "CONCAT %s@$%s %s@$%s %s@$%s\n", __Instruction_getFrame(resultScope), result, __Instruction_getFrame(input1Scope), input1, __Instruction_getFrame(input2Scope), input2);
}

void Instruction_call_func(size_t id){
fprintf(stdout, "CALL $func_%lu\n", id);
void Instruction_call_func(size_t id) {
fprintf(stdout, "CALL $func_%lu\n", id);
}

void Instruction_label_func(size_t id){
fprintf(stdout, "LABEL $func_%lu\n", id);
void Instruction_label_func(size_t id) {
fprintf(stdout, "LABEL $func_%lu\n", id);
}

void Instruction_move_arg(size_t id) {
fprintf(stdout, "MOVE LF@$%lu TF@%%0\n", id);
fprintf(stdout, "MOVE LF@$%lu TF@%%0\n", id);
}

void Instruction_pushs_func_result(size_t id){
fprintf(stdout, "PUSHS TF@$ret_%lu\n", id);
void Instruction_pushs_func_result(size_t id) {
fprintf(stdout, "PUSHS TF@$ret_%lu\n", id);
}

void Instruction_move_id(enum Frame destinationScope, size_t destination, enum Frame sourceScope, size_t source) {
fprintf(stdout, "MOVE %s@$%lu %s@$%lu\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source);
fprintf(stdout, "MOVE %s@$%lu %s@$%lu\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source);
}

void Instruction_move_int(enum Frame destinationScope, char *destination, int value) {
fprintf(stdout, "MOVE %s@$%s int@%d\n", __Instruction_getFrame(destinationScope), destination, value);
fprintf(stdout, "MOVE %s@$%s int@%d\n", __Instruction_getFrame(destinationScope), destination, value);
}

void Instruction_move_string(enum Frame destinationScope, char *destination, String *value) {
__Instruction_escape_string(value);
fprintf(stdout, "MOVE %s@$%s string@%s\n", __Instruction_getFrame(destinationScope), destination, value->value);
__Instruction_escape_string(value);
fprintf(stdout, "MOVE %s@$%s string@%s\n", __Instruction_getFrame(destinationScope), destination, value->value);
}

void Instruction_move_nil(enum Frame destinationScope, char *destination) {
fprintf(stdout, "MOVE %s@$%s nil@nil\n", __Instruction_getFrame(destinationScope), destination);
fprintf(stdout, "MOVE %s@$%s nil@nil\n", __Instruction_getFrame(destinationScope), destination);
}

void Instruction_move_float(enum Frame destinationScope, char *destination, double value) {
fprintf(stdout, "MOVE %s@$%s float@%a\n", __Instruction_getFrame(destinationScope), destination, value);
fprintf(stdout, "MOVE %s@$%s float@%a\n", __Instruction_getFrame(destinationScope), destination, value);
}

void Instruction_move_bool(enum Frame destinationScope, char *destination, bool value) {
fprintf(stdout, "MOVE %s@$%s bool@%s\n", __Instruction_getFrame(destinationScope), destination, value ? "true" : "false");
fprintf(stdout, "MOVE %s@$%s bool@%s\n", __Instruction_getFrame(destinationScope), destination, value ? "true" : "false");
}

void Instruction_move_int_id(enum Frame destinationScope, size_t destination, long int value) {
fprintf(stdout, "MOVE %s@$%lu int@%ld\n", __Instruction_getFrame(destinationScope), destination, value);
fprintf(stdout, "MOVE %s@$%lu int@%ld\n", __Instruction_getFrame(destinationScope), destination, value);
}

void Instruction_move_string_id(enum Frame destinationScope, size_t destination, String *value) {
__Instruction_escape_string(value);
fprintf(stdout, "MOVE %s@$%lu string@%s\n", __Instruction_getFrame(destinationScope), destination, value->value);
__Instruction_escape_string(value);
fprintf(stdout, "MOVE %s@$%lu string@%s\n", __Instruction_getFrame(destinationScope), destination, value->value);
}

void Instruction_move_nil_id(enum Frame destinationScope, size_t destination) {
fprintf(stdout, "MOVE %s@$%lu nil@nil\n", __Instruction_getFrame(destinationScope), destination);
fprintf(stdout, "MOVE %s@$%lu nil@nil\n", __Instruction_getFrame(destinationScope), destination);
}

void Instruction_move_float_id(enum Frame destinationScope, size_t destination, double value) {
fprintf(stdout, "MOVE %s@$%lu float@%a\n", __Instruction_getFrame(destinationScope), destination, value);
fprintf(stdout, "MOVE %s@$%lu float@%a\n", __Instruction_getFrame(destinationScope), destination, value);
}

void Instruction_move_bool_id(enum Frame destinationScope, size_t destination, bool value) {
fprintf(stdout, "MOVE %s@$%lu bool@%s\n", __Instruction_getFrame(destinationScope), destination, value ? "true" : "false");
fprintf(stdout, "MOVE %s@$%lu bool@%s\n", __Instruction_getFrame(destinationScope), destination, value ? "true" : "false");
}

void Instruction_add_int(enum Frame destinationScope, char *destination, enum Frame sourceScope, char *source, int value) {
fprintf(stdout, "ADD %s@$%s %s@$%s int@%d\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source, value);
}

void Instruction_add_int(enum Frame destinationScope, char *destination, enum Frame sourceScope, char *source, int value){
fprintf(stdout, "ADD %s@$%s %s@$%s int@%d\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source, value);
void Instruction_add_int_id(enum Frame destinationScope, size_t destination, enum Frame sourceScope, size_t source, int value) {
fprintf(stdout, "ADD %s@$%lu %s@$%lu int@%d\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source, value);
}

/** End of file src/compiler/codegen/Instruction.c **/

0 comments on commit 938ffe3

Please sign in to comment.