forked from solstice/solstice
Parse expressions in parens (3 + 2) * 4
This commit is contained in:
@@ -11,7 +11,17 @@
|
||||
#include "../lexer/SolsToken.h"
|
||||
|
||||
typedef enum SolsNodeType {
|
||||
SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE, SNT_CODE_BLOCK, SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV, SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO, SNT_OP_INCREMENT, SNT_OP_DECREMENT, SNT_OP_SET, 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_USE, SNT_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT
|
||||
SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE,
|
||||
SNT_CODE_BLOCK,
|
||||
SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV,
|
||||
SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO,
|
||||
SNT_OP_INCREMENT, SNT_OP_DECREMENT,
|
||||
SNT_OP_SET,
|
||||
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_USE, SNT_STRUCT,
|
||||
SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW,
|
||||
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN
|
||||
} SolsNodeType;
|
||||
|
||||
struct SolsNode;
|
||||
|
||||
@@ -1607,12 +1607,70 @@ static inline ResultType(Nothing, charptr) parseInlineGround(SolsParser* parser)
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseOpenParen(SolsParser* parser) {
|
||||
return Error(Nothing, charptr, "WIP");
|
||||
size_t parenCount = 1;
|
||||
size_t curlyCount = 0;
|
||||
SolsTokens tokens = ({
|
||||
ResultType(SolsTokens, charptr) _result = createSolsTokens();
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
// Collect tokens
|
||||
for (;;) {
|
||||
ResultType(SolsToken, Nothing) token = parserConsume(parser);
|
||||
if (token.error) {
|
||||
return Error(Nothing, charptr, "Expecting ')'");
|
||||
}
|
||||
bool done = false;
|
||||
switch (token.as.success.type) {
|
||||
case STT_OPEN_PAREN:
|
||||
parenCount++;
|
||||
break;
|
||||
case STT_CLOSE_PAREN:
|
||||
parenCount--;
|
||||
if (parenCount == 0) {
|
||||
if (curlyCount == 0) {
|
||||
done = true;
|
||||
} else {
|
||||
return Error(Nothing, charptr, "Expecting '}' before ')'");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STT_OPEN_CURLY:
|
||||
curlyCount++;
|
||||
break;
|
||||
case STT_CLOSE_CURLY:
|
||||
if (curlyCount == 0) {
|
||||
return Error(Nothing, charptr, "Extra closing curly brace inside ()");
|
||||
}
|
||||
curlyCount--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (done) break;
|
||||
addTokenToSolsTokens(&tokens, token.as.success);
|
||||
}
|
||||
// Parse tokens
|
||||
ResultType(SolsParser, charptr) newParser = createSolsParser(&tokens);
|
||||
if (newParser.error) {
|
||||
return Error(Nothing, charptr, newParser.as.error);
|
||||
}
|
||||
newParser.as.success.currentParent = &newParser.as.success.output;
|
||||
ResultType(Nothing, charptr) parsed = parse(&newParser.as.success);
|
||||
if (parsed.error) {
|
||||
addToParserErrors(parser, parsed.as.error);
|
||||
}
|
||||
// Add node to parent
|
||||
newParser.as.success.output.type = SNT_EXPR_IN_PAREN;
|
||||
addChildToSolsNode(parser->currentParent, newParser.as.success.output);
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseCloseParen(SolsParser* parser) {
|
||||
(void)parser;
|
||||
return Error(Nothing, charptr, "Extra closing parenthases");
|
||||
return Error(Nothing, charptr, "Extra closing parentheses");
|
||||
}
|
||||
|
||||
ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||
|
||||
Reference in New Issue
Block a user