forked from solstice/solstice
Destructors
This commit is contained in:
@@ -1199,6 +1199,32 @@ ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope*
|
|||||||
} else if (child->type == SNT_CONSTRUCTOR) {
|
} else if (child->type == SNT_CONSTRUCTOR) {
|
||||||
constructor = child;
|
constructor = child;
|
||||||
continue;
|
continue;
|
||||||
|
} else if (child->type == SNT_DESTRUCTOR) {
|
||||||
|
GroundInstruction destructorInst = groundCreateInstruction(FUN);
|
||||||
|
groundAddReferenceToInstruction(&destructorInst, groundCreateReference(FNREF, "destructor"));
|
||||||
|
groundAddReferenceToInstruction(&destructorInst, groundCreateReference(TYPEREF, "any"));
|
||||||
|
groundAddInstructionToProgram(&structDef, destructorInst);
|
||||||
|
|
||||||
|
SolsScope childScope = copySolsScope(scope);
|
||||||
|
|
||||||
|
SolsType selfType = ({
|
||||||
|
ResultType(SolsType, charptr) _result = copySolsType(&type);
|
||||||
|
if (_result.error) {
|
||||||
|
return Error(GroundProgram, charptr, _result.as.error);
|
||||||
|
}
|
||||||
|
_result.as.success;
|
||||||
|
});
|
||||||
|
selfType.type = STT_OBJECT;
|
||||||
|
|
||||||
|
addVariableToScope(&childScope, "self", selfType);
|
||||||
|
|
||||||
|
ResultType(GroundProgram, charptr) bodyCode = generateCode(child, &childScope);
|
||||||
|
if (bodyCode.error) return bodyCode;
|
||||||
|
for (size_t j = 0; j < bodyCode.as.success.size; j++) {
|
||||||
|
groundAddInstructionToProgram(&structDef, bodyCode.as.success.instructions[j]);
|
||||||
|
}
|
||||||
|
groundAddInstructionToProgram(&structDef, groundCreateInstruction(ENDFUN));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ResultType(SolsType, charptr) childType = getNodeType(&child->children.at[1], scope);
|
ResultType(SolsType, charptr) childType = getNodeType(&child->children.at[1], scope);
|
||||||
if (childType.error) {
|
if (childType.error) {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
|||||||
{"subtracts", STT_OP_SUBTO},
|
{"subtracts", STT_OP_SUBTO},
|
||||||
{"multiplies", STT_OP_MULTO},
|
{"multiplies", STT_OP_MULTO},
|
||||||
{"divides", STT_OP_DIVTO},
|
{"divides", STT_OP_DIVTO},
|
||||||
|
{"class", STT_KW_STRUCT}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1775,6 +1775,46 @@ static inline ResultType(Nothing, charptr) parseConstructor(SolsParser* parser)
|
|||||||
return Success(Nothing, charptr, {});
|
return Success(Nothing, charptr, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ResultType(Nothing, charptr) parseDestructor(SolsParser* parser) {
|
||||||
|
ResultType(SolsNode, charptr) node = createSolsNode(SNT_DESTRUCTOR);
|
||||||
|
ResultType(SolsType, charptr) type = createSolsType(STT_FUN);
|
||||||
|
if (type.error) {
|
||||||
|
return Error(Nothing, charptr, type.as.error);
|
||||||
|
}
|
||||||
|
type.as.success.returnType = malloc(sizeof(SolsType));
|
||||||
|
if (type.as.success.returnType == NULL) {
|
||||||
|
return Error(Nothing, charptr, "Failed to allocate memory for return type");
|
||||||
|
}
|
||||||
|
type.as.success.returnType->type = STT_NONE;
|
||||||
|
|
||||||
|
// Skip newlines before the opening curly brace
|
||||||
|
while (parserPeek(parser, 1).as.success.type == STT_LINE_END) {
|
||||||
|
parserConsume(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(SolsToken, Nothing) openCurly = parserConsume(parser);
|
||||||
|
if (openCurly.error || openCurly.as.success.type != STT_OPEN_CURLY) {
|
||||||
|
return Error(Nothing, charptr, "Expecting opening curly brace ({) for destructor body");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add node to parent
|
||||||
|
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||||
|
|
||||||
|
// Parse code block
|
||||||
|
ResultType(Nothing, charptr) res = parseCodeBlock(parser);
|
||||||
|
if (res.error) return res;
|
||||||
|
|
||||||
|
// Last child of parent is code block, we need to move it
|
||||||
|
SolsNode codeBlock = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||||
|
parser->currentParent->children.count--;
|
||||||
|
|
||||||
|
// We need to get the actual node from the parent to modify it
|
||||||
|
SolsNode* constructorNode = &parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||||
|
addChildToSolsNode(constructorNode, codeBlock);
|
||||||
|
return Success(Nothing, charptr, {});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
||||||
// Get struct name
|
// Get struct name
|
||||||
SolsNode structNode = ({
|
SolsNode structNode = ({
|
||||||
@@ -1854,6 +1894,16 @@ static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
|||||||
parser->currentParent->children.count--;
|
parser->currentParent->children.count--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (keyTok.type == STT_KW_DESTRUCTOR) {
|
||||||
|
// destructor {}
|
||||||
|
ResultType(Nothing, charptr) destructorNode = parseDestructor(parser);
|
||||||
|
if (destructorNode.error) {
|
||||||
|
return Error(Nothing, charptr, destructorNode.as.error);
|
||||||
|
}
|
||||||
|
addChildToSolsNode(&structNode, parser->currentParent->children.at[parser->currentParent->children.count - 1]);
|
||||||
|
parser->currentParent->children.count--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (keyTok.type != STT_IDENTIFIER) {
|
if (keyTok.type != STT_IDENTIFIER) {
|
||||||
return Error(Nothing, charptr, "Expecting struct key");
|
return Error(Nothing, charptr, "Expecting struct key");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user