diff options
-rw-r--r-- | code/main.felan | 3 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 45 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 2 | ||||
-rw-r--r-- | src/compiler/lexer.c | 6 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 38 | ||||
-rw-r--r-- | src/compiler/parser.h | 3 | ||||
-rw-r--r-- | src/runner/runner.c | 5 |
8 files changed, 96 insertions, 7 deletions
diff --git a/code/main.felan b/code/main.felan index 26a330c..88b1fbe 100644 --- a/code/main.felan +++ b/code/main.felan @@ -1,3 +1,4 @@ main :: () -> void { - b : *u64 = null; + a :u64= 2; + b : *u64 = &a; }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 5a6961a..5fed925 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -154,6 +154,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL", "AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL", "AST_TREE_TOKEN_OPERATOR_POINTER", + "AST_TREE_TOKEN_OPERATOR_ADDRESS", "AST_TREE_TOKEN_SCOPE", @@ -222,6 +223,7 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_VARIABLE_DEFINE: goto RETURN_SUCCESS; case AST_TREE_TOKEN_OPERATOR_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -463,6 +465,7 @@ void astTreeDestroy(AstTree tree) { return; } case AST_TREE_TOKEN_OPERATOR_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -622,8 +625,8 @@ AstTree *copyAstTree(AstTree *tree) { case AST_TREE_TOKEN_VALUE_VOID: return tree; case AST_TREE_TOKEN_VALUE_NULL: - return newAstTree(tree->token, NULL, copyAstTree(tree->type), tree->str_begin, - tree->str_end); + return newAstTree(tree->token, NULL, copyAstTree(tree->type), + tree->str_begin, tree->str_end); case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: return newAstTree(tree->token, tree->metadata, tree->type, tree->str_begin, @@ -698,6 +701,7 @@ AstTree *copyAstTree(AstTree *tree) { tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_OPERATOR_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -892,6 +896,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: goto AFTER_SWITCH; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -1133,6 +1138,9 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_POINTER: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_POINTER); + case PARSER_TOKEN_OPERATOR_ADDRESS: + return astTreeParseUnaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_ADDRESS); case PARSER_TOKEN_VARIABLE: return astTreeParseVariable(parserNode, helper); case PARSER_TOKEN_KEYWORD_IF: @@ -1289,6 +1297,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1812,6 +1821,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1908,6 +1918,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_OPERATOR_SUM: @@ -1998,6 +2009,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { AstTreeVariable *metadata = tree->metadata; return metadata->isConst; } + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_POINTER: { AstTreeSingleChild *metadata = tree->metadata; return isConst(metadata, helper); @@ -2027,6 +2039,11 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_OPERATOR_POINTER: return &AST_TREE_TYPE_TYPE; + case AST_TREE_TOKEN_OPERATOR_ADDRESS: { + AstTreeSingleChild *metadata = value->metadata; + return newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, makeTypeOf(metadata), + &AST_TREE_TYPE_TYPE, value->str_begin, value->str_end); + } case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = value->metadata; AstTreeFunction *function = metadata->function->metadata; @@ -2125,6 +2142,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_ADDRESS: return false; case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -2225,6 +2243,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { 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_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: @@ -2286,6 +2305,7 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, case AST_TREE_TOKEN_VALUE_BOOL: return false; case AST_TREE_TOKEN_OPERATOR_POINTER: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { @@ -2481,6 +2501,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesOperatorInfixWithRet(tree, &AST_TREE_BOOL_TYPE, helper); case AST_TREE_TOKEN_OPERATOR_POINTER: return setTypesOperatorPointer(tree, helper); + case AST_TREE_TOKEN_OPERATOR_ADDRESS: + return setTypesOperatorAddress(tree, helper); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree, helper); case AST_TREE_TOKEN_KEYWORD_IF: @@ -2908,13 +2930,30 @@ bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper) { } else if (!typeIsEqual(metadata->type, &AST_TREE_TYPE_TYPE)) { printError(tree->str_begin, tree->str_end, "Pointer type needs a type"); return false; - UNREACHABLE; } tree->type = &AST_TREE_TYPE_TYPE; return true; } +bool setTypesOperatorAddress(AstTree *tree, AstTreeSetTypesHelper helper) { + AstTreeSingleChild *metadata = tree->metadata; + if (!setAllTypes(metadata, helper, NULL)) { + return false; + } + + if (metadata->token != AST_TREE_TOKEN_VARIABLE) { + printError(tree->str_begin, tree->str_end, + "Can only get address of a variable (for now)"); + return false; + } + + tree->type = + newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, copyAstTree(metadata->type), + &AST_TREE_TYPE_TYPE, tree->str_begin, tree->str_end); + 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 33cf9da..0ea78e9 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -56,6 +56,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL, AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL, AST_TREE_TOKEN_OPERATOR_POINTER, + AST_TREE_TOKEN_OPERATOR_ADDRESS, AST_TREE_TOKEN_SCOPE, @@ -258,6 +259,7 @@ bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, AstTreeSetTypesHelper helper); bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorAddress(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 08eef75..905186a 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -68,13 +68,14 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_POINTER", + "LEXER_TOKEN_SYMBOL_ADDRESS", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", - ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", + ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -102,6 +103,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, LEXER_TOKEN_SYMBOL_SMALLER, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_ADDRESS, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -305,6 +307,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL: case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: case LEXER_TOKEN_SYMBOL_POINTER: + case LEXER_TOKEN_SYMBOL_ADDRESS: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = @@ -347,6 +350,7 @@ bool isSymbol(char c) { case '%': case '=': case '!': + case '&': return true; default: return false; diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 4789297..1ebe405 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -61,6 +61,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_SYMBOL_POINTER, + LEXER_TOKEN_SYMBOL_ADDRESS, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 3c40af1..fa6e17c 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -70,6 +70,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL", "PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL", "PARSER_TOKEN_OPERATOR_POINTER", + "PARSER_TOKEN_OPERATOR_ADDRESS", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -108,7 +109,7 @@ static constexpr ParserOrder PARSER_ORDER[] = { { .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, - LEXER_TOKEN_SYMBOL_POINTER, ), + LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_SYMBOL_ADDRESS, ), }, { .ltr = true, @@ -239,6 +240,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_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -465,6 +467,7 @@ void parserNodeDelete(ParserNode *node) { } goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -778,6 +781,12 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, *conti = result == NULL; return result; } + case LEXER_TOKEN_SYMBOL_ADDRESS: { + ParserNode *result = + parserLeftOperator(node, end, parent, PARSER_TOKEN_OPERATOR_ADDRESS); + *conti = result == NULL; + return result; + } case LEXER_TOKEN_KEYWORD_IF: return parserIf(node, end, parent); case LEXER_TOKEN_KEYWORD_WHILE: @@ -1173,7 +1182,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_TYPE_F32: case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: - case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_CONSTANT: @@ -1188,6 +1197,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1405,6 +1415,27 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, (ParserNodeSingleChildMetadata *)right, parent); } +ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, + ParserNode *parent, ParserToken token) { + LexerNode *rightNode = node + 1; + + if (rightNode >= end || rightNode->parserNode == NULL) { + printError(node->str_begin, node->str_end, "No operand found"); + return NULL; + } + + ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent); + + if (right == NULL) { + printError(node->str_begin, node->str_end, "No operand found"); + return NULL; + } + + return right->parent = node->parserNode = + newParserNode(token, node->str_begin, right->str_end, + (ParserNodeSingleChildMetadata *)right, parent); +} + ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent) { LexerNode *conditionNode = node + 1; if (conditionNode >= end) { @@ -1546,6 +1577,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1619,6 +1651,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: return true; + case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: @@ -1672,6 +1705,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: case PARSER_TOKEN_OPERATOR_POINTER: + case PARSER_TOKEN_OPERATOR_ADDRESS: 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 0eb2112..b888dae 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -66,6 +66,7 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL, PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL, PARSER_TOKEN_OPERATOR_POINTER, + PARSER_TOKEN_OPERATOR_ADDRESS, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -188,6 +189,8 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, ParserToken token, LexerToken laterToken); +ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, + 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 f120816..52c9673 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1009,6 +1009,11 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages, case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_OPERATOR_POINTER: 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); + } case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = expr->metadata; AstTree *value = runnerVariableGetValue(pages, variable); |