54 lines
1.9 KiB
C
54 lines
1.9 KiB
C
#include "codegen.h"
|
|
|
|
#include <groundvm.h>
|
|
#include "../parser/SolsNode.h"
|
|
#include "../include/estr.h"
|
|
|
|
// FIXME add proper erroring function
|
|
char* createCodegenError(char* what) {
|
|
Estr estr = CREATE_ESTR(what);
|
|
APPEND_ESTR(estr, "\nthats an error");
|
|
return estr.str;
|
|
}
|
|
|
|
static inline ResultType(GroundProgram, charptr) generateLiteralNode(SolsNode* node) {
|
|
// We don't even need to do anything lmao
|
|
return Success(GroundProgram, charptr, groundCreateProgram());
|
|
}
|
|
|
|
static inline ResultType(GroundProgram, charptr) generatePutsNode(SolsNode* node) {
|
|
if (node->children.count < 1) {
|
|
return Error(GroundProgram, charptr, "puts requires arguments");
|
|
}
|
|
GroundInstruction inst = groundCreateInstruction(PRINTLN);
|
|
for (size_t i = 0; i < node->children.count; i++) {
|
|
groundAddReferenceToInstruction(&inst, node->children.at[i].accessArg);
|
|
}
|
|
GroundProgram program = groundCreateProgram();
|
|
groundAddInstructionToProgram(&program, inst);
|
|
return Success(GroundProgram, charptr, program);
|
|
}
|
|
|
|
ResultType(GroundProgram, charptr) generateCode(SolsNode* node) {
|
|
|
|
GroundProgram program = groundCreateProgram();
|
|
|
|
// Generate code for all children before generating this node's code
|
|
for (size_t i = 0; i < node->children.count; i++) {
|
|
ResultType(GroundProgram, charptr) generated = generateCode(&node->children.at[i]);
|
|
if (generated.error) {
|
|
return Error(GroundProgram, charptr, createCodegenError(generated.as.error));
|
|
}
|
|
for (size_t j = 0; j < generated.as.success.size; j++) {
|
|
groundAddInstructionToProgram(&program, generated.as.success.instructions[j]);
|
|
}
|
|
}
|
|
|
|
// Now generate code for this node
|
|
switch (node->type) {
|
|
case SNT_PUTS: generate(Puts);
|
|
case SNT_LITERAL: generate(Literal);
|
|
}
|
|
return Success(GroundProgram, charptr, program);
|
|
}
|