diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index 5591c5d..fd00705 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -33,6 +33,14 @@ static inline ResultType(GroundProgram, charptr) generatePutsNode(SolsNode* node return Success(GroundProgram, charptr, program); } +static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node, SolsScope* scope) { + if (node->children.count <= 2) { + return Error(GroundProgram, charptr, "set requires arguments"); + } + return Error(GroundProgram, charptr, "WIP"); + addVariableToScope(scope, node->children.at[0].as.idName, NULL); +} + ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) { GroundProgram program = groundCreateProgram(); @@ -52,6 +60,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope switch (node->type) { case SNT_PUTS: generate(Puts); case SNT_LITERAL: generate(Literal); + case SNT_OP_SET: generate(Set); } return Success(GroundProgram, charptr, program); } diff --git a/src/parser/parser.c b/src/parser/parser.c index 8c0a698..f277675 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -148,6 +148,61 @@ static inline ResultType(Nothing, charptr) parseIdentifier(SolsParser* parser) { return Success(Nothing, charptr, {}); } +static inline ResultType(Nothing, charptr) parseSet(SolsParser* parser) { + if (parser->output.children.at[parser->output.children.count - 1].type != SNT_IDENTIFIER) { + return Error(Nothing, charptr, "Expecting identifier before '='"); + } + + // Collect tokens for node + ResultType(SolsTokens, charptr) tokens = createSolsTokens(); + if (tokens.error) { + return Error(Nothing, charptr, tokens.as.error); + } + + ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0); + if (peek.error) return Error(Nothing, charptr, "ruh roh"); + + for (;;) { + ResultType(SolsToken, Nothing) peek = parserPeek(parser, 1); + if (peek.error) break; + if (getPrecedence(&peek.as.success) <= STP_SET) { + break; + } + parserConsume(parser); + addTokenToSolsTokens(&tokens.as.success, peek.as.success); + } + + // Create node + ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_SET); + if (node.error) return Error(Nothing, charptr, node.as.error); + node.as.success.line = peek.as.success.line; + + // Parse selected tokens + ResultType(SolsParser, charptr) putsParser = createSolsParser(&tokens.as.success); + if (putsParser.error) return Error(Nothing, charptr, putsParser.as.error); + putsParser.as.success.currentParent = &putsParser.as.success.output; + ResultType(Nothing, charptr) parsed = parse(&putsParser.as.success); + + // Add any error messages from parsing + if (parsed.error) { + addToParserErrors(parser, parsed.as.error); + return Success(Nothing, charptr, {}); + } + + if (putsParser.as.success.output.children.count < 1) { + return Error(Nothing, charptr, "Expecting token after '='"); + } + + // Copy nodes into the sols node + for (size_t i = 0; i < putsParser.as.success.output.children.count; i++) { + addChildToSolsNode(&node.as.success, putsParser.as.success.output.children.at[i]); + } + + addChildToSolsNode(parser->currentParent, node.as.success); + + return Success(Nothing, charptr, {}); +} + static inline ResultType(Nothing, charptr) parseLiteral(SolsParser* parser) { ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0); if (peek.error) { @@ -223,14 +278,15 @@ static inline ResultType(Nothing, charptr) parsePuts(SolsParser* parser) { putsParser.as.success.currentParent = &putsParser.as.success.output; ResultType(Nothing, charptr) parsed = parse(&putsParser.as.success); - // Copy nodes into the sols node - for (size_t i = 0; i < putsParser.as.success.output.children.count; i++) { - addChildToSolsNode(&node.as.success, putsParser.as.success.output.children.at[i]); - } - // Add any error messages from parsing if (parsed.error) { addToParserErrors(parser, parsed.as.error); + return Success(Nothing, charptr, {}); + } + + // Copy nodes into the sols node + for (size_t i = 0; i < putsParser.as.success.output.children.count; i++) { + addChildToSolsNode(&node.as.success, putsParser.as.success.output.children.at[i]); } addChildToSolsNode(parser->currentParent, node.as.success); @@ -249,6 +305,7 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) { case STT_IDENTIFIER: PARSER_HANDLE(Identifier); case STT_LITERAL: PARSER_HANDLE(Literal); case STT_KW_PUTS: PARSER_HANDLE(Puts); + case STT_OP_SET: PARSER_HANDLE(Set); } } if (parser->errors.count > 0) {