Add all the other inequalities
This commit is contained in:
@@ -97,7 +97,8 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
||||
}
|
||||
return Success(SolsType, charptr, type.as.success);
|
||||
}
|
||||
case SNT_OP_EQUAL: {
|
||||
case SNT_OP_EQUAL:
|
||||
case SNT_OP_INEQUAL: {
|
||||
if (node->children.count < 2) {
|
||||
return Error(SolsType, charptr, "Not enough children to determine type");
|
||||
}
|
||||
@@ -128,6 +129,32 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
||||
|
||||
return Error(SolsType, charptr, "");
|
||||
}
|
||||
case SNT_OP_GREATER:
|
||||
case SNT_OP_LESSER:
|
||||
case SNT_OP_EQGREATER:
|
||||
case SNT_OP_EQLESSER: {
|
||||
if (node->children.count < 2) {
|
||||
return Error(SolsType, charptr, "Not enough children to determine type");
|
||||
}
|
||||
|
||||
ResultType(SolsType, charptr) leftType = getNodeType(&node->children.at[0], scope);
|
||||
if (leftType.error) {
|
||||
return Error(SolsType, charptr, leftType.as.error);
|
||||
}
|
||||
ResultType(SolsType, charptr) rightType = getNodeType(&node->children.at[1], scope);
|
||||
if (rightType.error) {
|
||||
return Error(SolsType, charptr, rightType.as.error);
|
||||
}
|
||||
|
||||
if (!(leftType.as.success.type == STT_INT || leftType.as.success.type == STT_DOUBLE)) {
|
||||
return Error(SolsType, charptr, "Cannot compare with left type");
|
||||
}
|
||||
|
||||
if (!(rightType.as.success.type == STT_INT || rightType.as.success.type == STT_DOUBLE)) {
|
||||
return Error(SolsType, charptr, "Cannot compare with right type");
|
||||
}
|
||||
return Success(SolsType, charptr, STT_BOOL);
|
||||
}
|
||||
case SNT_LITERAL: {
|
||||
switch (node->as.literal.type) {
|
||||
case SLT_INT: {
|
||||
@@ -363,6 +390,170 @@ static inline ResultType(GroundProgram, charptr) generateEqualNode(SolsNode* nod
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
static inline ResultType(GroundProgram, charptr) generateInequalNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 2) {
|
||||
return Error(GroundProgram, charptr, "inequal requires arguments");
|
||||
}
|
||||
|
||||
// Use this function for type checking
|
||||
ResultType(SolsType, charptr) type = getNodeType(node, scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
GroundProgram gp = groundCreateProgram();
|
||||
GroundInstruction add = groundCreateInstruction(INEQUAL);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
|
||||
|
||||
char* tmpId = malloc(sizeof(char) * 64);
|
||||
if (tmpId == NULL) {
|
||||
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in inequal");
|
||||
}
|
||||
snprintf(tmpId, 64, "__SOLS_TMP_INEQUAL_%zu", scope->tmpCounter++);
|
||||
|
||||
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
node->accessArg = groundCreateReference(VALREF, tmpId);
|
||||
|
||||
groundAddInstructionToProgram(&gp, add);
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
static inline ResultType(GroundProgram, charptr) generateGreaterNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 2) {
|
||||
return Error(GroundProgram, charptr, "greater requires arguments");
|
||||
}
|
||||
|
||||
// Use this function for type checking
|
||||
ResultType(SolsType, charptr) type = getNodeType(node, scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
GroundProgram gp = groundCreateProgram();
|
||||
GroundInstruction add = groundCreateInstruction(GREATER);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
|
||||
|
||||
char* tmpId = malloc(sizeof(char) * 64);
|
||||
if (tmpId == NULL) {
|
||||
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in greater");
|
||||
}
|
||||
snprintf(tmpId, 64, "__SOLS_TMP_GREATER_%zu", scope->tmpCounter++);
|
||||
|
||||
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
node->accessArg = groundCreateReference(VALREF, tmpId);
|
||||
|
||||
groundAddInstructionToProgram(&gp, add);
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
static inline ResultType(GroundProgram, charptr) generateEqGreaterNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 2) {
|
||||
return Error(GroundProgram, charptr, "eqgreater requires arguments");
|
||||
}
|
||||
|
||||
// Use this function for type checking
|
||||
ResultType(SolsType, charptr) type = getNodeType(node, scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
GroundProgram gp = groundCreateProgram();
|
||||
GroundInstruction add = groundCreateInstruction(LESSER);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
|
||||
|
||||
char* tmpId = malloc(sizeof(char) * 64);
|
||||
if (tmpId == NULL) {
|
||||
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in eqgreater");
|
||||
}
|
||||
snprintf(tmpId, 64, "__SOLS_TMP_EQGREATER_%zu", scope->tmpCounter++);
|
||||
|
||||
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
node->accessArg = groundCreateReference(VALREF, tmpId);
|
||||
|
||||
groundAddInstructionToProgram(&gp, add);
|
||||
|
||||
GroundInstruction not = groundCreateInstruction(NOT);
|
||||
groundAddReferenceToInstruction(¬, groundCreateReference(VALREF, tmpId));
|
||||
groundAddReferenceToInstruction(¬, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
groundAddInstructionToProgram(&gp, not);
|
||||
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
static inline ResultType(GroundProgram, charptr) generateLesserNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 2) {
|
||||
return Error(GroundProgram, charptr, "lesser requires arguments");
|
||||
}
|
||||
|
||||
// Use this function for type checking
|
||||
ResultType(SolsType, charptr) type = getNodeType(node, scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
GroundProgram gp = groundCreateProgram();
|
||||
GroundInstruction add = groundCreateInstruction(LESSER);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
|
||||
|
||||
char* tmpId = malloc(sizeof(char) * 64);
|
||||
if (tmpId == NULL) {
|
||||
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in lesser");
|
||||
}
|
||||
snprintf(tmpId, 64, "__SOLS_TMP_LESSER_%zu", scope->tmpCounter++);
|
||||
|
||||
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
node->accessArg = groundCreateReference(VALREF, tmpId);
|
||||
|
||||
groundAddInstructionToProgram(&gp, add);
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
static inline ResultType(GroundProgram, charptr) generateEqLesserNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 2) {
|
||||
return Error(GroundProgram, charptr, "eqlesser requires arguments");
|
||||
}
|
||||
|
||||
// Use this function for type checking
|
||||
ResultType(SolsType, charptr) type = getNodeType(node, scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
GroundProgram gp = groundCreateProgram();
|
||||
GroundInstruction add = groundCreateInstruction(GREATER);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
|
||||
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
|
||||
|
||||
char* tmpId = malloc(sizeof(char) * 64);
|
||||
if (tmpId == NULL) {
|
||||
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in eqlesser");
|
||||
}
|
||||
snprintf(tmpId, 64, "__SOLS_TMP_LESSER_%zu", scope->tmpCounter++);
|
||||
|
||||
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
node->accessArg = groundCreateReference(VALREF, tmpId);
|
||||
|
||||
groundAddInstructionToProgram(&gp, add);
|
||||
|
||||
GroundInstruction not = groundCreateInstruction(NOT);
|
||||
groundAddReferenceToInstruction(¬, groundCreateReference(VALREF, tmpId));
|
||||
groundAddReferenceToInstruction(¬, groundCreateReference(DIRREF, tmpId));
|
||||
|
||||
groundAddInstructionToProgram(&gp, not);
|
||||
|
||||
return Success(GroundProgram, charptr, gp);
|
||||
}
|
||||
|
||||
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
|
||||
|
||||
GroundProgram program = groundCreateProgram();
|
||||
@@ -388,6 +579,11 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
|
||||
case SNT_OP_MUL: generate(Mul);
|
||||
case SNT_OP_DIV: generate(Div);
|
||||
case SNT_OP_EQUAL: generate(Equal);
|
||||
case SNT_OP_INEQUAL: generate(Inequal);
|
||||
case SNT_OP_GREATER: generate(Greater);
|
||||
case SNT_OP_EQGREATER: generate(EqGreater);
|
||||
case SNT_OP_LESSER: generate(Lesser);
|
||||
case SNT_OP_EQLESSER: generate(EqLesser);
|
||||
}
|
||||
return Success(GroundProgram, charptr, program);
|
||||
}
|
||||
|
||||
@@ -535,6 +535,321 @@ static inline ResultType(Nothing, charptr) parseEqual(SolsParser* parser) {
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseInequal(SolsParser* parser) {
|
||||
if (parser->currentParent->children.count < 1) {
|
||||
return Error(Nothing, charptr, "Expecting something before '!='");
|
||||
}
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||
|
||||
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_COMPARE) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_INEQUAL);
|
||||
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 idnode into set node
|
||||
addChildToSolsNode(&node.as.success, idNode);
|
||||
|
||||
// Copy nodes into the set 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]);
|
||||
}
|
||||
|
||||
// Put the equal node where the idNode was
|
||||
parser->currentParent->children.count--;
|
||||
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseGreater(SolsParser* parser) {
|
||||
if (parser->currentParent->children.count < 1) {
|
||||
return Error(Nothing, charptr, "Expecting something before '>'");
|
||||
}
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||
|
||||
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_COMPARE) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_GREATER);
|
||||
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 idnode into set node
|
||||
addChildToSolsNode(&node.as.success, idNode);
|
||||
|
||||
// Copy nodes into the set 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]);
|
||||
}
|
||||
|
||||
// Put the equal node where the idNode was
|
||||
parser->currentParent->children.count--;
|
||||
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseLesser(SolsParser* parser) {
|
||||
if (parser->currentParent->children.count < 1) {
|
||||
return Error(Nothing, charptr, "Expecting something before '<'");
|
||||
}
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||
|
||||
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_COMPARE) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_LESSER);
|
||||
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 idnode into set node
|
||||
addChildToSolsNode(&node.as.success, idNode);
|
||||
|
||||
// Copy nodes into the set 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]);
|
||||
}
|
||||
|
||||
// Put the equal node where the idNode was
|
||||
parser->currentParent->children.count--;
|
||||
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseEqGreater(SolsParser* parser) {
|
||||
if (parser->currentParent->children.count < 1) {
|
||||
return Error(Nothing, charptr, "Expecting something before '>='");
|
||||
}
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||
|
||||
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_COMPARE) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_EQGREATER);
|
||||
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 idnode into set node
|
||||
addChildToSolsNode(&node.as.success, idNode);
|
||||
|
||||
// Copy nodes into the set 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]);
|
||||
}
|
||||
|
||||
// Put the equal node where the idNode was
|
||||
parser->currentParent->children.count--;
|
||||
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseEqLesser(SolsParser* parser) {
|
||||
if (parser->currentParent->children.count < 1) {
|
||||
return Error(Nothing, charptr, "Expecting something before '<='");
|
||||
}
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||
|
||||
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_COMPARE) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_EQLESSER);
|
||||
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 idnode into set node
|
||||
addChildToSolsNode(&node.as.success, idNode);
|
||||
|
||||
// Copy nodes into the set 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]);
|
||||
}
|
||||
|
||||
// Put the equal node where the idNode was
|
||||
parser->currentParent->children.count--;
|
||||
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) {
|
||||
@@ -643,6 +958,11 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||
case STT_OP_MUL: PARSER_HANDLE(Mul);
|
||||
case STT_OP_DIV: PARSER_HANDLE(Div);
|
||||
case STT_OP_EQUAL: PARSER_HANDLE(Equal);
|
||||
case STT_OP_INEQUAL: PARSER_HANDLE(Inequal);
|
||||
case STT_OP_GREATER: PARSER_HANDLE(Greater);
|
||||
case STT_OP_LESSER: PARSER_HANDLE(Lesser);
|
||||
case STT_OP_EQGREATER: PARSER_HANDLE(EqGreater);
|
||||
case STT_OP_EQLESSER: PARSER_HANDLE(EqLesser);
|
||||
}
|
||||
}
|
||||
if (parser->errors.count > 0) {
|
||||
|
||||
Reference in New Issue
Block a user