#include "codegen.h" #include #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); }