diff options
-rw-r--r-- | src/compiler/ast-tree.c | 114 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 13 | ||||
-rw-r--r-- | src/compiler/lexer.c | 17 | ||||
-rw-r--r-- | src/compiler/lexer.h | 4 | ||||
-rw-r--r-- | src/compiler/parser.c | 94 | ||||
-rw-r--r-- | src/compiler/parser.h | 13 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/runner/runner.c | 48 | ||||
-rw-r--r-- | test/main.felan | 8 |
9 files changed, 228 insertions, 86 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index ea5da0b..d7769bc 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -58,6 +58,10 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_ASSIGN", "AST_TREE_TOKEN_OPERATOR_SUM", + "AST_TREE_TOKEN_OPERATOR_SUB", + "AST_TREE_TOKEN_OPERATOR_MULTIPLY", + "AST_TREE_TOKEN_OPERATOR_DIVIDE", + "AST_TREE_TOKEN_OPERATOR_MODULO", "AST_TREE_TOKEN_NONE", }; @@ -184,6 +188,10 @@ void astTreePrint(const AstTree *tree, int indent) { } goto RETURN_SUCCESS; case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_OPERATOR_ASSIGN: { AstTreeInfix *metadata = tree->metadata; printf(",\n"); @@ -290,6 +298,10 @@ void astTreeDestroy(AstTree tree) { } return; case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_OPERATOR_ASSIGN: { AstTreeInfix *metadata = tree.metadata; astTreeDestroy(metadata->left); @@ -374,7 +386,11 @@ AstTree *copyAstTree(AstTree *tree) { tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_OPERATOR_ASSIGN: - case AST_TREE_TOKEN_OPERATOR_SUM: { + case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: { AstTreeInfix *metadata = tree->metadata; AstTreeInfix *new_metadata = a404m_malloc(sizeof(*new_metadata)); AstTree *left = copyAstTree(&metadata->left); @@ -487,7 +503,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { for (size_t i = 0; i < nodes->size; ++i) { ParserNode *eol = nodes->data[i]; if (eol->token != PARSER_TOKEN_SYMBOL_EOL) { - printError(eol->str_begin, eol->str_end, "Unexpected %s", + printError(eol->str_begin, eol->str_end, "Did you forgot semicolon?", PARSER_TOKEN_STRINGS[eol->token]); goto RETURN_ERROR; } @@ -536,6 +552,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_FUNCTION_DEFINITION: + case PARSER_TOKEN_FUNCTION_CALL: goto AFTER_SWITCH; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_IDENTIFIER: @@ -552,9 +569,12 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_SYMBOL_COMMA: - case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: printError(node->str_begin, node->str_end, "Should not be here"); goto RETURN_ERROR; case PARSER_TOKEN_NONE: @@ -675,9 +695,23 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables, case PARSER_TOKEN_KEYWORD_RETURN: return astTreeParseReturn(parserNode, variables, variables_size); case PARSER_TOKEN_OPERATOR_ASSIGN: - return astTreeParseAssign(parserNode, variables, variables_size); + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_ASSIGN); case PARSER_TOKEN_OPERATOR_SUM: - return astTreeParseSum(parserNode, variables, variables_size); + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_SUM); + case PARSER_TOKEN_OPERATOR_SUB: + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_SUB); + case PARSER_TOKEN_OPERATOR_MULTIPLY: + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_MULTIPLY); + case PARSER_TOKEN_OPERATOR_DIVIDE: + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_DIVIDE); + case PARSER_TOKEN_OPERATOR_MODULO: + return astTreeParseBinaryOperator(parserNode, variables, variables_size, + AST_TREE_TOKEN_OPERATOR_MODULO); case PARSER_TOKEN_VARIABLE: return astTreeParseVariable(parserNode, variables, variables_size); case PARSER_TOKEN_CONSTANT: @@ -944,35 +978,9 @@ AstTree *astTreeParseReturn(ParserNode *parserNode, parserNode->str_begin, parserNode->str_end); } -AstTree *astTreeParseAssign(ParserNode *parserNode, - AstTreeVariables **variables, - size_t variables_size) { - ParserNodeInfixMetadata *node_metadata = parserNode->metadata; - - AstTree *left = astTreeParse(node_metadata->left, variables, variables_size); - if (left == NULL) { - return NULL; - } - AstTree *right = - astTreeParse(node_metadata->right, variables, variables_size); - if (right == NULL) { - return NULL; - } - - AstTreeInfix *metadata = a404m_malloc(sizeof(*metadata)); - - metadata->left = *left; - metadata->right = *right; - - free(left); - free(right); - - return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata, NULL, - parserNode->str_begin, parserNode->str_end); -} - -AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables, - size_t variables_size) { +AstTree *astTreeParseBinaryOperator(ParserNode *parserNode, + AstTreeVariables **variables, + size_t variables_size, AstTreeToken token) { ParserNodeInfixMetadata *node_metadata = parserNode->metadata; AstTree *left = astTreeParse(node_metadata->left, variables, variables_size); @@ -993,8 +1001,8 @@ AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables, free(left); free(right); - return newAstTree(AST_TREE_TOKEN_OPERATOR_SUM, metadata, NULL, - parserNode->str_begin, parserNode->str_end); + return newAstTree(token, metadata, NULL, parserNode->str_begin, + parserNode->str_end); } bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, @@ -1115,6 +1123,10 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: return NULL; case AST_TREE_TOKEN_NONE: } @@ -1139,6 +1151,10 @@ bool isConst(AstTree *value) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: return false; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = value->metadata; @@ -1190,7 +1206,11 @@ AstTree *makeTypeOf(AstTree *value) { return copyAstTree(variable->type); } case AST_TREE_TOKEN_OPERATOR_ASSIGN: - case AST_TREE_TOKEN_OPERATOR_SUM: { + case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: { AstTreeInfix *metadata = value->metadata; return copyAstTree(metadata->left.type); } @@ -1213,6 +1233,10 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: return false; case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -1289,7 +1313,11 @@ bool setAllTypes(AstTree *tree, AstTreeFunction *function) { case AST_TREE_TOKEN_OPERATOR_ASSIGN: return setTypesOperatorAssign(tree); case AST_TREE_TOKEN_OPERATOR_SUM: - return setTypesOperatorSum(tree); + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: + return setTypesOperatorInfix(tree); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree); case AST_TREE_TOKEN_NONE: @@ -1429,7 +1457,7 @@ bool setTypesOperatorAssign(AstTree *tree) { } } -bool setTypesOperatorSum(AstTree *tree) { +bool setTypesOperatorInfix(AstTree *tree) { AstTreeInfix *infix = tree->metadata; if (!setTypesAstInfix(infix)) { return false; @@ -1500,6 +1528,10 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: return true; case AST_TREE_TOKEN_NONE: } @@ -1586,6 +1618,10 @@ size_t astTreeTypeSize(AstTree tree) { case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_NONE: } UNREACHABLE; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index d67560f..9caef63 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -25,6 +25,10 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_ASSIGN, AST_TREE_TOKEN_OPERATOR_SUM, + AST_TREE_TOKEN_OPERATOR_SUB, + AST_TREE_TOKEN_OPERATOR_MULTIPLY, + AST_TREE_TOKEN_OPERATOR_DIVIDE, + AST_TREE_TOKEN_OPERATOR_MODULO, AST_TREE_TOKEN_NONE, } AstTreeToken; @@ -146,12 +150,9 @@ AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); -AstTree *astTreeParseAssign(ParserNode *parserNode, +AstTree *astTreeParseBinaryOperator(ParserNode *parserNode, AstTreeVariables **variables, - size_t variables_size); - -AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables, - size_t variables_size); + size_t variables_size,AstTreeToken token); bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); @@ -174,7 +175,7 @@ bool setTypesTypeFunction(AstTree *tree); bool setTypesFunctionCall(AstTree *tree); bool setTypesVariable(AstTree *tree); bool setTypesOperatorAssign(AstTree *tree); -bool setTypesOperatorSum(AstTree *tree); +bool setTypesOperatorInfix(AstTree *tree); bool setTypesVariableDefine(AstTree *tree); bool setTypesAstVariable(AstTreeVariable *variable); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 52702ba..70cd1fb 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -33,12 +33,16 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_ASSIGN", "LEXER_TOKEN_SYMBOL_COMMA", "LEXER_TOKEN_SYMBOL_PLUS", + "LEXER_TOKEN_SYMBOL_MINUS", + "LEXER_TOKEN_SYMBOL_MULTIPLY", + "LEXER_TOKEN_SYMBOL_DIVIDE", + "LEXER_TOKEN_SYMBOL_MODULO", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", + ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", "-", "*", "/", "%", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -51,6 +55,10 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_SYMBOL_PLUS, + LEXER_TOKEN_SYMBOL_MINUS, + LEXER_TOKEN_SYMBOL_MULTIPLY, + LEXER_TOKEN_SYMBOL_DIVIDE, + LEXER_TOKEN_SYMBOL_MODULO, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -119,6 +127,9 @@ LexerNodeArray lexer(char *str) { goto RETURN_ERROR; } } + } else { + --iter; + c = *iter; } } if (isSpace(c)) { @@ -198,6 +209,10 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_ASSIGN: case LEXER_TOKEN_SYMBOL_COMMA: case LEXER_TOKEN_SYMBOL_PLUS: + case LEXER_TOKEN_SYMBOL_MINUS: + case LEXER_TOKEN_SYMBOL_MULTIPLY: + case LEXER_TOKEN_SYMBOL_DIVIDE: + case LEXER_TOKEN_SYMBOL_MODULO: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 6c0660f..6723cc9 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -27,6 +27,10 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_SYMBOL_PLUS, + LEXER_TOKEN_SYMBOL_MINUS, + LEXER_TOKEN_SYMBOL_MULTIPLY, + LEXER_TOKEN_SYMBOL_DIVIDE, + LEXER_TOKEN_SYMBOL_MODULO, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index f61836e..4b736b7 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -36,6 +36,10 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_ASSIGN", "PARSER_TOKEN_OPERATOR_SUM", + "PARSER_TOKEN_OPERATOR_SUB", + "PARSER_TOKEN_OPERATOR_MULTIPLY", + "PARSER_TOKEN_OPERATOR_DIVIDE", + "PARSER_TOKEN_OPERATOR_MODULO", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -67,7 +71,12 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, ), + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_SYMBOL_DIVIDE, + LEXER_TOKEN_SYMBOL_MODULO, ), + }, + { + .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, ), }, { .ltr = true, @@ -242,7 +251,11 @@ void parserNodePrint(const ParserNode *node, int indent) { } goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_ASSIGN: - case PARSER_TOKEN_OPERATOR_SUM: { + case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: { const ParserNodeInfixMetadata *metadata = node->metadata; printf(",\n"); for (int i = 0; i < indent; ++i) @@ -342,14 +355,17 @@ void parserNodeDelete(ParserNode *node) { } goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_ASSIGN: - case PARSER_TOKEN_OPERATOR_SUM: { + case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: { ParserNodeInfixMetadata *metadata = node->metadata; parserNodeDelete(metadata->left); parserNodeDelete(metadata->right); free(metadata); } goto RETURN_SUCCESS; - case PARSER_TOKEN_NONE: } UNREACHABLE; @@ -412,12 +428,13 @@ bool parserNodeArray(LexerNode *begin, LexerNode *end, ParserNode *parent) { for (LexerNode *iter = begin; iter < end; ++iter) { ParserNode *pNode = iter->parserNode; - if (pNode->parent != parent) { - continue; - } else if (pNode == NULL) { - printError(pNode->str_begin, pNode->str_end, "Bad child"); + if (pNode == NULL) { + printError(iter->str_begin, iter->str_end, "Bad child"); goto RETURN_ERROR; + } else if (pNode->parent != parent) { + continue; } + for (size_t i = 0; i < parsedNodes->size; ++i) { if (parsedNodes->data[i] == pNode) { goto CONTINUE; @@ -484,13 +501,28 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_NUMBER: return parserNumber(node, parent); case LEXER_TOKEN_SYMBOL_ASSIGN: - return parserAssign(node, begin, end, parent); + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_ASSIGN); + case LEXER_TOKEN_SYMBOL_MULTIPLY: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_MULTIPLY); + case LEXER_TOKEN_SYMBOL_DIVIDE: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_DIVIDE); + case LEXER_TOKEN_SYMBOL_MODULO: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_MODULO); case LEXER_TOKEN_SYMBOL_PLUS: - return parserPlus(node, begin, end, parent); + return parserBinaryOrLeftOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SUM); + case LEXER_TOKEN_SYMBOL_MINUS: + return parserBinaryOrLeftOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SUB); case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: case LEXER_TOKEN_NONE: + break; } UNREACHABLE; } @@ -915,7 +947,7 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end, } else { value = getUntilCommonParent(valueNode->parserNode, parent); if (!isValue(value)) { - printError(name->str_begin, name->str_end, "No value"); + printError(name->str_begin, name->str_end, "Bad value"); return NULL; } value->parent = variableNode; @@ -943,13 +975,14 @@ RETURN_ERROR: return NULL; } -ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, - ParserNode *parent) { +ParserNode *parserBinaryOperator(LexerNode *node, LexerNode *begin, + LexerNode *end, ParserNode *parent, + ParserToken token) { LexerNode *leftNode = node - 1; LexerNode *rightNode = node + 1; if (leftNode < begin || rightNode >= end) { - printError(node->str_begin, node->str_end, "Bad assign"); + printError(node->str_begin, node->str_end, "Bad binary operator"); return NULL; } @@ -957,7 +990,7 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent); if (left == NULL || right == NULL) { - printError(node->str_begin, node->str_end, "Bad assign"); + printError(node->str_begin, node->str_end, "Bad binary operator"); return NULL; } @@ -965,13 +998,13 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, metadata->left = left; metadata->right = right; - return left->parent = right->parent = node->parserNode = - newParserNode(PARSER_TOKEN_OPERATOR_ASSIGN, left->str_begin, - right->str_end, metadata, parent); + return left->parent = right->parent = node->parserNode = newParserNode( + token, left->str_begin, right->str_end, metadata, parent); } -ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end, - ParserNode *parent) { +ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, + LexerNode *end, ParserNode *parent, + ParserToken token) { LexerNode *leftNode = node - 1; LexerNode *rightNode = node + 1; @@ -992,9 +1025,8 @@ ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end, metadata->left = left; metadata->right = right; - return left->parent = right->parent = node->parserNode = - newParserNode(PARSER_TOKEN_OPERATOR_SUM, left->str_begin, - right->str_end, metadata, parent); + return left->parent = right->parent = node->parserNode = newParserNode( + token, left->str_begin, right->str_end, metadata, parent); } bool isAllArguments(const ParserNodeArray *nodes) { @@ -1019,6 +1051,10 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_VALUE_BOOL: return true; @@ -1061,6 +1097,10 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: return false; case PARSER_TOKEN_NONE: } @@ -1076,12 +1116,16 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: - return true; - case PARSER_TOKEN_TYPE_FUNCTION: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_U64: case PARSER_TOKEN_TYPE_BOOL: + return true; + case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_PARENTHESIS: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 29a303c..0b92fe5 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -31,6 +31,10 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_ASSIGN, PARSER_TOKEN_OPERATOR_SUM, + PARSER_TOKEN_OPERATOR_SUB, + PARSER_TOKEN_OPERATOR_MULTIPLY, + PARSER_TOKEN_OPERATOR_DIVIDE, + PARSER_TOKEN_OPERATOR_MODULO, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -130,10 +134,11 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); -ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, - ParserNode *parent); -ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end, - ParserNode *parent); +ParserNode *parserBinaryOperator(LexerNode *node, LexerNode *begin, + LexerNode *end, ParserNode *parent, + ParserToken token); +ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerNode *end, + ParserNode *parent,ParserToken token); bool isAllArguments(const ParserNodeArray *nodes); @@ -118,6 +118,7 @@ int main(int argc, char *argv[]) { return 1; } - const int ret = run(argv[1], false); + const int ret = run(argv[1], true); fileDelete(); + return ret; } diff --git a/src/runner/runner.c b/src/runner/runner.c index 2378387..9c3e7e2 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -41,8 +41,8 @@ void runnerVariableSetValue(RunnerVariablePages *pages, } for (size_t i = 0; i < pages->size; ++i) { RunnerVariables *variables = pages->data[i]; - for (size_t i = 0; i < variables->size; ++i) { - RunnerVariable *var = variables->data[i]; + for (size_t j = 0; j < variables->size; ++j) { + RunnerVariable *var = variables->data[j]; if (var->variable == variable) { if (var->value != NULL) { astTreeDelete(var->value); @@ -63,8 +63,8 @@ AstTree *runnerVariableGetValue(RunnerVariablePages *pages, } for (size_t i = 0; i < pages->size; ++i) { RunnerVariables *variables = pages->data[i]; - for (size_t i = 0; i < variables->size; ++i) { - RunnerVariable *var = variables->data[i]; + for (size_t j = 0; j < variables->size; ++j) { + RunnerVariable *var = variables->data[j]; if (var->variable == variable) { if (var->value != NULL) { return var->value; @@ -205,6 +205,10 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments, } continue; case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -249,7 +253,11 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) { UNREACHABLE; } } - case AST_TREE_TOKEN_OPERATOR_SUM: { + case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: { AstTreeInfix *metadata = tree->metadata; AstTree *left = calcAstTreeValue(&metadata->left, pages); AstTree *right = calcAstTreeValue(&metadata->right, pages); @@ -257,8 +265,30 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) { if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { if (left->token == AST_TREE_TOKEN_VALUE_U64 && right->token == AST_TREE_TOKEN_VALUE_U64) { - left->metadata = - (void *)((AstTreeU64)left->metadata + (AstTreeU64)right->metadata); + switch (tree->token) { + case AST_TREE_TOKEN_OPERATOR_SUM: + left->metadata = (void *)((AstTreeU64)left->metadata + + (AstTreeU64)right->metadata); + break; + case AST_TREE_TOKEN_OPERATOR_SUB: + left->metadata = (void *)((AstTreeU64)left->metadata - + (AstTreeU64)right->metadata); + break; + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + left->metadata = (void *)((AstTreeU64)left->metadata * + (AstTreeU64)right->metadata); + break; + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + left->metadata = (void *)((AstTreeU64)left->metadata / + (AstTreeU64)right->metadata); + break; + case AST_TREE_TOKEN_OPERATOR_MODULO: + left->metadata = (void *)((AstTreeU64)left->metadata % + (AstTreeU64)right->metadata); + break; + default: + UNREACHABLE; + } astTreeDelete(right); return left; } else { @@ -301,6 +331,10 @@ AstTree *deepCopyAstTree(AstTree *tree) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_OPERATOR_SUB: + case AST_TREE_TOKEN_OPERATOR_MULTIPLY: + case AST_TREE_TOKEN_OPERATOR_DIVIDE: + case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_NONE: } UNREACHABLE; diff --git a/test/main.felan b/test/main.felan index f5799d4..3cf7788 100644 --- a/test/main.felan +++ b/test/main.felan @@ -1,10 +1,12 @@ main :: () -> void { - a := fun(2, 3); - print(a+5); + a := fun(2, 3,); + print(a+5+t); }; +t :: fun(1,2); + fun :: (a:u64, b:u64)->u64 { - return a+b+1; + return b+a*b-b/a%2; }; print :: (a:u64)->void { |