diff options
-rw-r--r-- | code/main.felan | 22 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 69 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 2 | ||||
-rw-r--r-- | src/compiler/lexer.c | 35 | ||||
-rw-r--r-- | src/compiler/lexer.h | 3 | ||||
-rw-r--r-- | src/compiler/parser.c | 38 | ||||
-rw-r--r-- | src/compiler/parser.h | 3 | ||||
-rw-r--r-- | src/runner/runner.c | 37 |
8 files changed, 166 insertions, 43 deletions
diff --git a/code/main.felan b/code/main.felan index 72c9826..c994d63 100644 --- a/code/main.felan +++ b/code/main.felan @@ -1,14 +1,12 @@ main :: () -> void { - a :u64= 2; - f(a); -}; - -f :: (a: u64)->u64{ - b :u64= 1; - print_u64 b; - if a == 0 - b = 2; - else - f(a-1); - print_u64 b; + a :u64= 1; + b :*u64 = &a; + print_u64 b.*; + print_u64 a; + b.* = 2; + print_u64 b.*; + print_u64 a; + a = 3; + print_u64 b.*; + print_u64 a; }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 4190679..71429f1 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -155,6 +155,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL", "AST_TREE_TOKEN_OPERATOR_POINTER", "AST_TREE_TOKEN_OPERATOR_ADDRESS", + "AST_TREE_TOKEN_OPERATOR_DEREFERENCE", "AST_TREE_TOKEN_SCOPE", @@ -224,6 +225,7 @@ void astTreePrint(const AstTree *tree, int indent) { goto RETURN_SUCCESS; case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -466,6 +468,7 @@ void astTreeDestroy(AstTree tree) { } case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -753,6 +756,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], } case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -867,7 +871,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], } case AST_TREE_TOKEN_NONE: } - printLog("Bad token %ld", tree->token); + printLog("Bad token %d", tree->token); UNREACHABLE; } @@ -880,16 +884,28 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables, .size = variables.size, }; + size_t new_variables_size = variables_size + 1; + AstTreeVariables new_oldVariables[new_variables_size]; + AstTreeVariables new_newVariables[new_variables_size]; + for (size_t i = 0; i < variables_size; ++i) { + new_oldVariables[i] = oldVariables[i]; + new_newVariables[i] = newVariables[i]; + } + new_oldVariables[new_variables_size - 1] = variables; + new_newVariables[new_variables_size - 1] = result; + for (size_t i = 0; i < result.size; ++i) { result.data[i] = a404m_malloc(sizeof(*result.data[i])); if (variables.data[i]->value != NULL) { - result.data[i]->value = copyAstTreeBack( - variables.data[i]->value, oldVariables, newVariables, variables_size); + result.data[i]->value = + copyAstTreeBack(variables.data[i]->value, new_oldVariables, + new_newVariables, new_variables_size); } else { result.data[i]->value = NULL; } - result.data[i]->type = copyAstTreeBack( - variables.data[i]->type, oldVariables, newVariables, variables_size); + result.data[i]->type = + copyAstTreeBack(variables.data[i]->type, new_oldVariables, + new_newVariables, new_variables_size); result.data[i]->isConst = variables.data[i]->isConst; result.data[i]->name_begin = variables.data[i]->name_begin; result.data[i]->name_end = variables.data[i]->name_end; @@ -1022,6 +1038,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: goto AFTER_SWITCH; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -1266,6 +1283,9 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_ADDRESS: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_ADDRESS); + case PARSER_TOKEN_OPERATOR_DEREFERENCE: + return astTreeParseUnaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_DEREFERENCE); case PARSER_TOKEN_VARIABLE: return astTreeParseVariable(parserNode, helper); case PARSER_TOKEN_KEYWORD_IF: @@ -1423,6 +1443,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1947,6 +1968,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -2044,6 +2066,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_OPERATOR_SUM: @@ -2134,6 +2157,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { AstTreeVariable *metadata = tree->metadata; return metadata->isConst; } + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_POINTER: { AstTreeSingleChild *metadata = tree->metadata; @@ -2169,6 +2193,17 @@ AstTree *makeTypeOf(AstTree *value) { return newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, makeTypeOf(metadata), &AST_TREE_TYPE_TYPE, value->str_begin, value->str_end); } + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: { + AstTreeSingleChild *metadata = value->metadata; + AstTree *type = makeTypeOf(metadata); + if (type->token != AST_TREE_TOKEN_OPERATOR_POINTER) { + UNREACHABLE; + } + AstTree *ret = type->metadata; + astTreeDelete(type->type); + astTreeDelete(type->metadata); + return ret; + } case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = value->metadata; AstTreeFunction *function = metadata->function->metadata; @@ -2267,6 +2302,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_SCOPE: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: return false; case AST_TREE_TOKEN_TYPE_TYPE: @@ -2369,12 +2405,13 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { 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_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_SCOPE: { bool shouldRet = false; - AstTree *value = runExpression(tree, &shouldRet); + AstTree *value = runExpression(tree, &shouldRet); if (value == NULL) { printError(tree->str_begin, tree->str_end, "Unknown error"); } @@ -2431,6 +2468,7 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, return false; case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { @@ -2623,6 +2661,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesOperatorPointer(tree, helper); case AST_TREE_TOKEN_OPERATOR_ADDRESS: return setTypesOperatorAddress(tree, helper); + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: + return setTypesOperatorDereference(tree, helper); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree, helper); case AST_TREE_TOKEN_KEYWORD_IF: @@ -2988,6 +3028,7 @@ bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeInfix *infix = tree->metadata; + // TODO: check left one for being left value if (!setTypesAstInfix(infix, helper)) { return false; } else if (!typeIsEqual(infix->left.type, infix->right.type)) { @@ -3070,6 +3111,22 @@ bool setTypesOperatorAddress(AstTree *tree, AstTreeSetTypesHelper helper) { return true; } +bool setTypesOperatorDereference(AstTree *tree, AstTreeSetTypesHelper helper) { + AstTreeSingleChild *metadata = tree->metadata; + if (!setAllTypes(metadata, helper, NULL)) { + return false; + } + + if (metadata->type->token != AST_TREE_TOKEN_OPERATOR_POINTER) { + printError(tree->str_begin, tree->str_end, + "Can only dereferenece pointers"); + return false; + } + + tree->type = copyAstTree(metadata->type->metadata); + return true; +} + bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeVariable *metadata = tree->metadata; tree->type = &AST_TREE_VOID_TYPE; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 87d5c93..6ce8c64 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -57,6 +57,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL, AST_TREE_TOKEN_OPERATOR_POINTER, AST_TREE_TOKEN_OPERATOR_ADDRESS, + AST_TREE_TOKEN_OPERATOR_DEREFERENCE, AST_TREE_TOKEN_SCOPE, @@ -267,6 +268,7 @@ bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorAddress(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorDereference(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 905186a..75fb04b 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -69,13 +69,14 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_POINTER", "LEXER_TOKEN_SYMBOL_ADDRESS", + "LEXER_TOKEN_SYMBOL_DEREFERENCE", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", - ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", + ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", ",", + "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", ".*", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -104,6 +105,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_SMALLER, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_SYMBOL_ADDRESS, + LEXER_TOKEN_SYMBOL_DEREFERENCE, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -195,20 +197,21 @@ LexerNodeArray lexer(char *str) { if (isSpace(c)) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_NONE); - } else if (isIdentifier(c)) { + } else if (isIdentifier(c) || + (node_token == LEXER_TOKEN_IDENTIFIER && isNumber(c))) { if (node_token != LEXER_TOKEN_IDENTIFIER && node_token != LEXER_TOKEN_NUMBER) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_IDENTIFIER); } - } else if (isNumber(c)) { - if (node_token != LEXER_TOKEN_IDENTIFIER && - node_token != LEXER_TOKEN_NUMBER) { + } else if (isNumber(c) || (node_token == LEXER_TOKEN_NUMBER && c == '.')) { + if (node_token != LEXER_TOKEN_NUMBER) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_NUMBER); } - } else if (isSymbol(c) || isSingleSymbol(c)) { - if (node_token != LEXER_TOKEN_SYMBOL || isSingleSymbol(*node_str_begin)) { + } else if (isSymbol(c)) { + if (node_token != LEXER_TOKEN_SYMBOL || + !isCompleteSymbol(node_str_begin, iter - node_str_begin + 1)) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_SYMBOL); } @@ -308,6 +311,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: case LEXER_TOKEN_SYMBOL_POINTER: case LEXER_TOKEN_SYMBOL_ADDRESS: + case LEXER_TOKEN_SYMBOL_DEREFERENCE: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = @@ -336,7 +340,7 @@ bool isIdentifier(char c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_'; } -bool isNumber(char c) { return ('0' <= c && c <= '9') || c == '.'; } +bool isNumber(char c) { return '0' <= c && c <= '9'; } bool isSymbol(char c) { switch (c) { @@ -351,14 +355,6 @@ bool isSymbol(char c) { case '=': case '!': case '&': - return true; - default: - return false; - } -} - -bool isSingleSymbol(char c) { - switch (c) { case ';': case ':': case ',': @@ -372,4 +368,9 @@ bool isSingleSymbol(char c) { } } +bool isCompleteSymbol(char *str, size_t str_size) { + return searchInStringArray(LEXER_SYMBOL_STRINGS, LEXER_SYMBOL_SIZE, str, + str_size) != LEXER_SYMBOL_SIZE; +} + bool isSpace(char c) { return isspace(c); } diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 1ebe405..5e2496b 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -62,6 +62,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_SYMBOL_ADDRESS, + LEXER_TOKEN_SYMBOL_DEREFERENCE, LEXER_TOKEN_NONE, } LexerToken; @@ -105,5 +106,5 @@ extern void lexerPushClear(LexerNodeArray *array, size_t *array_size, extern bool isIdentifier(char c); extern bool isNumber(char c); extern bool isSymbol(char c); -extern bool isSingleSymbol(char c); +extern bool isCompleteSymbol(char *str, size_t str_size); extern bool isSpace(char c); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index fa6e17c..17d596b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -71,6 +71,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL", "PARSER_TOKEN_OPERATOR_POINTER", "PARSER_TOKEN_OPERATOR_ADDRESS", + "PARSER_TOKEN_OPERATOR_DEREFERENCE", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -108,6 +109,10 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_DEREFERENCE, ), + }, + { + .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_SYMBOL_ADDRESS, ), }, @@ -241,6 +246,7 @@ void parserNodePrint(const ParserNode *node, int indent) { goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -468,6 +474,7 @@ void parserNodeDelete(ParserNode *node) { goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -787,6 +794,12 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, *conti = result == NULL; return result; } + case LEXER_TOKEN_SYMBOL_DEREFERENCE: { + ParserNode *result = parserRightOperator(node, begin, parent, + PARSER_TOKEN_OPERATOR_DEREFERENCE); + *conti = result == NULL; + return result; + } case LEXER_TOKEN_KEYWORD_IF: return parserIf(node, end, parent); case LEXER_TOKEN_KEYWORD_WHILE: @@ -1198,6 +1211,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1436,6 +1450,27 @@ ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, (ParserNodeSingleChildMetadata *)right, parent); } +ParserNode *parserRightOperator(LexerNode *node, LexerNode *begin, + ParserNode *parent, ParserToken token) { + LexerNode *leftNode = node - 1; + + if (leftNode < begin || leftNode->parserNode == NULL) { + printError(node->str_begin, node->str_end, "No operand found"); + return NULL; + } + + ParserNode *left = getUntilCommonParent(leftNode->parserNode, parent); + + if (left == NULL) { + printError(node->str_begin, node->str_end, "No operand found"); + return NULL; + } + + return left->parent = node->parserNode = + newParserNode(token, node->str_begin, left->str_end, + (ParserNodeSingleChildMetadata *)left, parent); +} + ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent) { LexerNode *conditionNode = node + 1; if (conditionNode >= end) { @@ -1578,6 +1613,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1670,6 +1706,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN: case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1706,6 +1743,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: + case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index b888dae..e566696 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -67,6 +67,7 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL, PARSER_TOKEN_OPERATOR_POINTER, PARSER_TOKEN_OPERATOR_ADDRESS, + PARSER_TOKEN_OPERATOR_DEREFERENCE, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -191,6 +192,8 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerToken laterToken); ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, ParserNode *parent, ParserToken token); +ParserNode *parserRightOperator(LexerNode *node, LexerNode *begin, + ParserNode *parent, ParserToken token); ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserWhile(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserComptime(LexerNode *node, LexerNode *end, ParserNode *parent); diff --git a/src/runner/runner.c b/src/runner/runner.c index 1c9ef07..efb91ee 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -44,6 +44,9 @@ (type) * (originalType *)(op0)->metadata) void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value) { + if (variable->isConst) { + UNREACHABLE; + } if (variable->value != NULL) { astTreeDelete(variable->value); } @@ -179,13 +182,21 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_ASSIGN: { AstTreeInfix *metadata = expr->metadata; + AstTreeVariable *left; if (metadata->left.token == AST_TREE_TOKEN_VARIABLE) { - AstTreeVariable *left = metadata->left.metadata; - runnerVariableSetValue(left, runExpression(&metadata->right, shouldRet)); - return copyAstTree(left->value); + left = metadata->left.metadata; + } else if (metadata->left.token == AST_TREE_TOKEN_OPERATOR_DEREFERENCE) { + AstTree *left_metadata = metadata->left.metadata; + if (left_metadata->token != AST_TREE_TOKEN_VARIABLE) { + UNREACHABLE; + } + left = left_metadata->metadata; + left = left->value->metadata; } else { UNREACHABLE; } + runnerVariableSetValue(left, runExpression(&metadata->right, shouldRet)); + return copyAstTree(left->value); } case AST_TREE_TOKEN_KEYWORD_RETURN: { AstTreeReturn *metadata = expr->metadata; @@ -849,13 +860,25 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { return copyAstTree(expr); case AST_TREE_TOKEN_OPERATOR_ADDRESS: { AstTreeSingleChild *metadata = expr->metadata; - return newAstTree(AST_TREE_TOKEN_VARIABLE, metadata->metadata, - copyAstTree(expr->type), expr->str_begin, expr->str_end); + if (metadata->token != AST_TREE_TOKEN_VARIABLE) { + UNREACHABLE; + } + return copyAstTree(metadata); + } + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: { + AstTreeSingleChild *metadata = expr->metadata; + AstTree *operand = runExpression(metadata, shouldRet); + if (metadata->token != AST_TREE_TOKEN_VARIABLE) { + UNREACHABLE; + } + AstTreeVariable *variable = operand->metadata; + AstTree *ret = copyAstTree(variable->value); + astTreeDelete(operand); + return ret; } case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = expr->metadata; - AstTree *value = variable->value; - return runExpression(value, shouldRet); + return copyAstTree(variable->value); } case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_NONE: |