summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/main.felan22
-rw-r--r--src/compiler/ast-tree.c69
-rw-r--r--src/compiler/ast-tree.h2
-rw-r--r--src/compiler/lexer.c35
-rw-r--r--src/compiler/lexer.h3
-rw-r--r--src/compiler/parser.c38
-rw-r--r--src/compiler/parser.h3
-rw-r--r--src/runner/runner.c37
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: