diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index c73f5a4..8ee38e3 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -986,13 +986,59 @@ ResultType(GroundProgram, charptr) generateInlineGroundNode(SolsNode* node, Sols return Success(GroundProgram, charptr, groundParseFile(node->as.inlineGround)); } +ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope* scope) { + SolsType type = ({ + ResultType(SolsType, charptr) type = createSolsType(STT_TEMPLATE); + if (type.error) { + return Error(GroundProgram, charptr, type.as.error); + } + type.as.success; + }); + GroundProgram constants = groundCreateProgram(); + GroundProgram structDef = groundCreateProgram(); + GroundInstruction structDefInst = groundCreateInstruction(STRUCT); + groundAddReferenceToInstruction(&structDefInst, groundCreateReference(TYPEREF, node->as.idName)); + groundAddInstructionToProgram(&structDef, structDefInst); + for (size_t i = 0; i < node->children.count; i++) { + // Add to type for type system + SolsNode* child = &node->children.at[i]; + ResultType(SolsType, charptr) childType = getNodeType(&child->children.at[1], scope); + if (childType.error) { + return Error(GroundProgram, charptr, childType.as.error); + } + addChildToSolsType(&type, childType.as.success, child->children.at[0].as.idName); + + // Generate constant initial value + ResultType(GroundProgram, charptr) childCode = generateCode(&child->children.at[1], scope); + if (childCode.error) { + return Error(GroundProgram, charptr, childCode.as.error); + } + for (size_t j = 0; j < childCode.as.success.size; j++) { + groundAddInstructionToProgram(&constants, childCode.as.success.instructions[j]); + } + + // Add to struct + GroundInstruction structInst = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&structInst, groundCreateReference(DIRREF, child->children.at[0].as.idName)); + groundAddReferenceToInstruction(&structInst, child->children.at[1].accessArg); + groundAddInstructionToProgram(&structDef, structInst); + } + groundAddInstructionToProgram(&structDef, groundCreateInstruction(ENDSTRUCT)); + + // Combine into one program + for (size_t i = 0; i < structDef.size; i++) { + groundAddInstructionToProgram(&constants, structDef.instructions[i]); + } + return Success(GroundProgram, charptr, constants); +} + ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) { GroundProgram program = groundCreateProgram(); SolsScope backupScope = {NULL, 0}; - if (node->type != SNT_IF && node->type != SNT_WHILE && node->type != SNT_LAMBDA && node->type != SNT_DEF) { + if (node->type != SNT_IF && node->type != SNT_WHILE && node->type != SNT_LAMBDA && node->type != SNT_DEF && node->type != SNT_STRUCT) { if (node->type == SNT_CODE_BLOCK) { backupScope = *scope; SolsScope newScope = copySolsScope(scope); @@ -1039,6 +1085,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope case SNT_RETURN: generate(Return); case SNT_USE: generate(Use); case SNT_GROUND: generate(InlineGround); + case SNT_STRUCT: generate(Struct); } return Success(GroundProgram, charptr, program); }