forked from solstice/solstice
Constructors
This commit is contained in:
@@ -255,6 +255,18 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
|||||||
return Error(SolsType, charptr, estr.str);
|
return Error(SolsType, charptr, estr.str);
|
||||||
}
|
}
|
||||||
if (type.as.success.type != STT_FUN) {
|
if (type.as.success.type != STT_FUN) {
|
||||||
|
if (type.as.success.type == STT_TEMPLATE) {
|
||||||
|
SolsType* constructor = NULL;
|
||||||
|
for (size_t i = 0; i < type.as.success.children.count; i++) {
|
||||||
|
if (strcmp(type.as.success.children.at[i].name, "constructor") == 0) {
|
||||||
|
constructor = &type.as.success.children.at[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (constructor != NULL) {
|
||||||
|
return Success(SolsType, charptr, *constructor->returnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
Estr estr = CREATE_ESTR(node->as.idName);
|
Estr estr = CREATE_ESTR(node->as.idName);
|
||||||
APPEND_ESTR(estr, " is not a callable function");
|
APPEND_ESTR(estr, " is not a callable function");
|
||||||
return Error(SolsType, charptr, estr.str);
|
return Error(SolsType, charptr, estr.str);
|
||||||
@@ -272,7 +284,9 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
|||||||
SolsVariable* var = findSolsVariable(scope, node->as.type.identifierType);
|
SolsVariable* var = findSolsVariable(scope, node->as.type.identifierType);
|
||||||
if (var == NULL) {
|
if (var == NULL) {
|
||||||
Estr estr = CREATE_ESTR("Unable to find variable ");
|
Estr estr = CREATE_ESTR("Unable to find variable ");
|
||||||
|
if (node->as.type.identifierType != NULL) {
|
||||||
APPEND_ESTR(estr, node->as.type.identifierType);
|
APPEND_ESTR(estr, node->as.type.identifierType);
|
||||||
|
}
|
||||||
return Error(SolsType, charptr, estr.str);
|
return Error(SolsType, charptr, estr.str);
|
||||||
}
|
}
|
||||||
type = var->typeinfo;
|
type = var->typeinfo;
|
||||||
@@ -293,6 +307,7 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
|||||||
}
|
}
|
||||||
return findStructMemberType(&type.as.success, node->children.at[1].as.idName);
|
return findStructMemberType(&type.as.success, node->children.at[1].as.idName);
|
||||||
}
|
}
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
return Error(SolsType, charptr, "Not yet implemented");
|
return Error(SolsType, charptr, "Not yet implemented");
|
||||||
}
|
}
|
||||||
@@ -946,6 +961,31 @@ ResultType(GroundProgram, charptr) generateFunctionCallNode(SolsNode* node, Sols
|
|||||||
return Error(GroundProgram, charptr, type.as.error);
|
return Error(GroundProgram, charptr, type.as.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* oldId = NULL;
|
||||||
|
|
||||||
|
if (type.as.success.type == STT_TEMPLATE) {
|
||||||
|
SolsType* constructor = NULL;
|
||||||
|
for (size_t i = 0; i < type.as.success.children.count; i++) {
|
||||||
|
if (strcmp(type.as.success.children.at[i].name, "constructor") == 0) {
|
||||||
|
constructor = &type.as.success.children.at[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (constructor == NULL) {
|
||||||
|
return Error(GroundProgram, charptr, "Template type does not have a constructor");
|
||||||
|
}
|
||||||
|
type.as.success = *constructor;
|
||||||
|
|
||||||
|
node->children.at[0].type = SNT_IDENTIFIER;
|
||||||
|
oldId = node->children.at[0].as.idName;
|
||||||
|
Estr idName = CREATE_ESTR(node->children.at[0].as.idName);
|
||||||
|
APPEND_ESTR(idName, "_SOLS_CONSTRUCTOR");
|
||||||
|
node->children.at[0].as.idName = idName.str;
|
||||||
|
node->children.at[0].accessArg = groundCreateReference(FNREF, idName.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t argCount = node->children.count - 1;
|
||||||
|
|
||||||
// Ensure the argument types match the function types
|
// Ensure the argument types match the function types
|
||||||
if (node->children.count - 1 != type.as.success.children.count) {
|
if (node->children.count - 1 != type.as.success.children.count) {
|
||||||
return Error(GroundProgram, charptr, "Incorrect amount of arguments for function");
|
return Error(GroundProgram, charptr, "Incorrect amount of arguments for function");
|
||||||
@@ -993,6 +1033,10 @@ ResultType(GroundProgram, charptr) generateFunctionCallNode(SolsNode* node, Sols
|
|||||||
|
|
||||||
node->accessArg = groundCreateReference(VALREF, returnStr);
|
node->accessArg = groundCreateReference(VALREF, returnStr);
|
||||||
|
|
||||||
|
if (oldId != NULL) {
|
||||||
|
node->children.at[0].as.idName = oldId;
|
||||||
|
}
|
||||||
|
|
||||||
return Success(GroundProgram, charptr, program);
|
return Success(GroundProgram, charptr, program);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1111,6 +1155,7 @@ ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope*
|
|||||||
}
|
}
|
||||||
type.as.success;
|
type.as.success;
|
||||||
});
|
});
|
||||||
|
SolsNode* constructor = NULL;
|
||||||
GroundProgram constants = groundCreateProgram();
|
GroundProgram constants = groundCreateProgram();
|
||||||
GroundProgram structDef = groundCreateProgram();
|
GroundProgram structDef = groundCreateProgram();
|
||||||
GroundInstruction structDefInst = groundCreateInstruction(STRUCT);
|
GroundInstruction structDefInst = groundCreateInstruction(STRUCT);
|
||||||
@@ -1150,6 +1195,9 @@ ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope*
|
|||||||
groundAddInstructionToProgram(&structDef, defNode.as.success.instructions[j]);
|
groundAddInstructionToProgram(&structDef, defNode.as.success.instructions[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} else if (child->type == SNT_CONSTRUCTOR) {
|
||||||
|
constructor = child;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ResultType(SolsType, charptr) childType = getNodeType(&child->children.at[1], scope);
|
ResultType(SolsType, charptr) childType = getNodeType(&child->children.at[1], scope);
|
||||||
@@ -1175,6 +1223,53 @@ ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope*
|
|||||||
}
|
}
|
||||||
groundAddInstructionToProgram(&structDef, groundCreateInstruction(ENDSTRUCT));
|
groundAddInstructionToProgram(&structDef, groundCreateInstruction(ENDSTRUCT));
|
||||||
|
|
||||||
|
// Construct constructor
|
||||||
|
if (constructor != NULL) {
|
||||||
|
GroundInstruction constructorInst = groundCreateInstruction(FUN);
|
||||||
|
Estr constructorName = CREATE_ESTR(node->as.idName);
|
||||||
|
APPEND_ESTR(constructorName, "_SOLS_CONSTRUCTOR");
|
||||||
|
groundAddReferenceToInstruction(&constructorInst, groundCreateReference(FNREF, constructorName.str));
|
||||||
|
groundAddReferenceToInstruction(&constructorInst, groundCreateReference(TYPEREF, node->as.idName));
|
||||||
|
for (size_t i = 0; i < constructor->as.type.children.count; i++) {
|
||||||
|
ResultType(GroundArg, charptr) arg = createGroundArgFromSolsType(&constructor->as.type.children.at[i].type, scope);
|
||||||
|
if (arg.error) {
|
||||||
|
return Error(GroundProgram, charptr, arg.as.error);
|
||||||
|
}
|
||||||
|
groundAddReferenceToInstruction(&constructorInst, arg.as.success);
|
||||||
|
groundAddReferenceToInstruction(&constructorInst, groundCreateReference(DIRREF, constructor->as.type.children.at[i].name));
|
||||||
|
}
|
||||||
|
groundAddInstructionToProgram(&structDef, constructorInst);
|
||||||
|
|
||||||
|
GroundInstruction constructorSelf = groundCreateInstruction(INIT);
|
||||||
|
groundAddReferenceToInstruction(&constructorSelf, groundCreateReference(DIRREF, "self"));
|
||||||
|
groundAddReferenceToInstruction(&constructorSelf, groundCreateReference(TYPEREF, node->as.idName));
|
||||||
|
groundAddInstructionToProgram(&structDef, constructorSelf);
|
||||||
|
|
||||||
|
SolsScope childScope = copySolsScope(scope);
|
||||||
|
addVariableToScope(&childScope, "self", type);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < constructor->as.type.children.count; i++) {
|
||||||
|
addVariableToScope(&childScope, constructor->as.type.children.at[i].name, constructor->as.type.children.at[i].type);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(GroundProgram, charptr) constructorCode = generateCode(&constructor->children.at[0], &childScope);
|
||||||
|
if (constructorCode.error) {
|
||||||
|
return Error(GroundProgram, charptr, constructorCode.as.error);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < constructorCode.as.success.size; i++) {
|
||||||
|
groundAddInstructionToProgram(&structDef, constructorCode.as.success.instructions[i]);
|
||||||
|
}
|
||||||
|
GroundInstruction ret = groundCreateInstruction(RETURN);
|
||||||
|
groundAddReferenceToInstruction(&ret, groundCreateReference(VALREF, "self"));
|
||||||
|
groundAddInstructionToProgram(&structDef, ret);
|
||||||
|
groundAddInstructionToProgram(&structDef, groundCreateInstruction(ENDFUN));
|
||||||
|
|
||||||
|
*constructor->as.type.returnType = type;
|
||||||
|
constructor->as.type.returnType->type = STT_OBJECT;
|
||||||
|
|
||||||
|
addChildToSolsType(&type, constructor->as.type, "constructor");
|
||||||
|
}
|
||||||
|
|
||||||
// Add to scope
|
// Add to scope
|
||||||
addVariableToScope(scope, node->as.idName, type);
|
addVariableToScope(scope, node->as.idName, type);
|
||||||
|
|
||||||
@@ -1182,6 +1277,8 @@ ResultType(GroundProgram, charptr) generateStructNode(SolsNode* node, SolsScope*
|
|||||||
for (size_t i = 0; i < structDef.size; i++) {
|
for (size_t i = 0; i < structDef.size; i++) {
|
||||||
groundAddInstructionToProgram(&constants, structDef.instructions[i]);
|
groundAddInstructionToProgram(&constants, structDef.instructions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return Success(GroundProgram, charptr, constants);
|
return Success(GroundProgram, charptr, constants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,16 @@
|
|||||||
#include "SolsLiteral.h"
|
#include "SolsLiteral.h"
|
||||||
|
|
||||||
typedef enum SolsTokenType {
|
typedef enum SolsTokenType {
|
||||||
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO, STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_LAMBDA, STT_KW_RETURN, STT_KW_USE, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE, STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA
|
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT,
|
||||||
|
STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN,
|
||||||
|
STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV,
|
||||||
|
STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO,
|
||||||
|
STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET,
|
||||||
|
STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER,
|
||||||
|
STT_KW_DEF, STT_KW_LAMBDA, STT_KW_RETURN,
|
||||||
|
STT_KW_USE, STT_KW_STRUCT, STT_KW_CONSTRUCTOR, STT_KW_DESTRUCTOR,
|
||||||
|
STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE,
|
||||||
|
STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA
|
||||||
} SolsTokenType;
|
} SolsTokenType;
|
||||||
|
|
||||||
typedef char* charptr;
|
typedef char* charptr;
|
||||||
|
|||||||
@@ -277,6 +277,9 @@ ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type, struc
|
|||||||
return Error(GroundArg, charptr, "Anonymous structs are not supported yet");
|
return Error(GroundArg, charptr, "Anonymous structs are not supported yet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case STT_NONE: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "none"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Error(GroundArg, charptr, "How did we get here?");
|
return Error(GroundArg, charptr, "How did we get here?");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "../include/nothing.h"
|
#include "../include/nothing.h"
|
||||||
|
|
||||||
typedef enum SolsTypeType {
|
typedef enum SolsTypeType {
|
||||||
STT_INT, STT_STRING, STT_DOUBLE, STT_BOOL, STT_CHAR, STT_FUN, STT_TEMPLATE, STT_OBJECT, STT_UNKNOWN
|
STT_INT, STT_STRING, STT_DOUBLE, STT_BOOL, STT_CHAR, STT_FUN, STT_TEMPLATE, STT_OBJECT, STT_UNKNOWN, STT_NONE
|
||||||
} SolsTypeType;
|
} SolsTypeType;
|
||||||
|
|
||||||
// Definition of charptr for Result() and ResultType() macros
|
// Definition of charptr for Result() and ResultType() macros
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
|||||||
{"return", STT_KW_RETURN},
|
{"return", STT_KW_RETURN},
|
||||||
{"use", STT_KW_USE},
|
{"use", STT_KW_USE},
|
||||||
{"struct", STT_KW_STRUCT},
|
{"struct", STT_KW_STRUCT},
|
||||||
|
{"constructor", STT_KW_CONSTRUCTOR},
|
||||||
|
{"destructor", STT_KW_DESTRUCTOR},
|
||||||
{"ground", STT_KW_GROUND},
|
{"ground", STT_KW_GROUND},
|
||||||
{"new", STT_KW_NEW},
|
{"new", STT_KW_NEW},
|
||||||
{"{", STT_OPEN_CURLY},
|
{"{", STT_OPEN_CURLY},
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ typedef enum SolsNodeType {
|
|||||||
SNT_OP_SET,
|
SNT_OP_SET,
|
||||||
SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER,
|
SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER,
|
||||||
SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN,
|
SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN,
|
||||||
SNT_USE, SNT_STRUCT,
|
SNT_USE, SNT_STRUCT, SNT_CONSTRUCTOR, SNT_DESTRUCTOR,
|
||||||
SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW,
|
SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW,
|
||||||
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN, SNT_DOT
|
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN, SNT_DOT,
|
||||||
} SolsNodeType;
|
} SolsNodeType;
|
||||||
|
|
||||||
struct SolsNode;
|
struct SolsNode;
|
||||||
|
|||||||
@@ -1675,6 +1675,106 @@ static inline ResultType(Nothing, charptr) parseCloseParen(SolsParser* parser) {
|
|||||||
return Error(Nothing, charptr, "Extra closing parentheses");
|
return Error(Nothing, charptr, "Extra closing parentheses");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ResultType(Nothing, charptr) parseConstructor(SolsParser* parser) {
|
||||||
|
ResultType(SolsNode, charptr) node = createSolsNode(SNT_CONSTRUCTOR);
|
||||||
|
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;
|
||||||
|
if (node.error) {
|
||||||
|
return Error(Nothing, charptr, node.as.error);
|
||||||
|
}
|
||||||
|
ResultType(SolsToken, Nothing) openParen = parserConsume(parser);
|
||||||
|
if (openParen.error || openParen.as.success.type != STT_OPEN_PAREN) {
|
||||||
|
return Error(Nothing, charptr, "Expecting '('");
|
||||||
|
}
|
||||||
|
// Parse type signature
|
||||||
|
for (;;) {
|
||||||
|
ResultType(SolsToken, Nothing) next = parserPeek(parser, 1);
|
||||||
|
if (next.error) {
|
||||||
|
return Error(Nothing, charptr, "Expecting ')' at end of constructor argument list");
|
||||||
|
}
|
||||||
|
if (next.as.success.type == STT_CLOSE_PAREN) {
|
||||||
|
parserConsume(parser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern of type, name, comma
|
||||||
|
|
||||||
|
SolsType tmpType;
|
||||||
|
|
||||||
|
if (next.as.success.type == STT_TYPE) {
|
||||||
|
tmpType = next.as.success.as.type;
|
||||||
|
} else if (next.as.success.type == STT_IDENTIFIER) {
|
||||||
|
tmpType = createIdentifiedSolsType(next.as.success.as.idName).as.success;
|
||||||
|
} else {
|
||||||
|
return Error(Nothing, charptr, "Expecting a type or identifier of type in constructor argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
parserConsume(parser);
|
||||||
|
|
||||||
|
char* argName;
|
||||||
|
next = parserPeek(parser, 1);
|
||||||
|
|
||||||
|
if (next.as.success.type == STT_IDENTIFIER) {
|
||||||
|
argName = next.as.success.as.idName;
|
||||||
|
} else {
|
||||||
|
return Error(Nothing, charptr, "Expecting identifier after type in constructor argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add type to constructed SolsType
|
||||||
|
addChildToSolsType(&type.as.success, tmpType, argName);
|
||||||
|
parserConsume(parser);
|
||||||
|
|
||||||
|
next = parserPeek(parser, 1);
|
||||||
|
if (next.error) {
|
||||||
|
return Error(Nothing, charptr, "Expecting a comma or closing bracket");
|
||||||
|
}
|
||||||
|
if (next.as.success.type == STT_CLOSE_PAREN) {
|
||||||
|
parserConsume(parser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (next.as.success.type != STT_COMMA) {
|
||||||
|
return Error(Nothing, charptr, "Expecting a comma or closing bracket");
|
||||||
|
}
|
||||||
|
parserConsume(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add type to node
|
||||||
|
node.as.success.as.type = type.as.success;
|
||||||
|
|
||||||
|
// 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 constructor 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 = ({
|
||||||
@@ -1735,7 +1835,7 @@ static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
|||||||
_result.as.success;
|
_result.as.success;
|
||||||
});
|
});
|
||||||
if (keyTok.type == STT_KW_DEF) {
|
if (keyTok.type == STT_KW_DEF) {
|
||||||
// def
|
// def fnName(Arg arg1, Arg arg2, ...) ReturnType {}
|
||||||
ResultType(Nothing, charptr) defNode = parseDef(parser);
|
ResultType(Nothing, charptr) defNode = parseDef(parser);
|
||||||
if (defNode.error) {
|
if (defNode.error) {
|
||||||
return Error(Nothing, charptr, defNode.as.error);
|
return Error(Nothing, charptr, defNode.as.error);
|
||||||
@@ -1744,6 +1844,16 @@ static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
|||||||
parser->currentParent->children.count--;
|
parser->currentParent->children.count--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (keyTok.type == STT_KW_CONSTRUCTOR) {
|
||||||
|
// constructor(Arg arg1, Arg arg2, ...) {}
|
||||||
|
ResultType(Nothing, charptr) constructorNode = parseConstructor(parser);
|
||||||
|
if (constructorNode.error) {
|
||||||
|
return Error(Nothing, charptr, constructorNode.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");
|
||||||
}
|
}
|
||||||
@@ -1906,6 +2016,14 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
|||||||
}
|
}
|
||||||
case STT_CLOSE_PAREN: PARSER_HANDLE(CloseParen);
|
case STT_CLOSE_PAREN: PARSER_HANDLE(CloseParen);
|
||||||
case STT_DOT: PARSER_HANDLE(Dot);
|
case STT_DOT: PARSER_HANDLE(Dot);
|
||||||
|
case STT_KW_CONSTRUCTOR: {
|
||||||
|
createParserError(parser, "'constructor' must be used inside a struct definition");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STT_KW_DESTRUCTOR: {
|
||||||
|
createParserError(parser, "'destructor' must be used inside a struct definition");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parser->errors.count > 0) {
|
if (parser->errors.count > 0) {
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
use io
|
struct Person {
|
||||||
|
name = ""
|
||||||
|
age = 0
|
||||||
|
def greet() string {
|
||||||
|
return "Hello, " + self.name + "!"
|
||||||
|
}
|
||||||
|
|
||||||
struct dingus {
|
constructor(string name, int age) {
|
||||||
x = 5
|
self.name = name
|
||||||
y = "dingus"
|
self.age = age
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e = new dingus
|
max = Person("Max", 16)
|
||||||
puts e
|
puts max
|
||||||
puts dingus
|
puts max.greet()
|
||||||
|
|
||||||
puts e.x
|
|
||||||
println(e.y)
|
|
||||||
|
|
||||||
e.x = 7
|
|
||||||
e.y = "heheheha"
|
|
||||||
puts e.x
|
|
||||||
println(e.y)
|
|
||||||
Reference in New Issue
Block a user