summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-26 02:06:04 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-26 02:06:04 +0330
commit3950c23e40207cd8a374fcd4aa5739c0a63115f5 (patch)
tree9bc4703a7eeb2d2ae9ca6324e61c56598cefa134
parent7bd975ec69c8dc9d5a6343a2e5f06bd7dd78d78e (diff)
add address operator
-rw-r--r--code/main.felan3
-rw-r--r--src/compiler/ast-tree.c45
-rw-r--r--src/compiler/ast-tree.h2
-rw-r--r--src/compiler/lexer.c6
-rw-r--r--src/compiler/lexer.h1
-rw-r--r--src/compiler/parser.c38
-rw-r--r--src/compiler/parser.h3
-rw-r--r--src/runner/runner.c5
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);