diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/ast-tree.c | 150 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 14 | ||||
-rw-r--r-- | src/compiler/code-generator.c | 10 | ||||
-rw-r--r-- | src/compiler/lexer.c | 21 | ||||
-rw-r--r-- | src/compiler/lexer.h | 6 | ||||
-rw-r--r-- | src/compiler/parser.c | 71 | ||||
-rw-r--r-- | src/compiler/parser.h | 8 | ||||
-rw-r--r-- | src/runner/runner.c | 92 |
8 files changed, 330 insertions, 42 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 9f421ae..d50d0f6 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -19,20 +19,20 @@ AstTree AST_TREE_VOID_TYPE = { .type = &AST_TREE_TYPE_TYPE, }; -AstTree AST_TREE_I64_TYPE = { - .token = AST_TREE_TOKEN_TYPE_I64, +AstTree AST_TREE_BOOL_TYPE = { + .token = AST_TREE_TOKEN_TYPE_BOOL, .metadata = NULL, .type = &AST_TREE_TYPE_TYPE, }; -AstTree AST_TREE_U64_TYPE = { - .token = AST_TREE_TOKEN_TYPE_U64, +AstTree AST_TREE_I64_TYPE = { + .token = AST_TREE_TOKEN_TYPE_I64, .metadata = NULL, .type = &AST_TREE_TYPE_TYPE, }; -AstTree AST_TREE_BOOL_TYPE = { - .token = AST_TREE_TOKEN_TYPE_BOOL, +AstTree AST_TREE_U64_TYPE = { + .token = AST_TREE_TOKEN_TYPE_U64, .metadata = NULL, .type = &AST_TREE_TYPE_TYPE, }; @@ -145,7 +145,7 @@ void astTreePrint(const AstTree *tree, int indent) { } goto RETURN_SUCCESS; case AST_TREE_TOKEN_VALUE_INT: { - AstTreeU64 metadata = (AstTreeU64)tree->metadata; + AstTreeInt metadata = (AstTreeInt)tree->metadata; printf(",value=%lu", metadata); } goto RETURN_SUCCESS; @@ -201,7 +201,14 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: - case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { + AstTreeInfix *metadata = tree->metadata; printf(",\n"); for (int i = 0; i < indent; ++i) @@ -276,7 +283,9 @@ void astTreeRootPrint(const AstTreeRoot *root) { } void astTreeDestroy(AstTree tree) { - astTreeDelete(tree.type); + if (tree.type != NULL) { + astTreeDelete(tree.type); + } switch (tree.token) { case AST_TREE_TOKEN_FUNCTION: { AstTreeFunction *metadata = tree.metadata; @@ -350,7 +359,13 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: - case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { AstTreeInfix *metadata = tree.metadata; astTreeDestroy(metadata->left); astTreeDestroy(metadata->right); @@ -463,7 +478,13 @@ AstTree *copyAstTree(AstTree *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: { + case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { AstTreeInfix *metadata = tree->metadata; AstTreeInfix *new_metadata = a404m_malloc(sizeof(*new_metadata)); AstTree *left = copyAstTree(&metadata->left); @@ -651,6 +672,12 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_KEYWORD_IF: goto AFTER_SWITCH; @@ -800,7 +827,7 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_VALUE_INT: return newAstTree( AST_TREE_TOKEN_VALUE_INT, - (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata, NULL, + (void *)(AstTreeInt)(ParserNodeIntMetadata)parserNode->metadata, NULL, parserNode->str_begin, parserNode->str_end); case PARSER_TOKEN_VALUE_BOOL: return newAstTree( @@ -829,6 +856,24 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_MODULO: return astTreeParseBinaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_MODULO); + case PARSER_TOKEN_OPERATOR_EQUAL: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_EQUAL); + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_NOT_EQUAL); + case PARSER_TOKEN_OPERATOR_GREATER: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_GREATER); + case PARSER_TOKEN_OPERATOR_SMALLER: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_SMALLER); + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL); + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL); case PARSER_TOKEN_OPERATOR_PLUS: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_PLUS); @@ -958,6 +1003,12 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -1350,6 +1401,12 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -1431,6 +1488,12 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_SCOPE: return NULL; case AST_TREE_TOKEN_NONE: @@ -1464,6 +1527,12 @@ bool isConst(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_SCOPE: return false; case AST_TREE_TOKEN_VARIABLE: { @@ -1530,6 +1599,14 @@ AstTree *makeTypeOf(AstTree *value) { AstTreeInfix *metadata = value->metadata; return copyAstTree(metadata->left.type); } + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { + return &AST_TREE_BOOL_TYPE; + } case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -1556,6 +1633,12 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_SCOPE: @@ -1616,7 +1699,13 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable, 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_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { AstTreeInfix *metadata = tree->metadata; return isCircularDependencies(helper, variable, &metadata->left) || isCircularDependencies(helper, variable, &metadata->right); @@ -1719,6 +1808,13 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: return setTypesOperatorInfix(tree, helper); + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + return setTypesOperatorInfixWithRet(tree, &AST_TREE_BOOL_TYPE, helper); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree, helper); case AST_TREE_TOKEN_KEYWORD_IF: @@ -1774,6 +1870,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper) { } bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper _helper) { + (void)(_helper); AstTreeSingleChild *metadata = tree->metadata; AstTreeSetTypesHelper helper = { .lookingType = &AST_TREE_U64_TYPE, @@ -1894,6 +1991,20 @@ bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper helper) { } } +bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, + AstTreeSetTypesHelper helper) { + AstTreeInfix *infix = tree->metadata; + if (!setTypesAstInfix(infix, helper)) { + return false; + } else if (!typeIsEqual(infix->left.type, infix->right.type)) { + printError(tree->str_begin, tree->str_end, "Type mismatch"); + return false; + } else { + tree->type = retType; + return true; + } +} + bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeSingleChild *operand = tree->metadata; if (!setAllTypes(operand, helper, NULL)) { @@ -1912,6 +2023,7 @@ bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper _helper) { + (void)_helper; AstTreeSetTypesHelper helper = { .lookingType = &AST_TREE_TYPE_TYPE, }; @@ -2030,6 +2142,12 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_SCOPE: return true; case AST_TREE_TOKEN_NONE: @@ -2125,6 +2243,12 @@ size_t astTreeTypeSize(AstTree tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 1d2f054..798a6b4 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -33,6 +33,12 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_MULTIPLY, AST_TREE_TOKEN_OPERATOR_DIVIDE, AST_TREE_TOKEN_OPERATOR_MODULO, + AST_TREE_TOKEN_OPERATOR_EQUAL, + AST_TREE_TOKEN_OPERATOR_NOT_EQUAL, + AST_TREE_TOKEN_OPERATOR_GREATER, + AST_TREE_TOKEN_OPERATOR_SMALLER, + AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL, + AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL, AST_TREE_TOKEN_SCOPE, @@ -51,6 +57,7 @@ typedef struct AstTree { extern AstTree AST_TREE_TYPE_TYPE; extern AstTree AST_TREE_VOID_TYPE; +extern AstTree AST_TREE_BOOL_TYPE; extern AstTree AST_TREE_I64_TYPE; extern AstTree AST_TREE_U64_TYPE; extern AstTree AST_TREE_VOID_VALUE; @@ -96,7 +103,7 @@ typedef struct AstTreeFunctionCall { size_t parameters_size; } AstTreeFunctionCall; -typedef uint64_t AstTreeU64; +typedef uint64_t AstTreeInt; typedef bool AstTreeBool; @@ -189,6 +196,8 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, + AstTreeSetTypesHelper helper); bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper, @@ -196,7 +205,8 @@ bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); -bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper helper); +bool setTypesAstVariable(AstTreeVariable *variable, + AstTreeSetTypesHelper helper); bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper); bool astTreeCleanRoot(AstTreeRoot *root); diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c index 665b92a..0a3938e 100644 --- a/src/compiler/code-generator.c +++ b/src/compiler/code-generator.c @@ -103,7 +103,7 @@ CodeGeneratorFunctionEnd *newCodeGeneratorFunctionEnd(char *name_begin, CodeGeneratorOperand *newCodeGeneratorOperandFromAstTree(AstTree tree) { switch (tree.token) { case AST_TREE_TOKEN_VALUE_INT: - return newCodeGeneratorOperand((void *)(uint64_t)(AstTreeU64)tree.metadata, + return newCodeGeneratorOperand((void *)(uint64_t)(AstTreeInt)tree.metadata, false); case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = tree.metadata; @@ -112,7 +112,7 @@ CodeGeneratorOperand *newCodeGeneratorOperandFromAstTree(AstTree tree) { } if (variable->isConst) { return newCodeGeneratorOperand( - (void *)(uint64_t)(AstTreeU64)variable->value->metadata, false); + (void *)(uint64_t)(AstTreeInt)variable->value->metadata, false); } else { char *name = a404m_malloc( (variable->name_end - variable->name_begin + 1) * sizeof(*name)); @@ -217,7 +217,7 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) { case AST_TREE_TOKEN_VALUE_INT: if (!variable->isConst) { CodeGeneratorOperand value = makeCodeGeneratorOperand( - (void *)(uint64_t)(AstTreeU64)variable->value->metadata, false); + (void *)(uint64_t)(AstTreeInt)variable->value->metadata, false); generateCodePushDefine( codes, createGenerateDefine(variable->name_begin, variable->name_end, @@ -281,7 +281,7 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end, AstTreeSingleChild *metadata = tree->metadata; if (metadata->token == AST_TREE_TOKEN_VALUE_INT) { CodeGeneratorOperand *value = newCodeGeneratorOperand( - (void *)(uint64_t)(AstTreeU64)metadata->metadata, false); + (void *)(uint64_t)(AstTreeInt)metadata->metadata, false); generateCodePushCode( codes, createGenerateCode(NULL, NULL, CODE_GENERATOR_INSTRUCTION_PRINT_U64, @@ -290,7 +290,7 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end, AstTreeVariable *variable = metadata->metadata; if (variable->isConst) { CodeGeneratorOperand *value = newCodeGeneratorOperand( - (void *)(uint64_t)(AstTreeU64)variable->value->metadata, false); + (void *)(uint64_t)(AstTreeInt)variable->value->metadata, false); generateCodePushCode( codes, createGenerateCode(NULL, NULL, diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 6b9fb60..7ea8f43 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -43,12 +43,19 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_MULTIPLY", "LEXER_TOKEN_SYMBOL_DIVIDE", "LEXER_TOKEN_SYMBOL_MODULO", + "LEXER_TOKEN_SYMBOL_EQUAL", + "LEXER_TOKEN_SYMBOL_NOT_EQUAL", + "LEXER_TOKEN_SYMBOL_GREATER", + "LEXER_TOKEN_SYMBOL_SMALLER", + "LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL", + "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", "-", "*", "/", "%", + ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", + "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -65,6 +72,12 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_SYMBOL_DIVIDE, LEXER_TOKEN_SYMBOL_MODULO, + LEXER_TOKEN_SYMBOL_EQUAL, + LEXER_TOKEN_SYMBOL_NOT_EQUAL, + LEXER_TOKEN_SYMBOL_GREATER, + LEXER_TOKEN_SYMBOL_SMALLER, + LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -231,6 +244,12 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_MULTIPLY: case LEXER_TOKEN_SYMBOL_DIVIDE: case LEXER_TOKEN_SYMBOL_MODULO: + case LEXER_TOKEN_SYMBOL_EQUAL: + case LEXER_TOKEN_SYMBOL_NOT_EQUAL: + case LEXER_TOKEN_SYMBOL_GREATER: + case LEXER_TOKEN_SYMBOL_SMALLER: + case LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL: + case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: 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 03cbd5f..f432c9d 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -36,6 +36,12 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_SYMBOL_DIVIDE, LEXER_TOKEN_SYMBOL_MODULO, + LEXER_TOKEN_SYMBOL_EQUAL, + LEXER_TOKEN_SYMBOL_NOT_EQUAL, + LEXER_TOKEN_SYMBOL_GREATER, + LEXER_TOKEN_SYMBOL_SMALLER, + LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 55ede12..3b21074 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -88,6 +88,13 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EQUAL, LEXER_TOKEN_SYMBOL_NOT_EQUAL, + LEXER_TOKEN_SYMBOL_GREATER, LEXER_TOKEN_SYMBOL_SMALLER, + LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, ), + }, + { + .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, ), }, { @@ -146,12 +153,12 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_BOOL: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_INT: { - ParserNodeU64Metadata metadata = (ParserNodeU64Metadata)node->metadata; + ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata; printf(",operand=%ld", metadata); } goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_BOOL: { - ParserNodeU64Metadata metadata = (ParserNodeU64Metadata)node->metadata; + ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata; printf(",value=%b", (ParserNodeBoolMetadata)metadata); } goto RETURN_SUCCESS; @@ -272,7 +279,13 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_OPERATOR_SUB: case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: - case PARSER_TOKEN_OPERATOR_MODULO: { + case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { const ParserNodeInfixMetadata *metadata = node->metadata; printf(",\n"); for (int i = 0; i < indent; ++i) @@ -402,7 +415,13 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_OPERATOR_SUB: case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: - case PARSER_TOKEN_OPERATOR_MODULO: { + case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { ParserNodeInfixMetadata *metadata = node->metadata; parserNodeDelete(metadata->left); parserNodeDelete(metadata->right); @@ -572,6 +591,24 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_MODULO: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_MODULO); + case LEXER_TOKEN_SYMBOL_EQUAL: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_EQUAL); + case LEXER_TOKEN_SYMBOL_NOT_EQUAL: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_NOT_EQUAL); + case LEXER_TOKEN_SYMBOL_GREATER: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_GREATER); + case LEXER_TOKEN_SYMBOL_SMALLER: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SMALLER); + case LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL); + case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL); case LEXER_TOKEN_SYMBOL_PLUS: { ParserNode *result = parserBinaryOrLeftOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_PLUS, @@ -738,7 +775,7 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { } parserNode = newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end, - (void *)(ParserNodeU64Metadata)value, parent); + (void *)(ParserNodeIntMetadata)value, parent); } } return node->parserNode = parserNode; @@ -970,6 +1007,12 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end, @@ -1261,6 +1304,12 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_KEYWORD_IF: @@ -1312,6 +1361,12 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_KEYWORD_IF: return false; case PARSER_TOKEN_NONE: @@ -1334,6 +1389,12 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_I64: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 4808032..a5378d7 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -39,6 +39,12 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_MULTIPLY, PARSER_TOKEN_OPERATOR_DIVIDE, PARSER_TOKEN_OPERATOR_MODULO, + PARSER_TOKEN_OPERATOR_EQUAL, + PARSER_TOKEN_OPERATOR_NOT_EQUAL, + PARSER_TOKEN_OPERATOR_GREATER, + PARSER_TOKEN_OPERATOR_SMALLER, + PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL, + PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -92,7 +98,7 @@ typedef struct ParserNodeFunctionCall { typedef ParserNode ParserNodeSingleChildMetadata; -typedef uint64_t ParserNodeU64Metadata; +typedef uint64_t ParserNodeIntMetadata; typedef struct ParserNodeInfixMetadata { ParserNode *left; diff --git a/src/runner/runner.c b/src/runner/runner.c index e3af6fc..d36562a 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -180,7 +180,7 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages) { case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { AstTreeSingleChild *metadata = expr->metadata; AstTree *tree = calcAstTreeValue(metadata, pages); - printf("%lu", (AstTreeU64)tree->metadata); + printf("%lu", (AstTreeInt)tree->metadata); astTreeDelete(tree); } return NULL; @@ -267,6 +267,12 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -307,34 +313,79 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) { 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_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { AstTreeInfix *metadata = tree->metadata; AstTree *left = calcAstTreeValue(&metadata->left, pages); AstTree *right = calcAstTreeValue(&metadata->right, pages); - if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { + if ((left->type == &AST_TREE_U64_TYPE && + right->type == &AST_TREE_U64_TYPE) || + (left->type == &AST_TREE_I64_TYPE && + right->type == &AST_TREE_I64_TYPE)) { if (left->token == AST_TREE_TOKEN_VALUE_INT && right->token == AST_TREE_TOKEN_VALUE_INT) { switch (tree->token) { case AST_TREE_TOKEN_OPERATOR_SUM: - left->metadata = (void *)((AstTreeU64)left->metadata + - (AstTreeU64)right->metadata); + left->metadata = (void *)((AstTreeInt)left->metadata + + (AstTreeInt)right->metadata); break; case AST_TREE_TOKEN_OPERATOR_SUB: - left->metadata = (void *)((AstTreeU64)left->metadata - - (AstTreeU64)right->metadata); + left->metadata = (void *)((AstTreeInt)left->metadata - + (AstTreeInt)right->metadata); break; case AST_TREE_TOKEN_OPERATOR_MULTIPLY: - left->metadata = (void *)((AstTreeU64)left->metadata * - (AstTreeU64)right->metadata); + left->metadata = (void *)((AstTreeInt)left->metadata * + (AstTreeInt)right->metadata); break; case AST_TREE_TOKEN_OPERATOR_DIVIDE: - left->metadata = (void *)((AstTreeU64)left->metadata / - (AstTreeU64)right->metadata); + left->metadata = (void *)((AstTreeInt)left->metadata / + (AstTreeInt)right->metadata); break; case AST_TREE_TOKEN_OPERATOR_MODULO: - left->metadata = (void *)((AstTreeU64)left->metadata % - (AstTreeU64)right->metadata); + left->metadata = (void *)((AstTreeInt)left->metadata % + (AstTreeInt)right->metadata); + break; + case AST_TREE_TOKEN_OPERATOR_EQUAL: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata == + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; + break; + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata == + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; + break; + case AST_TREE_TOKEN_OPERATOR_GREATER: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata > + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; + break; + case AST_TREE_TOKEN_OPERATOR_SMALLER: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata < + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; + break; + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata >= + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; + break; + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + left->metadata = (void *)(bool)((AstTreeInt)left->metadata <= + (AstTreeInt)right->metadata); + astTreeDelete(left->type); + left->type = &AST_TREE_U64_TYPE; break; default: UNREACHABLE; @@ -355,10 +406,10 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) { if (operand->token == AST_TREE_TOKEN_VALUE_INT) { switch (tree->token) { case AST_TREE_TOKEN_OPERATOR_PLUS: - operand->metadata = (void *)(+(AstTreeU64)operand->metadata); + operand->metadata = (void *)(+(AstTreeInt)operand->metadata); break; case AST_TREE_TOKEN_OPERATOR_MINUS: - operand->metadata = (void *)(-(AstTreeU64)operand->metadata); + operand->metadata = (void *)(-(AstTreeInt)operand->metadata); break; default: UNREACHABLE; @@ -378,10 +429,12 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -413,6 +466,15 @@ AstTree *deepCopyAstTree(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_OPERATOR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: + case AST_TREE_TOKEN_OPERATOR_GREATER: + case AST_TREE_TOKEN_OPERATOR_SMALLER: + case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case AST_TREE_TOKEN_KEYWORD_IF: + case AST_TREE_TOKEN_TYPE_I64: + case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: } UNREACHABLE; |