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 5, 2023
2 parents 378149f + bf67aec commit 2240ed2
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 74 deletions.
19 changes: 18 additions & 1 deletion include/compiler/codegen/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
fprintf(stdout, "# Variable %s (%lu)\n", declaration->name->value, declaration->id);

#define COMMENT_WHILE(id) \
fprintf(stdout, "# While statement %lu\n", id);
fprintf(stdout, "# While loop %lu\n", id);

#define COMMENT_FOR(id) \
fprintf(stdout, "# For loop %lu\n", id);

#define COMMENT_IF(id) \
fprintf(stdout, "# If statement %lu\n", id);
Expand Down Expand Up @@ -194,6 +197,20 @@ void Instruction_add_int(enum Frame destinationScope, char *destination, enum Fr

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

void Instruction_label_id(char *label, size_t id);

void Instruction_jump_id(char *label, size_t id);

void Instruction_defvar_id(char *name ,size_t id, enum Frame frame);

void Instruction_pushs_id(char *name, size_t id, enum Frame frame);

void Instruction_pops_id(char *name, size_t id, enum Frame frame);

void Instruction_jump_ifeqs_id(char *label, size_t id);

void Instruction_jump_ifneqs_id(char *label, size_t id);

#endif // INSTRUCTION_H

/** End of file include/compiler/codegen/Instruction.h **/
140 changes: 67 additions & 73 deletions src/compiler/codegen/Codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *funct
void __Codegen_evaluateStatement(Codegen *codegen, StatementASTNode *statementAstNode);
void __Codegen_evaluateReturnStatement(Codegen *codegen, ReturnStatementASTNode *returnStatement);
void __Codegen_evaluateBindingCondition(Codegen *codegen, OptionalBindingConditionASTNode *optionalBindingCondition);
// void __Codegen_evaluateForStatement(Codegen *codegen, ForStatementASTNode *forStatement);
void __Codegen_evaluateForStatement(Codegen *codegen, ForStatementASTNode *forStatement);
void __Codegen_evaluateBreakStatement(BreakStatementASTNode *breakStatement);
void __Codegen_evaluateContinueStatement(ContinueStatementASTNode *continueStatement);

// Optimalizations
void __Codegen_generateCoalescing();
Expand Down Expand Up @@ -355,7 +357,7 @@ void __Codegen_generateUserFunctions(Codegen *codegen) {
}

void __Codegen_generateFunctionDeclaration(Codegen *codegen, FunctionDeclaration *functionDeclaration) {
if(!is_func_generable(functionDeclaration->node->builtin)) {
if(functionDeclaration->node->builtin != FUNCTION_NONE) {
return;
}

Expand Down Expand Up @@ -435,19 +437,16 @@ void __Codegen_evaluateStatement(Codegen *codegen, StatementASTNode *statementAs
__Codegen_evaluateExpressionStatement(codegen, expressionStatement);
} break;
case NODE_FOR_STATEMENT: {
// ForStatementASTNode *forStatement = (ForStatementASTNode*)statementAstNode;
// __Codegen_evaluateForStatement(codegen, forStatement);
fassertf("[Codegen] For statement not implemented.");
ForStatementASTNode *forStatement = (ForStatementASTNode*)statementAstNode;
__Codegen_evaluateForStatement(codegen, forStatement);
} break;
case NODE_BREAK_STATEMENT: {
fassertf("[Codegen] Break statement outside of loop.");
// BreakStatementASTNode *breakStatement = (BreakStatementASTNode*)statementAstNode;
// __Codegen_evaluateBreakStatement(codegen, breakStatement);
BreakStatementASTNode *breakStatement = (BreakStatementASTNode*)statementAstNode;
__Codegen_evaluateBreakStatement(breakStatement);
} break;
case NODE_CONTINUE_STATEMENT: {
fassertf("[Codegen] Continue statement outside of loop.");
// ContinueStatementASTNode *continueStatement = (ContinueStatementASTNode*)statementAstNode;
// __Codegen_evaluateContinueStatement(codegen, continueStatement);
ContinueStatementASTNode *continueStatement = (ContinueStatementASTNode*)statementAstNode;
__Codegen_evaluateContinueStatement(continueStatement);
} break;
case NODE_FUNCTION_DECLARATION: {
// Declarations are generated at the beginning of the file
Expand Down Expand Up @@ -505,8 +504,9 @@ void __Codegen_evaluateIfStatement(Codegen *codegen, IfStatementASTNode *ifState

void __Codegen_evaluateWhileStatement(Codegen *codegen, WhileStatementASTNode *whileStatement) {
COMMENT_WHILE(whileStatement->id)

// Start label
Instruction_label_while_start(whileStatement->id);
Instruction_label_id("loop_start", whileStatement->id);

// Process test
if(whileStatement->test->_type == NODE_OPTIONAL_BINDING_CONDITION) {
Expand All @@ -515,19 +515,18 @@ void __Codegen_evaluateWhileStatement(Codegen *codegen, WhileStatementASTNode *w
} else {
__Codegen_evaluateExpression(codegen, whileStatement->test);
}
Instruction_pushs_bool(true);

// Make actual test
Instruction_jumpifneqs_while_end(whileStatement->id);
Instruction_pushs_bool(true);
Instruction_jump_ifneqs_id("loop_end", whileStatement->id);

// Process body
__Codegen_evaluateBlock(codegen, whileStatement->body);

// At end, go to begging for test
Instruction_jump_while_start(whileStatement->id);
Instruction_jump_id("loop_start", whileStatement->id);

// End of loop, clear stack
Instruction_label_while_end(whileStatement->id);
Instruction_label_id("loop_end", whileStatement->id);
}

void __Codegen_evaluateBinaryExpression(Codegen *codegen, BinaryExpressionASTNode *binaryExpression) {
Expand All @@ -536,10 +535,7 @@ void __Codegen_evaluateBinaryExpression(Codegen *codegen, BinaryExpressionASTNod
__Codegen_evaluateBinaryOperator(binaryExpression);
}

// TODO: Careful, there are some exceptions when working with nils
void __Codegen_evaluateBinaryOperator(BinaryExpressionASTNode *expression) {
assertf(expression != NULL);

switch(expression->operator) {
case OPERATOR_PLUS: {
if(expression->type.type == TYPE_STRING) {
Expand Down Expand Up @@ -602,9 +598,8 @@ void __Codegen_evaluateBinaryOperator(BinaryExpressionASTNode *expression) {
case OPERATOR_UNWRAP:
case OPERATOR_DEFAULT:
case OPERATOR_RANGE:
case OPERATOR_HALF_OPEN_RANGE: {
fassertf("[Codegen] Unknown operator.");
}
case OPERATOR_HALF_OPEN_RANGE:
fassertf("[Codegen] Unexpected operator type (evaluateBinaryOperator).");
}
}

Expand Down Expand Up @@ -648,7 +643,6 @@ void __Codegen_evaluateVariableDeclarator(Codegen *codegen, VariableDeclaratorAS
if(Analyser_isDeclarationGlobal(codegen->analyser, variableDeclarator->pattern->id->id)) {
Instruction_pops(variableDeclarator->pattern->id->id, FRAME_GLOBAL);
} else {
// Instruction_defvar(variableDeclarator->pattern->id->id, codegen->frame);
Instruction_pops(variableDeclarator->pattern->id->id, codegen->frame);
}
NEWLINE
Expand Down Expand Up @@ -709,9 +703,6 @@ void __Codegen_evaluateExpressionStatement(Codegen *codegen, ExpressionStatement
}

void __Codegen_evaluateExpression(Codegen *codegen, ExpressionASTNode *expression) {
assertf(codegen != NULL);
assertf(expression != NULL);

switch(expression->_type) {
case NODE_LITERAL_EXPRESSION: {
LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)expression;
Expand All @@ -728,7 +719,7 @@ void __Codegen_evaluateExpression(Codegen *codegen, ExpressionASTNode *expressio
case NODE_FUNCTION_CALL: {
FunctionCallASTNode *functionCall = (FunctionCallASTNode*)expression;
enum BuiltInFunction builtin = Analyser_getBuiltInFunctionById(codegen->analyser, functionCall->id->id);
if(is_func_builtin(builtin)) {
if(builtin != FUNCTION_NONE) {
__Codegen_resolveBuiltInFunction(codegen, functionCall, builtin);
} else {
__Codegen_evaluateFunctionCall(codegen, functionCall);
Expand All @@ -737,17 +728,18 @@ void __Codegen_evaluateExpression(Codegen *codegen, ExpressionASTNode *expressio
case NODE_UNARY_EXPRESSION: {
UnaryExpressionASTNode *unaryExpression = (UnaryExpressionASTNode*)expression;
__Codegen_evaluateExpression(codegen, unaryExpression->argument);

if(unaryExpression->operator == OPERATOR_NOT) {
Instruction_nots();
}
} break;
case NODE_BINARY_EXPRESSION: {
BinaryExpressionASTNode *binaryExpression = (BinaryExpressionASTNode*)expression;
__Codegen_evaluateBinaryExpression(codegen, binaryExpression);
} break;
case NODE_INTERPOLATION_EXPRESSION: {
InterpolationExpressionASTNode *interpolation = (InterpolationExpressionASTNode*)expression;
assertf(interpolation);
assertf(interpolation->concatenated);
__Codegen_evaluateBinaryExpression(codegen, interpolation->concatenated);
} break;
break;
}
default:
fassertf("Unexpected ASTNode type. Analyser probably failed.");
}
Expand Down Expand Up @@ -871,27 +863,16 @@ void __Codegen_resolveBuiltInFunction(Codegen *codegen, FunctionCallASTNode *fun
// Handle return value
Instruction_pushs_var_named("RETVAL_CHR", FRAME_TEMPORARY);
} break;
case FUNCTION_INTERNAL_STRINGIFY_NUMBER:
case FUNCTION_INTERNAL_STRINGIFY_DOUBLE:
case FUNCTION_INTERNAL_STRINGIFY_INT:
case FUNCTION_INTERNAL_STRINGIFY_BOOL:
case FUNCTION_INTERNAL_STRINGIFY_STRING:
case FUNCTION_INTERNAL_MODULO: {
// Internal functions are handled as user defined functions
__Codegen_evaluateFunctionCall(codegen, functionCall);
} break;
case FUNCTIONS_COUNT:
case FUNCTION_NONE:
fassertf("Expected builtin function, got user defined.");
default: {
fassertf("Unknown builtin function.");
}
}
}

void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *functionCall) {
Array *arguments = functionCall->argumentList->arguments;

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) {
Expand All @@ -910,7 +891,6 @@ void __Codegen_evaluateFunctionCall(Codegen *codegen, FunctionCallASTNode *funct
Instruction_pops(parameterId, FRAME_TEMPORARY);
}


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

void __Codegen_evaluateForStatement(Codegen *codegen, ForStatementASTNode *forStatement) {
Instruction_label("for_cycle");
size_t loopId = forStatement->id;
size_t iteratorId = forStatement->iterator->id;
RangeASTNode *range = forStatement->range;
enum Frame currentFrame = codegen->frame;

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

Instruction_defvar_where("for_end", codegen->frame);
__Codegen_evaluateExpression(codegen, forStatement->range->end);
Instruction_pops_where("for_end", codegen->frame);
// Initialize iterator
__Codegen_evaluateExpression(codegen, range->start);
Instruction_pops(iteratorId, currentFrame);

Instruction_jump("for_cycle_test");
// Initialize end
__Codegen_evaluateExpression(codegen, range->end);
Instruction_pops(range->endId, currentFrame);

Instruction_label("for_cycle_iterate");
// Increment iterator
Instruction_add_int_id(codegen->frame, forStatement->iterator->id, codegen->frame, forStatement->iterator->id, 1);
Instruction_add_int_id(currentFrame, iteratorId, currentFrame, iteratorId, -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_label_id("loop_start", loopId);
Instruction_add_int_id(currentFrame, iteratorId, currentFrame, iteratorId, 1);
Instruction_pushs_var(range->endId, currentFrame);
Instruction_pushs_var(iteratorId, currentFrame);

switch(range->operator) {
case OPERATOR_RANGE:
Instruction_lts();
break;
case OPERATOR_HALF_OPEN_RANGE:
Instruction_gts();
Instruction_nots();
break;
default:
fassertf("Unknown range operator.");
}

Instruction_pushs_bool(true);
Instruction_jump_ifeqs("for_cycle_end");
Instruction_jump_ifeqs_id("loop_end", loopId);

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

Instruction_label_id("loop_end", loopId);
}

void __Codegen_evaluateBreakStatement(BreakStatementASTNode *breakStatement) {
Instruction_jump_id("loop_end", breakStatement->id);
}

Instruction_label("for_cycle_end");
void __Codegen_evaluateContinueStatement(ContinueStatementASTNode *continueStatement) {
Instruction_jump_id("loop_start", continueStatement->id);
}

/** End of file src/compiler/codegen/Codegen.c **/
28 changes: 28 additions & 0 deletions src/compiler/codegen/Instruction.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,4 +359,32 @@ void Instruction_add_int_id(enum Frame destinationScope, size_t destination, enu
fprintf(stdout, "ADD %s@$%lu %s@$%lu int@%d\n", __Instruction_getFrame(destinationScope), destination, __Instruction_getFrame(sourceScope), source, value);
}

void Instruction_label_id(char *label, size_t id) {
fprintf(stdout, "LABEL $%s_%lu\n", label, id);
}

void Instruction_jump_id(char *label, size_t id) {
fprintf(stdout, "JUMP $%s_%lu\n", label, id);
}

void Instruction_defvar_id(char *name ,size_t id, enum Frame frame){
fprintf(stdout, "DEFVAR %s@$%s_%lu\n", __Instruction_getFrame(frame), name, id);
}

void Instruction_pushs_id(char *name, size_t id, enum Frame frame){
fprintf(stdout, "PUSHS %s@$%s_%lu\n", __Instruction_getFrame(frame), name, id);
}

void Instruction_pops_id(char *name, size_t id, enum Frame frame){
fprintf(stdout, "POPS %s@$%s_%lu\n", __Instruction_getFrame(frame), name, id);
}

void Instruction_jump_ifeqs_id(char *label, size_t id) {
fprintf(stdout, "JUMPIFEQS $%s_%lu\n", label, id);
}

void Instruction_jump_ifneqs_id(char *label, size_t id) {
fprintf(stdout, "JUMPIFNEQS $%s_%lu\n", label, id);
}

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

0 comments on commit 2240ed2

Please sign in to comment.