If and while (scoping coming soon)

This commit is contained in:
2026-02-28 11:27:45 +11:00
parent 82a127f34c
commit 2719017f72
4 changed files with 254 additions and 38 deletions

View File

@@ -9,6 +9,8 @@ SolsTokenPrecedence getPrecedence(SolsToken *token) {
switch (token->type) {
case STT_LINE_END: return STP_NEWLINE;
case STT_KW_PUTS: return STP_PUTS;
case STT_KW_IF: return STP_IF;
case STT_KW_WHILE: return STP_WHILE;
case STT_OP_ADDTO:
case STT_OP_SUBTO:
case STT_OP_MULTO:
@@ -998,6 +1000,130 @@ static inline ResultType(Nothing, charptr) parseCodeBlock(SolsParser* parser) {
return Success(Nothing, charptr, {});
}
static inline ResultType(Nothing, charptr) parseWhile(SolsParser* parser) {
// 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 (peek.as.success.type == STT_OPEN_CURLY) {
break;
}
parserConsume(parser);
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
}
// Create node
ResultType(SolsNode, charptr) node = createSolsNode(SNT_WHILE);
if (node.error) return Error(Nothing, charptr, node.as.error);
node.as.success.line = peek.as.success.line;
// Parse selected tokens
ResultType(SolsParser, charptr) whileParser = createSolsParser(&tokens.as.success);
if (whileParser.error) return Error(Nothing, charptr, whileParser.as.error);
whileParser.as.success.currentParent = &whileParser.as.success.output;
ResultType(Nothing, charptr) parsed = parse(&whileParser.as.success);
// 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 < whileParser.as.success.output.children.count; i++) {
addChildToSolsNode(&node.as.success, whileParser.as.success.output.children.at[i]);
}
addChildToSolsNode(parser->currentParent, node.as.success);
if(parserPeek(parser, 1).as.success.type != STT_OPEN_CURLY) {
return Error(Nothing, charptr, "Expecting opening curly brace for while loop body");
}
parserConsume(parser);
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--;
addChildToSolsNode(&node.as.success, codeBlock);
return Success(Nothing, charptr, {});
}
static inline ResultType(Nothing, charptr) parseIf(SolsParser* parser) {
// 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 (peek.as.success.type == STT_OPEN_CURLY) {
break;
}
parserConsume(parser);
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
}
// Create node
ResultType(SolsNode, charptr) node = createSolsNode(SNT_IF);
if (node.error) return Error(Nothing, charptr, node.as.error);
node.as.success.line = peek.as.success.line;
// Parse selected tokens
ResultType(SolsParser, charptr) ifParser = createSolsParser(&tokens.as.success);
if (ifParser.error) return Error(Nothing, charptr, ifParser.as.error);
ifParser.as.success.currentParent = &ifParser.as.success.output;
ResultType(Nothing, charptr) parsed = parse(&ifParser.as.success);
// 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 < ifParser.as.success.output.children.count; i++) {
addChildToSolsNode(&node.as.success, ifParser.as.success.output.children.at[i]);
}
addChildToSolsNode(parser->currentParent, node.as.success);
if(parserPeek(parser, 1).as.success.type != STT_OPEN_CURLY) {
return Error(Nothing, charptr, "Expecting opening curly brace for if statement body");
}
parserConsume(parser);
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--;
addChildToSolsNode(&node.as.success, codeBlock);
return Success(Nothing, charptr, {});
}
static inline ResultType(Nothing, charptr) parseCloseCurly(SolsParser* parser) {
(void)parser;
return Error(Nothing, charptr, "Extra closing curly brace");
@@ -1014,6 +1140,8 @@ 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_KW_IF: PARSER_HANDLE(If);
case STT_KW_WHILE: PARSER_HANDLE(While);
case STT_OP_SET: PARSER_HANDLE(Set);
case STT_OP_ADD: PARSER_HANDLE(Add);
case STT_OP_SUB: PARSER_HANDLE(Sub);

View File

@@ -14,6 +14,8 @@
typedef enum SolsTokenPrecedence {
STP_NEWLINE = 0,
STP_PUTS = 1,
STP_IF = 1,
STP_WHILE = 1,
STP_COMPARE = 2,
STP_SET = 3,
STP_FUNCTION = 4,