diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/ast-tree.c | 493 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 19 | ||||
-rw-r--r-- | src/compiler/lexer.c | 69 | ||||
-rw-r--r-- | src/compiler/lexer.h | 13 | ||||
-rw-r--r-- | src/compiler/parser.c | 117 | ||||
-rw-r--r-- | src/compiler/parser.h | 12 | ||||
-rw-r--r-- | src/runner/runner.c | 769 |
7 files changed, 1483 insertions, 9 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 2372feb..676fafb 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -123,6 +123,18 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_BUILTIN_IS_COMPTIME", "AST_TREE_TOKEN_BUILTIN_STACK_ALLOC", "AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC", + "AST_TREE_TOKEN_BUILTIN_NEG", + "AST_TREE_TOKEN_BUILTIN_ADD", + "AST_TREE_TOKEN_BUILTIN_SUB", + "AST_TREE_TOKEN_BUILTIN_MUL", + "AST_TREE_TOKEN_BUILTIN_DIV", + "AST_TREE_TOKEN_BUILTIN_MOD", + "AST_TREE_TOKEN_BUILTIN_EQUAL", + "AST_TREE_TOKEN_BUILTIN_NOT_EQUAL", + "AST_TREE_TOKEN_BUILTIN_GREATER", + "AST_TREE_TOKEN_BUILTIN_SMALLER", + "AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL", + "AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL", "AST_TREE_TOKEN_KEYWORD_PUTC", "AST_TREE_TOKEN_KEYWORD_RETURN", @@ -181,6 +193,9 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_ADDRESS", "AST_TREE_TOKEN_OPERATOR_DEREFERENCE", "AST_TREE_TOKEN_OPERATOR_ACCESS", + "AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT", + "AST_TREE_TOKEN_OPERATOR_LOGICAL_AND", + "AST_TREE_TOKEN_OPERATOR_LOGICAL_OR", "AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS", "AST_TREE_TOKEN_SCOPE", @@ -642,6 +657,18 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -921,6 +948,18 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: return newAstTree( tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), @@ -1638,6 +1677,18 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: goto AFTER_SWITCH; @@ -1747,6 +1798,32 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) { return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_STACK_ALLOC); case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC); + case PARSER_TOKEN_BUILTIN_NEG: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_NEG); + case PARSER_TOKEN_BUILTIN_ADD: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_ADD); + case PARSER_TOKEN_BUILTIN_SUB: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SUB); + case PARSER_TOKEN_BUILTIN_MUL: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_MUL); + case PARSER_TOKEN_BUILTIN_DIV: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_DIV); + case PARSER_TOKEN_BUILTIN_MOD: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_MOD); + case PARSER_TOKEN_BUILTIN_EQUAL: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_EQUAL); + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_NOT_EQUAL); + case PARSER_TOKEN_BUILTIN_GREATER: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_GREATER); + case PARSER_TOKEN_BUILTIN_SMALLER: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SMALLER); + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + return astTreeParseKeyword(parserNode, + AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL); + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: + return astTreeParseKeyword(parserNode, + AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL); case PARSER_TOKEN_TYPE_TYPE: return &AST_TREE_TYPE_TYPE; case PARSER_TOKEN_TYPE_FUNCTION: @@ -2069,6 +2146,18 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode, case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -2672,6 +2761,18 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode, case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -2863,6 +2964,18 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -2983,6 +3096,18 @@ bool isConstByValue(AstTree *tree) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -3227,6 +3352,18 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PUTC: @@ -3269,6 +3406,18 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PUTC: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -3418,6 +3567,18 @@ AstTree *getValue(AstTree *tree) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -3527,6 +3688,18 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_KEYWORD_PUTC: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_IF: @@ -3629,6 +3802,18 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_KEYWORD_PUTC: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_IF: @@ -3940,6 +4125,22 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesBuiltinStackAlloc(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: return setTypesBuiltinHeapAlloc(tree, helper, functionCall); + case AST_TREE_TOKEN_BUILTIN_NEG: + return setTypesBuiltinUnary(tree, helper, functionCall); + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + return setTypesBuiltinBinary(tree, helper, functionCall); + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: + return setTypesBuiltinBinaryWithRet(tree, helper, functionCall, + &AST_TREE_BOOL_TYPE); case AST_TREE_TOKEN_TYPE_ARRAY: return setTypesTypeArray(tree, helper); case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: @@ -5067,6 +5268,290 @@ bool setTypesBuiltinHeapAlloc(AstTree *tree, AstTreeSetTypesHelper helper, NOT_IMPLEMENTED; } +bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall) { + (void)helper; + if (functionCall->parameters_size != 1) { + printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); + return false; + } + + char *str = functionCall->parameters[0].nameBegin; + size_t str_size = functionCall->parameters[0].nameEnd - + functionCall->parameters[0].nameBegin; + + static char VALUE_STR[] = "value"; + static size_t VALUE_STR_SIZE = + sizeof(VALUE_STR) / sizeof(*VALUE_STR) - sizeof(*VALUE_STR); + + if (str_size != 0 && (str_size != VALUE_STR_SIZE || + !strnEquals(str, VALUE_STR, VALUE_STR_SIZE))) { + printError(functionCall->parameters[0].nameBegin, + functionCall->parameters[0].nameEnd, "Unknown parameter"); + return false; + } + + AstTree *type = functionCall->parameters[0].value->type; + switch (type->token) { + case AST_TREE_TOKEN_TYPE_I8: + case AST_TREE_TOKEN_TYPE_U8: + case AST_TREE_TOKEN_TYPE_I16: + case AST_TREE_TOKEN_TYPE_U16: + case AST_TREE_TOKEN_TYPE_I32: + case AST_TREE_TOKEN_TYPE_U32: + case AST_TREE_TOKEN_TYPE_I64: + case AST_TREE_TOKEN_TYPE_U64: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: + goto AFTER_SWITCH; + case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_CAST: + case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_IMPORT: + case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: + case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: + case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: + case AST_TREE_TOKEN_KEYWORD_PUTC: + case AST_TREE_TOKEN_KEYWORD_RETURN: + case AST_TREE_TOKEN_KEYWORD_IF: + case AST_TREE_TOKEN_KEYWORD_WHILE: + case AST_TREE_TOKEN_KEYWORD_COMPTIME: + case AST_TREE_TOKEN_KEYWORD_STRUCT: + case AST_TREE_TOKEN_TYPE_FUNCTION: + case AST_TREE_TOKEN_TYPE_ARRAY: + case AST_TREE_TOKEN_TYPE_TYPE: + case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_CODE: + case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_FUNCTION_CALL: + case AST_TREE_TOKEN_VARIABLE: + case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: + case AST_TREE_TOKEN_VALUE_INT: + case AST_TREE_TOKEN_VALUE_FLOAT: + case AST_TREE_TOKEN_VALUE_BOOL: + case AST_TREE_TOKEN_VALUE_OBJECT: + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_PLUS: + case AST_TREE_TOKEN_OPERATOR_MINUS: + 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_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_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: + case AST_TREE_TOKEN_OPERATOR_ACCESS: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: + case AST_TREE_TOKEN_SCOPE: + case AST_TREE_TOKEN_NONE: + } + printError(functionCall->parameters[0].nameBegin, + functionCall->parameters[0].nameEnd, "Bad argument"); + return false; + +AFTER_SWITCH: + AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); + type_metadata->arguments_size = 1; + type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * + sizeof(*type_metadata->arguments)); + + type_metadata->returnType = copyAstTree(type); + + type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(type), + .name_begin = VALUE_STR, + .name_end = VALUE_STR + VALUE_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + }; + + tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, + &AST_TREE_TYPE_TYPE, NULL, NULL); + return true; +} + +bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall) { + (void)helper; + if (functionCall->parameters_size != 2) { + printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); + return false; + } + AstTree *left = NULL; + AstTree *right = NULL; + + static char LEFT_STR[] = "left"; + static const size_t LEFT_STR_SIZE = + sizeof(LEFT_STR) / sizeof(*LEFT_STR) - sizeof(*LEFT_STR); + static char RIGHT_STR[] = "right"; + static const size_t RIGHT_STR_SIZE = + sizeof(RIGHT_STR) / sizeof(*RIGHT_STR) - sizeof(*RIGHT_STR); + + for (size_t i = 0; i < functionCall->parameters_size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters[i]; + const size_t param_name_size = param.nameEnd - param.nameBegin; + + if (param_name_size == 0) { + if (left == NULL) { + left = param.value; + } else if (right == NULL) { + right = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, + "Bad paramter"); + return false; + } + } else if (param_name_size == LEFT_STR_SIZE && + strnEquals(param.nameBegin, LEFT_STR, LEFT_STR_SIZE) && + left == NULL) { + left = param.value; + } else if (param_name_size == RIGHT_STR_SIZE && + strnEquals(param.nameBegin, RIGHT_STR, RIGHT_STR_SIZE) && + right == NULL) { + right = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, "Bad paramter"); + return false; + } + } + + if (left == NULL || right == NULL) { + return false; + } + + AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); + type_metadata->arguments_size = 2; + type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * + sizeof(*type_metadata->arguments)); + + type_metadata->returnType = copyAstTree(left->type); + + type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(left->type), + .name_begin = LEFT_STR, + .name_end = LEFT_STR + LEFT_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + }; + + type_metadata->arguments[1] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(left->type), + .name_begin = RIGHT_STR, + .name_end = RIGHT_STR + RIGHT_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + }; + + tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, + &AST_TREE_TYPE_TYPE, NULL, NULL); + return true; +} + +bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall, + AstTree *retType) { + (void)helper; + if (functionCall->parameters_size != 2) { + printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); + return false; + } + AstTree *left = NULL; + AstTree *right = NULL; + + static char LEFT_STR[] = "left"; + static const size_t LEFT_STR_SIZE = + sizeof(LEFT_STR) / sizeof(*LEFT_STR) - sizeof(*LEFT_STR); + static char RIGHT_STR[] = "right"; + static const size_t RIGHT_STR_SIZE = + sizeof(RIGHT_STR) / sizeof(*RIGHT_STR) - sizeof(*RIGHT_STR); + + for (size_t i = 0; i < functionCall->parameters_size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters[i]; + const size_t param_name_size = param.nameEnd - param.nameBegin; + + if (param_name_size == 0) { + if (left == NULL) { + left = param.value; + } else if (right == NULL) { + right = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, + "Bad paramter"); + return false; + } + } else if (param_name_size == LEFT_STR_SIZE && + strnEquals(param.nameBegin, LEFT_STR, LEFT_STR_SIZE) && + left == NULL) { + left = param.value; + } else if (param_name_size == RIGHT_STR_SIZE && + strnEquals(param.nameBegin, RIGHT_STR, RIGHT_STR_SIZE) && + right == NULL) { + right = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, "Bad paramter"); + return false; + } + } + + if (left == NULL || right == NULL) { + return false; + } + + AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); + type_metadata->arguments_size = 2; + type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * + sizeof(*type_metadata->arguments)); + + type_metadata->returnType = copyAstTree(retType); + + type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(left->type), + .name_begin = LEFT_STR, + .name_end = LEFT_STR + LEFT_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + }; + + type_metadata->arguments[1] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(left->type), + .name_begin = RIGHT_STR, + .name_end = RIGHT_STR + RIGHT_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + }; + + tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, + &AST_TREE_TYPE_TYPE, NULL, NULL); + return true; +} + bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeBracket *metadata = tree->metadata; @@ -5262,13 +5747,19 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin, } } if (variable != NULL) { - printError(name_begin, name_end, "Multiple candidates found"); + printError(name_begin, name_end, "Multiple candidates found for %.*s", + (int)(name_end - name_begin), name_begin); return NULL; } variable = var; CONTINUE_OUTER: } } + if (variable == NULL) { + printError(name_begin, name_end, "No candidates found for %.*s", + (int)(name_end - name_begin), name_begin); + return NULL; + } return variable; } diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index b454217..74aa027 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -12,6 +12,18 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_BUILTIN_IS_COMPTIME, AST_TREE_TOKEN_BUILTIN_STACK_ALLOC, AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC, + AST_TREE_TOKEN_BUILTIN_NEG, + AST_TREE_TOKEN_BUILTIN_ADD, + AST_TREE_TOKEN_BUILTIN_SUB, + AST_TREE_TOKEN_BUILTIN_MUL, + AST_TREE_TOKEN_BUILTIN_DIV, + AST_TREE_TOKEN_BUILTIN_MOD, + AST_TREE_TOKEN_BUILTIN_EQUAL, + AST_TREE_TOKEN_BUILTIN_NOT_EQUAL, + AST_TREE_TOKEN_BUILTIN_GREATER, + AST_TREE_TOKEN_BUILTIN_SMALLER, + AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL, + AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL, AST_TREE_TOKEN_KEYWORD_PUTC, AST_TREE_TOKEN_KEYWORD_RETURN, @@ -411,6 +423,13 @@ bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall); bool setTypesBuiltinHeapAlloc(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall); +bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall); +bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall); +bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall, + AstTree *retType); bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper helper); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 651f1df..b28bd48 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -10,12 +10,25 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS", "LEXER_TOKEN_SYMBOL_CLOSE_BRACKET", "LEXER_TOKEN_IDENTIFIER", + "LEXER_TOKEN_BUILTIN", "LEXER_TOKEN_BUILTIN_CAST", "LEXER_TOKEN_BUILTIN_TYPE_OF", "LEXER_TOKEN_BUILTIN_IMPORT", "LEXER_TOKEN_BUILTIN_IS_COMPTIME", "LEXER_TOKEN_BUILTIN_STACK_ALLOC", "LEXER_TOKEN_BUILTIN_HEAP_ALLOC", + "LEXER_TOKEN_BUILTIN_NEG", + "LEXER_TOKEN_BUILTIN_ADD", + "LEXER_TOKEN_BUILTIN_SUB", + "LEXER_TOKEN_BUILTIN_MUL", + "LEXER_TOKEN_BUILTIN_DIV", + "LEXER_TOKEN_BUILTIN_MOD", + "LEXER_TOKEN_BUILTIN_EQUAL", + "LEXER_TOKEN_BUILTIN_NOT_EQUAL", + "LEXER_TOKEN_BUILTIN_GREATER", + "LEXER_TOKEN_BUILTIN_SMALLER", + "LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL", + "LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL", "LEXER_TOKEN_KEYWORD_TYPE", "LEXER_TOKEN_KEYWORD_VOID", "LEXER_TOKEN_KEYWORD_I8", @@ -175,13 +188,45 @@ static const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); static const char *LEXER_BUILTIN_STRINGS[] = { - "cast", "typeOf", "import", "isComptime", "stackAlloc", "heapAlloc", + "cast", + "typeOf", + "import", + "isComptime", + "stackAlloc", + "heapAlloc", + "neg", + "add", + "sub", + "mul", + "div", + "mod", + "equal", + "notEqual", + "greater", + "smaller", + "greaterOrEqual", + "smallerOrEqual", }; static const LexerToken LEXER_BUILTIN_TOKENS[] = { - LEXER_TOKEN_BUILTIN_CAST, LEXER_TOKEN_BUILTIN_TYPE_OF, - LEXER_TOKEN_BUILTIN_IMPORT, LEXER_TOKEN_BUILTIN_IS_COMPTIME, - LEXER_TOKEN_BUILTIN_STACK_ALLOC, LEXER_TOKEN_BUILTIN_HEAP_ALLOC, + LEXER_TOKEN_BUILTIN_CAST, + LEXER_TOKEN_BUILTIN_TYPE_OF, + LEXER_TOKEN_BUILTIN_IMPORT, + LEXER_TOKEN_BUILTIN_IS_COMPTIME, + LEXER_TOKEN_BUILTIN_STACK_ALLOC, + LEXER_TOKEN_BUILTIN_HEAP_ALLOC, + LEXER_TOKEN_BUILTIN_NEG, + LEXER_TOKEN_BUILTIN_ADD, + LEXER_TOKEN_BUILTIN_SUB, + LEXER_TOKEN_BUILTIN_MUL, + LEXER_TOKEN_BUILTIN_DIV, + LEXER_TOKEN_BUILTIN_MOD, + LEXER_TOKEN_BUILTIN_EQUAL, + LEXER_TOKEN_BUILTIN_NOT_EQUAL, + LEXER_TOKEN_BUILTIN_GREATER, + LEXER_TOKEN_BUILTIN_SMALLER, + LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL, + LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL, }; static const size_t LEXER_BUILTIN_SIZE = sizeof(LEXER_BUILTIN_TOKENS) / sizeof(*LEXER_BUILTIN_TOKENS); @@ -319,6 +364,10 @@ LexerNodeArray lexer(char *str) { RETURN_SUCCESS: result.data = a404m_realloc(result.data, result.size * sizeof(*result.data)); +#ifdef PRINT_COMPILE_TREE + lexerNodeArrayPrint(result); +#endif + return result; } @@ -430,6 +479,18 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_BUILTIN_IS_COMPTIME: case LEXER_TOKEN_BUILTIN_STACK_ALLOC: case LEXER_TOKEN_BUILTIN_HEAP_ALLOC: + case LEXER_TOKEN_BUILTIN_NEG: + case LEXER_TOKEN_BUILTIN_ADD: + case LEXER_TOKEN_BUILTIN_SUB: + case LEXER_TOKEN_BUILTIN_MUL: + case LEXER_TOKEN_BUILTIN_DIV: + case LEXER_TOKEN_BUILTIN_MOD: + case LEXER_TOKEN_BUILTIN_EQUAL: + case LEXER_TOKEN_BUILTIN_NOT_EQUAL: + case LEXER_TOKEN_BUILTIN_GREATER: + case LEXER_TOKEN_BUILTIN_SMALLER: + case LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET: case LEXER_TOKEN_SYMBOL_OPEN_BRACKET: if (*array_size == array->size) { diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 91eff63..7f52eaf 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -2,6 +2,7 @@ #include "utils/type.h" #include <stddef.h> +#include <stdio.h> typedef enum LexerToken { LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET, @@ -19,6 +20,18 @@ typedef enum LexerToken { LEXER_TOKEN_BUILTIN_IS_COMPTIME, LEXER_TOKEN_BUILTIN_STACK_ALLOC, LEXER_TOKEN_BUILTIN_HEAP_ALLOC, + LEXER_TOKEN_BUILTIN_NEG, + LEXER_TOKEN_BUILTIN_ADD, + LEXER_TOKEN_BUILTIN_SUB, + LEXER_TOKEN_BUILTIN_MUL, + LEXER_TOKEN_BUILTIN_DIV, + LEXER_TOKEN_BUILTIN_MOD, + LEXER_TOKEN_BUILTIN_EQUAL, + LEXER_TOKEN_BUILTIN_NOT_EQUAL, + LEXER_TOKEN_BUILTIN_GREATER, + LEXER_TOKEN_BUILTIN_SMALLER, + LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL, + LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL, LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_I8, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 8ca259f..6e8283a 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -18,6 +18,18 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_BUILTIN_IS_COMPTIME", "PARSER_TOKEN_BUILTIN_STACK_ALLOC", "PARSER_TOKEN_BUILTIN_HEAP_ALLOC", + "PARSER_TOKEN_BUILTIN_NEG", + "PARSER_TOKEN_BUILTIN_ADD", + "PARSER_TOKEN_BUILTIN_SUB", + "PARSER_TOKEN_BUILTIN_MUL", + "PARSER_TOKEN_BUILTIN_DIV", + "PARSER_TOKEN_BUILTIN_MOD", + "PARSER_TOKEN_BUILTIN_EQUAL", + "PARSER_TOKEN_BUILTIN_NOT_EQUAL", + "PARSER_TOKEN_BUILTIN_GREATER", + "PARSER_TOKEN_BUILTIN_SMALLER", + "PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL", + "PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL", "PARSER_TOKEN_VALUE_INT", "PARSER_TOKEN_VALUE_FLOAT", @@ -232,6 +244,18 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -521,6 +545,18 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -717,6 +753,9 @@ ParserNode *parserFromPath(const char *filePath ParserNode *parser(LexerNodeArray lexed) { ParserNode *root = newParserNode(PARSER_TOKEN_ROOT, NULL, NULL, NULL, NULL); if (parserNodeArray(lexed.data, lexed.data + lexed.size, root)) { +#ifdef PRINT_COMPILE_TREE + parserNodePrint(root, 0); +#endif return root; } else { free(root); @@ -811,6 +850,32 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_STACK_ALLOC); case LEXER_TOKEN_BUILTIN_HEAP_ALLOC: return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_HEAP_ALLOC); + case LEXER_TOKEN_BUILTIN_NEG: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_NEG); + case LEXER_TOKEN_BUILTIN_ADD: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_ADD); + case LEXER_TOKEN_BUILTIN_SUB: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SUB); + case LEXER_TOKEN_BUILTIN_MUL: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_MUL); + case LEXER_TOKEN_BUILTIN_DIV: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_DIV); + case LEXER_TOKEN_BUILTIN_MOD: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_MOD); + case LEXER_TOKEN_BUILTIN_EQUAL: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_EQUAL); + case LEXER_TOKEN_BUILTIN_NOT_EQUAL: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_NOT_EQUAL); + case LEXER_TOKEN_BUILTIN_GREATER: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_GREATER); + case LEXER_TOKEN_BUILTIN_SMALLER: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SMALLER); + case LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + return parserNoMetadata(node, parent, + PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL); + case LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: + return parserNoMetadata(node, parent, + PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL); case LEXER_TOKEN_KEYWORD_TYPE: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE); case LEXER_TOKEN_KEYWORD_VOID: @@ -1547,8 +1612,20 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_BUILTIN_TYPE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: - case PARSER_TOKEN_BUILTIN_STACK_ALLOC: - case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_STACK_ALLOC: + case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2015,6 +2092,18 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_PARENTHESIS: @@ -2130,6 +2219,18 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: @@ -2192,6 +2293,18 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index ac729f9..b34b82f 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -15,6 +15,18 @@ typedef enum ParserToken { PARSER_TOKEN_BUILTIN_IS_COMPTIME, PARSER_TOKEN_BUILTIN_STACK_ALLOC, PARSER_TOKEN_BUILTIN_HEAP_ALLOC, + PARSER_TOKEN_BUILTIN_NEG, + PARSER_TOKEN_BUILTIN_ADD, + PARSER_TOKEN_BUILTIN_SUB, + PARSER_TOKEN_BUILTIN_MUL, + PARSER_TOKEN_BUILTIN_DIV, + PARSER_TOKEN_BUILTIN_MOD, + PARSER_TOKEN_BUILTIN_EQUAL, + PARSER_TOKEN_BUILTIN_NOT_EQUAL, + PARSER_TOKEN_BUILTIN_GREATER, + PARSER_TOKEN_BUILTIN_SMALLER, + PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL, + PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL, PARSER_TOKEN_VALUE_INT, PARSER_TOKEN_VALUE_FLOAT, diff --git a/src/runner/runner.c b/src/runner/runner.c index dc3e655..e334cf1 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -3,6 +3,7 @@ #include "utils/log.h" #include "utils/memory.h" #include "utils/string.h" +#include <math.h> #include <stdatomic.h> #include <stdio.h> @@ -381,10 +382,750 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope, ret = copyAstTree(variable->type); } goto RETURN; + case AST_TREE_TOKEN_BUILTIN_NEG: { + AstTree *value = args.data[0]; + bool shouldRet = false; + ret = runExpression(value, scope, &shouldRet, false, isComptime); + switch (value->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = -*(i8 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = -*(u8 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = -*(i16 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = -*(u16 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = -*(i32 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = -*(u32 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = -*(i64 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = -*(u64 *)ret->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = -*(f16 *)ret->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = -*(f32 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = -*(f64 *)ret->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = -*(f128 *)ret->metadata; + break; + default: + UNREACHABLE; + } + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_ADD: { + bool shouldRet = false; + ret = runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + switch (ret->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = *(i8 *)ret->metadata + *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = *(u8 *)ret->metadata + *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = *(i16 *)ret->metadata + *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = *(u16 *)ret->metadata + *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = *(i32 *)ret->metadata + *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = *(u32 *)ret->metadata + *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = *(i64 *)ret->metadata + *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = *(u64 *)ret->metadata + *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = *(f16 *)ret->metadata + *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = *(f32 *)ret->metadata + *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = *(f64 *)ret->metadata + *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = + *(f128 *)ret->metadata + *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_SUB: { + bool shouldRet = false; + ret = runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + switch (ret->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = *(i8 *)ret->metadata - *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = *(u8 *)ret->metadata - *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = *(i16 *)ret->metadata - *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = *(u16 *)ret->metadata - *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = *(i32 *)ret->metadata - *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = *(u32 *)ret->metadata - *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = *(i64 *)ret->metadata - *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = *(u64 *)ret->metadata - *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = *(f16 *)ret->metadata - *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = *(f32 *)ret->metadata - *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = *(f64 *)ret->metadata - *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = + *(f128 *)ret->metadata - *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_MUL: { + bool shouldRet = false; + ret = runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + switch (ret->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = *(i8 *)ret->metadata * *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = *(u8 *)ret->metadata * *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = *(i16 *)ret->metadata * *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = *(u16 *)ret->metadata * *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = *(i32 *)ret->metadata * *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = *(u32 *)ret->metadata * *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = *(i64 *)ret->metadata * *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = *(u64 *)ret->metadata * *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = *(f16 *)ret->metadata * *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = *(f32 *)ret->metadata * *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = *(f64 *)ret->metadata * *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = + *(f128 *)ret->metadata * *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_DIV: { + bool shouldRet = false; + ret = runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + switch (ret->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = *(i8 *)ret->metadata / *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = *(u8 *)ret->metadata / *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = *(i16 *)ret->metadata / *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = *(u16 *)ret->metadata / *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = *(i32 *)ret->metadata / *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = *(u32 *)ret->metadata / *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = *(i64 *)ret->metadata / *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = *(u64 *)ret->metadata / *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = *(f16 *)ret->metadata / *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = *(f32 *)ret->metadata / *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = *(f64 *)ret->metadata / *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = + *(f128 *)ret->metadata / *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_MOD: { + bool shouldRet = false; + ret = runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + switch (ret->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret->metadata = *(i8 *)ret->metadata % *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret->metadata = *(u8 *)ret->metadata % *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret->metadata = *(i16 *)ret->metadata % *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret->metadata = *(u16 *)ret->metadata % *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret->metadata = *(i32 *)ret->metadata % *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret->metadata = *(u32 *)ret->metadata % *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret->metadata = *(i64 *)ret->metadata % *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret->metadata = *(u64 *)ret->metadata % *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(f16 *)ret->metadata = + fmodf(*(f16 *)ret->metadata, *(f16 *)right->metadata); + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(f32 *)ret->metadata = + fmodf(*(f32 *)ret->metadata, *(f32 *)right->metadata); + break; + case AST_TREE_TOKEN_TYPE_F64: + *(f64 *)ret->metadata = + fmod(*(f64 *)ret->metadata, *(f64 *)right->metadata); + break; + case AST_TREE_TOKEN_TYPE_F128: + *(f128 *)ret->metadata = + fmodl(*(f128 *)ret->metadata, *(f128 *)right->metadata); + break; + default: + UNREACHABLE; + } + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_EQUAL: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata == *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata == *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata == *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata == *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata == *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata == *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata == *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata == *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata == *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata == *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata == *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata == *(f128 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_BOOL: + *(AstTreeBool *)ret->metadata = + *(AstTreeBool *)left->metadata == *(AstTreeBool *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata != *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata != *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata != *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata != *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata != *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata != *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata != *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata != *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata != *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata != *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata != *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata != *(f128 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_BOOL: + *(AstTreeBool *)ret->metadata = + *(AstTreeBool *)left->metadata == *(AstTreeBool *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_GREATER: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata > *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata > *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata > *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata > *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata > *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata > *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata > *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata > *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata > *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata > *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata > *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata > *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_SMALLER: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata < *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata < *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata < *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata < *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata < *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata < *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata < *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata < *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata < *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata < *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata < *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata < *(f128 *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata >= *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata >= *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata >= *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata >= *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata >= *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata >= *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata >= *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata >= *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata >= *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata >= *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata >= *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata >= *(f128 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_BOOL: + *(AstTreeBool *)ret->metadata = + *(AstTreeBool *)left->metadata == *(AstTreeBool *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: { + bool shouldRet = false; + AstTree *left = + runExpression(args.data[0], scope, &shouldRet, false, isComptime); + AstTree *right = + runExpression(args.data[1], scope, &shouldRet, false, isComptime); + + ret = + newAstTree(AST_TREE_TOKEN_VALUE_BOOL, a404m_malloc(sizeof(AstTreeBool)), + &AST_TREE_BOOL_TYPE, NULL, NULL); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(AstTreeBool *)ret->metadata = + *(i8 *)left->metadata <= *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(AstTreeBool *)ret->metadata = + *(u8 *)left->metadata <= *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(AstTreeBool *)ret->metadata = + *(i16 *)left->metadata <= *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(AstTreeBool *)ret->metadata = + *(u16 *)left->metadata <= *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(AstTreeBool *)ret->metadata = + *(i32 *)left->metadata <= *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(AstTreeBool *)ret->metadata = + *(u32 *)left->metadata <= *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(AstTreeBool *)ret->metadata = + *(i64 *)left->metadata <= *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(AstTreeBool *)ret->metadata = + *(u64 *)left->metadata <= *(u64 *)right->metadata; + break; +#ifdef FLOAT_16_SUPPORT + case AST_TREE_TOKEN_TYPE_F16: + *(AstTreeBool *)ret->metadata = + *(f16 *)left->metadata <= *(f16 *)right->metadata; + break; +#endif + case AST_TREE_TOKEN_TYPE_F32: + *(AstTreeBool *)ret->metadata = + *(f32 *)left->metadata <= *(f32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F64: + *(AstTreeBool *)ret->metadata = + *(f64 *)left->metadata <= *(f64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_F128: + *(AstTreeBool *)ret->metadata = + *(f128 *)left->metadata <= *(f128 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_BOOL: + *(AstTreeBool *)ret->metadata = + *(AstTreeBool *)left->metadata == *(AstTreeBool *)right->metadata; + break; + default: + UNREACHABLE; + } + astTreeDelete(left); + astTreeDelete(right); + } + goto RETURN; case AST_TREE_TOKEN_BUILTIN_IMPORT: default: } - printLog("Bad builtin"); UNREACHABLE; RETURN: @@ -417,7 +1158,19 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, metadata->parameters_size, isComptime); } else if (function->token == AST_TREE_TOKEN_BUILTIN_CAST || function->token == AST_TREE_TOKEN_BUILTIN_TYPE_OF || - function->token == AST_TREE_TOKEN_BUILTIN_IMPORT) { + function->token == AST_TREE_TOKEN_BUILTIN_IMPORT || + function->token == AST_TREE_TOKEN_BUILTIN_NEG || + function->token == AST_TREE_TOKEN_BUILTIN_ADD || + function->token == AST_TREE_TOKEN_BUILTIN_SUB || + function->token == AST_TREE_TOKEN_BUILTIN_MUL || + function->token == AST_TREE_TOKEN_BUILTIN_DIV || + function->token == AST_TREE_TOKEN_BUILTIN_MOD || + function->token == AST_TREE_TOKEN_BUILTIN_EQUAL || + function->token == AST_TREE_TOKEN_BUILTIN_NOT_EQUAL || + function->token == AST_TREE_TOKEN_BUILTIN_GREATER || + function->token == AST_TREE_TOKEN_BUILTIN_SMALLER || + function->token == AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL || + function->token == AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL) { result = runAstTreeBuiltin(function, scope, metadata->parameters, metadata->parameters_size, isComptime); } else { @@ -590,6 +1343,18 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: + case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_ADD: + case AST_TREE_TOKEN_BUILTIN_SUB: + case AST_TREE_TOKEN_BUILTIN_MUL: + case AST_TREE_TOKEN_BUILTIN_DIV: + case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_EQUAL: + case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: + case AST_TREE_TOKEN_BUILTIN_GREATER: + case AST_TREE_TOKEN_BUILTIN_SMALLER: + case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: return copyAstTree(expr); case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: { AstTreeBool *metadata = a404m_malloc(sizeof(*metadata)); |