diff options
-rw-r--r-- | code/main.felan | 5 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 211 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 19 | ||||
-rw-r--r-- | src/compiler/lexer.c | 5 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 13 | ||||
-rw-r--r-- | src/compiler/parser.h | 1 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/runner/runner.c | 131 | ||||
-rw-r--r-- | src/runner/runner.h | 2 |
10 files changed, 327 insertions, 63 deletions
diff --git a/code/main.felan b/code/main.felan index 7428511..f4b7608 100644 --- a/code/main.felan +++ b/code/main.felan @@ -11,6 +11,11 @@ st :: struct { }; main :: () -> void { + b :u64= 2; + c := &b; + c.* = 4; + print_u64 b; a : st = undefined; + a.a = 5; }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 4c37703..ef5e6a7 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -158,6 +158,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_POINTER", "AST_TREE_TOKEN_OPERATOR_ADDRESS", "AST_TREE_TOKEN_OPERATOR_DEREFERENCE", + "AST_TREE_TOKEN_OPERATOR_ACCESS", "AST_TREE_TOKEN_SCOPE", @@ -428,9 +429,26 @@ void astTreePrint(const AstTree *tree, int indent) { printf(" "); } printf("]"); - + } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + AstTreeAccess *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("left=\n"); + astTreePrint(metadata->object, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("right=%.*s", + (int)(metadata->member.name.end - metadata->member.name.begin), + metadata->member.name.begin); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); } + goto RETURN_SUCCESS; case AST_TREE_TOKEN_NONE: } @@ -447,7 +465,11 @@ void astTreeVariablePrint(const AstTreeVariable *variable, int indent) { printf("{\nname=\"%.*s\",\nvalue=\n", (int)(variable->name_end - variable->name_begin), variable->name_begin); - astTreePrint(variable->value, indent); + if (variable->value == NULL) { + printf("null"); + } else { + astTreePrint(variable->value, indent); + } printf("\n}"); } @@ -617,6 +639,12 @@ void astTreeDestroy(AstTree tree) { free(metadata); } return; + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + AstTreeAccess *metadata = tree.metadata; + astTreeDelete(metadata->object); + free(metadata); + } + return; case AST_TREE_TOKEN_NONE: } printLog("token = %d", tree.token); @@ -958,6 +986,18 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), tree->str_begin, tree->str_end); } + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + AstTreeAccess *metadata = tree->metadata; + AstTreeAccess *new_metadata = a404m_malloc(sizeof(*new_metadata)); + + new_metadata->object = metadata->object; + new_metadata->member = metadata->member; + + return newAstTree( + tree->token, new_metadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); + } case AST_TREE_TOKEN_NONE: } printLog("Bad token %d", tree->token); @@ -1087,6 +1127,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: @@ -1361,6 +1402,9 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: return astTreeParseBinaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL); + case PARSER_TOKEN_OPERATOR_ACCESS: + return astTreeParseAccessOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_ACCESS); case PARSER_TOKEN_OPERATOR_PLUS: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_PLUS); @@ -1538,6 +1582,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: + case PARSER_TOKEN_OPERATOR_ACCESS: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -2081,6 +2126,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: + case PARSER_TOKEN_OPERATOR_ACCESS: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -2188,6 +2234,33 @@ AstTree *astTreeParseStruct(ParserNode *parserNode, AstTreeHelper *helper) { parserNode->str_begin, parserNode->str_end); } +AstTree *astTreeParseAccessOperator(ParserNode *parserNode, + AstTreeHelper *helper, AstTreeToken token) { + ParserNodeInfixMetadata *node_metadata = parserNode->metadata; + + AstTree *object = astTreeParse(node_metadata->left, helper); + if (object == NULL) { + return NULL; + } + + ParserNode *right_node = node_metadata->right; + if (right_node->token != PARSER_TOKEN_IDENTIFIER) { + printError(right_node->str_begin, right_node->str_end, + "Should be an identifier but got `%s`", + PARSER_TOKEN_STRINGS[right_node->token]); + return NULL; + } + + AstTreeAccess *metadata = a404m_malloc(sizeof(*metadata)); + + metadata->object = object; + metadata->member.name.begin = right_node->str_begin; + metadata->member.name.end = right_node->str_end; + + return newAstTree(token, metadata, NULL, parserNode->str_begin, + parserNode->str_end); +} + bool isFunction(AstTree *value) { return value->type->token == AST_TREE_TOKEN_TYPE_FUNCTION; } @@ -2267,6 +2340,10 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { AstTreeSingleChild *metadata = tree->metadata; return isConst(metadata, helper); } + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + AstTreeAccess *metadata = tree->metadata; + return isConst(metadata->object, helper); + } case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -2368,6 +2445,22 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { return &AST_TREE_BOOL_TYPE; } + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + AstTreeAccess *metadata = value->metadata; + + AstTreeStruct *struc = metadata->object->type->metadata; + const size_t size = metadata->member.name.end - metadata->member.name.begin; + const char *str = metadata->member.name.begin; + + for (size_t i = 0; i < struc->variables.size; ++i) { + AstTreeVariable *member = struc->variables.data[i]; + const size_t member_size = member->name_end - member->name_begin; + if (member_size == size && strncmp(member->name_begin, str, size)) { + return copyAstTree(member->type); + } + } + UNREACHABLE; + } case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -2413,6 +2506,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_ACCESS: return false; case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -2524,12 +2618,13 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { 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_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, false); if (value == NULL) { printError(tree->str_begin, tree->str_end, "Unknown error"); } @@ -2584,6 +2679,7 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: + case AST_TREE_TOKEN_OPERATOR_ACCESS: return false; case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -2799,6 +2895,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesComptime(tree, helper); case AST_TREE_TOKEN_KEYWORD_STRUCT: return setTypesStruct(tree, helper); + case AST_TREE_TOKEN_OPERATOR_ACCESS: + return setTypesOperatorAccess(tree, helper); case AST_TREE_TOKEN_NONE: break; } @@ -3451,7 +3549,7 @@ bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeStruct *metadata = tree->metadata; for (size_t i = 0; i < metadata->variables.size; ++i) { - if (!setAllTypes(metadata->variables.data[i]->type, helper, NULL)) { + if (!setTypesAstVariable(metadata->variables.data[i], helper)) { return false; } } @@ -3459,6 +3557,38 @@ bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper) { return true; } +bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { + AstTreeAccess *metadata = tree->metadata; + if (!setAllTypes(metadata->object, helper, NULL)) { + return false; + } else if (metadata->object->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT) { + printError(metadata->object->str_begin, metadata->object->str_end, + "The object is not a struct"); + return false; + } + + AstTreeStruct *struc = metadata->object->type->metadata; + const size_t size = metadata->member.name.end - metadata->member.name.begin; + const char *str = metadata->member.name.begin; + + size_t index = 0; + + for (size_t i = 0; i < struc->variables.size; ++i) { + AstTreeVariable *member = struc->variables.data[i]; + const size_t member_size = member->name_end - member->name_begin; + if (member_size == size && strncmp(member->name_begin, str, size)) { + metadata->member.index = index; + tree->type = copyAstTree(member->type); + return true; + } + index += sizeOfType(member->type); + } + + printError(metadata->member.name.begin, metadata->member.name.end, + "Member not found"); + return false; +} + bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) { if (!setAllTypes(&infix->left, helper, NULL)) { return false; @@ -3470,3 +3600,76 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) { return setAllTypes(&infix->right, newHelper, NULL); } + +size_t sizeOfType(AstTree *type) { + switch (type->token) { + case AST_TREE_TOKEN_TYPE_TYPE: + UNREACHABLE; + case AST_TREE_TOKEN_TYPE_VOID: + return 0; + case AST_TREE_TOKEN_TYPE_I8: + case AST_TREE_TOKEN_TYPE_U8: + case AST_TREE_TOKEN_TYPE_BOOL: + return 1; + case AST_TREE_TOKEN_TYPE_I16: + case AST_TREE_TOKEN_TYPE_U16: + case AST_TREE_TOKEN_TYPE_F16: + return 2; + case AST_TREE_TOKEN_TYPE_I32: + case AST_TREE_TOKEN_TYPE_U32: + case AST_TREE_TOKEN_TYPE_F32: + return 4; + case AST_TREE_TOKEN_TYPE_I64: + case AST_TREE_TOKEN_TYPE_U64: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_FUNCTION: + return 8; + case AST_TREE_TOKEN_TYPE_F128: + return 16; + case AST_TREE_TOKEN_KEYWORD_STRUCT: { + AstTreeStruct *metadata = type->metadata; + size_t size = 0; + for (size_t i = 0; i < metadata->variables.size; ++i) { + size += sizeOfType(metadata->variables.data[i]->type); + } + return size; + } + 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_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_SCOPE: + case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + 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_NONE: + } + printError(type->str_begin, type->str_end, "Bad token %d", type->token); + UNREACHABLE; +} diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 00f477c..fdc797e 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -61,6 +61,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_POINTER, AST_TREE_TOKEN_OPERATOR_ADDRESS, AST_TREE_TOKEN_OPERATOR_DEREFERENCE, + AST_TREE_TOKEN_OPERATOR_ACCESS, AST_TREE_TOKEN_SCOPE, @@ -194,6 +195,19 @@ typedef struct AstTreeStruct { AstTreeVariables variables; } AstTreeStruct; +typedef struct AstTreeName { + char *begin; + char *end; +} AstTreeName; + +typedef struct AstTreeAccess { + AstTree *object; + struct { + AstTreeName name; + size_t index; + } member; +} AstTreeAccess; + void astTreePrint(const AstTree *tree, int indent); void astTreeVariablePrint(const AstTreeVariable *variable, int indent); void astTreeRootPrint(const AstTreeRoot *root); @@ -251,6 +265,8 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseParenthesis(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseStruct(ParserNode *parserNode, AstTreeHelper *helper); +AstTree *astTreeParseAccessOperator(ParserNode *parserNode, + AstTreeHelper *helper, AstTreeToken token); bool isFunction(AstTree *value); bool isConst(AstTree *tree, AstTreeHelper *helper); @@ -299,7 +315,10 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); bool setTypesComptime(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper helper); bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper); + +size_t sizeOfType(AstTree *type); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 16e8ee5..6feb77e 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -72,13 +72,14 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_POINTER", "LEXER_TOKEN_SYMBOL_ADDRESS", "LEXER_TOKEN_SYMBOL_DEREFERENCE", + "LEXER_TOKEN_SYMBOL_ACCESS", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", ",", - "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", ".*", + "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", ".*", ".", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -108,6 +109,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_SYMBOL_ADDRESS, LEXER_TOKEN_SYMBOL_DEREFERENCE, + LEXER_TOKEN_SYMBOL_ACCESS, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -318,6 +320,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_POINTER: case LEXER_TOKEN_SYMBOL_ADDRESS: case LEXER_TOKEN_SYMBOL_DEREFERENCE: + case LEXER_TOKEN_SYMBOL_ACCESS: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 6862c0d..4b59dff 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -65,6 +65,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_SYMBOL_ADDRESS, LEXER_TOKEN_SYMBOL_DEREFERENCE, + LEXER_TOKEN_SYMBOL_ACCESS, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 2c7e6a6..ad06a7f 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -74,6 +74,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_POINTER", "PARSER_TOKEN_OPERATOR_ADDRESS", "PARSER_TOKEN_OPERATOR_DEREFERENCE", + "PARSER_TOKEN_OPERATOR_ACCESS", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -113,7 +114,8 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - ORDER_ARRAY(LEXER_TOKEN_SYMBOL_DEREFERENCE, ), + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_DEREFERENCE, + LEXER_TOKEN_SYMBOL_ACCESS, ), }, { .ltr = false, @@ -343,6 +345,7 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: @@ -536,6 +539,7 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: @@ -786,6 +790,9 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL); + case LEXER_TOKEN_SYMBOL_ACCESS: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_ACCESS); case LEXER_TOKEN_SYMBOL_PLUS: { ParserNode *result = parserBinaryOrLeftOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_PLUS, @@ -1227,6 +1234,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_SYMBOL_COMMA: + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: @@ -1654,6 +1662,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: @@ -1738,6 +1747,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_KEYWORD_STRUCT: + case PARSER_TOKEN_OPERATOR_ACCESS: return true; case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: @@ -1788,6 +1798,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index bb843e2..2df35b9 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -70,6 +70,7 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_POINTER, PARSER_TOKEN_OPERATOR_ADDRESS, PARSER_TOKEN_OPERATOR_DEREFERENCE, + PARSER_TOKEN_OPERATOR_ACCESS, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) { return 1; } - const int ret = run(argv[1], false); + const int ret = run(argv[1], true); fileDelete(); return ret; } diff --git a/src/runner/runner.c b/src/runner/runner.c index 94907a7..a335f85 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -70,7 +70,7 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, for (size_t i = 0; i < arguments_size; ++i) { AstTreeFunctionCallParam param = arguments[i]; AstTreeVariable *arg = function->arguments.data[i]; - AstTree *value = runExpression(param.value, &shouldRet); + AstTree *value = runExpression(param.value, &shouldRet, false); runnerVariableSetValue(arg, value); } @@ -80,7 +80,7 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, for (size_t i = 0; i < function->scope.expressions_size; ++i) { astTreeDelete(ret); - ret = runExpression(function->scope.expressions[i], &shouldRet); + ret = runExpression(function->scope.expressions[i], &shouldRet, false); if (shouldRet) { break; } @@ -89,11 +89,11 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, return ret; } -AstTree *runExpression(AstTree *expr, bool *shouldRet) { +AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { switch (expr->token) { case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { AstTreeSingleChild *metadata = expr->metadata; - AstTree *tree = runExpression(metadata, shouldRet); + AstTree *tree = runExpression(metadata, shouldRet, false); printf("%lu", *(AstTreeInt *)tree->metadata); astTreeDelete(tree); return &AST_TREE_VOID_VALUE; @@ -113,43 +113,38 @@ 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) { - left = metadata->left.metadata; - } else { - AstTree *left_metadata = metadata->left.metadata; - AstTree *var = runExpression(left_metadata, shouldRet); - if (var->token != AST_TREE_TOKEN_VARIABLE) { - UNREACHABLE; - } - left = var->metadata; - astTreeDelete(var); + AstTree *l = runExpression(&metadata->left, shouldRet, true); + if (l->token != AST_TREE_TOKEN_VARIABLE) { + UNREACHABLE; } - runnerVariableSetValue(left, runExpression(&metadata->right, shouldRet)); + AstTreeVariable *left = l->metadata; + runnerVariableSetValue(left, + runExpression(&metadata->right, shouldRet, false)); return copyAstTree(left->value); } case AST_TREE_TOKEN_KEYWORD_RETURN: { AstTreeReturn *metadata = expr->metadata; *shouldRet = true; if (metadata->value != NULL) { - return runExpression(metadata->value, shouldRet); + return runExpression(metadata->value, shouldRet, false); } else { return &AST_TREE_VOID_VALUE; } } case AST_TREE_TOKEN_VARIABLE_DEFINE: { AstTreeVariable *variable = expr->metadata; - runnerVariableSetValue(variable, runExpression(variable->value, shouldRet)); + runnerVariableSetValue(variable, + runExpression(variable->value, shouldRet, false)); return &AST_TREE_VOID_VALUE; } case AST_TREE_TOKEN_KEYWORD_IF: { AstTreeIf *metadata = expr->metadata; - AstTree *condition = runExpression(metadata->condition, shouldRet); + AstTree *condition = runExpression(metadata->condition, shouldRet, false); AstTree *ret; if (*(AstTreeBool *)condition->metadata) { - ret = runExpression(metadata->ifBody, shouldRet); + ret = runExpression(metadata->ifBody, shouldRet, isLeft); } else if (metadata->elseBody != NULL) { - ret = runExpression(metadata->elseBody, shouldRet); + ret = runExpression(metadata->elseBody, shouldRet, isLeft); } else { ret = &AST_TREE_VOID_VALUE; } @@ -160,19 +155,19 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { AstTreeWhile *metadata = expr->metadata; AstTree *ret = NULL; while (!*shouldRet) { - AstTree *tree = runExpression(metadata->condition, shouldRet); + AstTree *tree = runExpression(metadata->condition, shouldRet, false); bool conti = *(AstTreeBool *)tree->metadata; astTreeDelete(tree); if (!conti) { break; } - ret = runExpression(metadata->body, shouldRet); + ret = runExpression(metadata->body, shouldRet, isLeft); } return ret; } case AST_TREE_TOKEN_KEYWORD_COMPTIME: { AstTreeSingleChild *operand = expr->metadata; - return runExpression((AstTree *)operand, shouldRet); + return runExpression((AstTree *)operand, shouldRet, isLeft); } case AST_TREE_TOKEN_SCOPE: { AstTreeScope *metadata = expr->metadata; @@ -180,12 +175,14 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { AstTree *ret = &AST_TREE_VOID_VALUE; for (size_t i = 0; i < metadata->expressions_size && !*shouldRet; ++i) { astTreeDelete(ret); - ret = runExpression(metadata->expressions[i], shouldRet); + ret = runExpression(metadata->expressions[i], shouldRet, + i == metadata->expressions_size - 1 && isLeft); } return ret; } case AST_TREE_TOKEN_OPERATOR_PLUS: { - AstTreeSingleChild *operand = runExpression(expr->metadata, shouldRet); + AstTreeSingleChild *operand = + runExpression(expr->metadata, shouldRet, false); if (operand->type == &AST_TREE_U64_TYPE) { doLeftOperation(operand, +, AstTreeInt, u64); } else if (operand->type == &AST_TREE_I64_TYPE) { @@ -217,7 +214,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { return operand; } case AST_TREE_TOKEN_OPERATOR_MINUS: { - AstTreeSingleChild *operand = runExpression(expr->metadata, shouldRet); + AstTreeSingleChild *operand = + runExpression(expr->metadata, shouldRet, false); if (operand->type == &AST_TREE_U64_TYPE) { doLeftOperation(operand, -, AstTreeInt, u64); } else if (operand->type == &AST_TREE_I64_TYPE) { @@ -250,8 +248,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_SUM: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doOperation(left, right, +, AstTreeInt, u64); @@ -297,8 +295,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_SUB: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doOperation(left, right, -, AstTreeInt, u64); @@ -344,8 +342,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_MULTIPLY: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doOperation(left, right, *, AstTreeInt, u64); @@ -391,8 +389,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_DIVIDE: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doOperation(left, right, /, AstTreeInt, u64); @@ -438,8 +436,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_MODULO: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doOperation(left, right, %, AstTreeInt, u64); @@ -473,8 +471,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_EQUAL: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, ==, AstTreeInt, u64); @@ -526,8 +524,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, !=, AstTreeInt, u64); @@ -579,8 +577,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_GREATER: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, >, AstTreeInt, u64); @@ -626,8 +624,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_SMALLER: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, <, AstTreeInt, u64); @@ -673,8 +671,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, >=, AstTreeInt, u64); @@ -720,8 +718,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: { AstTreeInfix *metadata = expr->metadata; - AstTree *left = runExpression(&metadata->left, shouldRet); - AstTree *right = runExpression(&metadata->right, shouldRet); + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { doLogicalOperation(left, right, <=, AstTreeInt, u64); @@ -789,6 +787,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_KEYWORD_STRUCT: return copyAstTree(expr); case AST_TREE_TOKEN_OPERATOR_ADDRESS: { AstTreeSingleChild *metadata = expr->metadata; @@ -799,21 +798,43 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { } case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: { AstTreeSingleChild *metadata = expr->metadata; - AstTree *operand = runExpression(metadata, shouldRet); + AstTree *operand = runExpression(metadata, shouldRet, false); if (operand->token != AST_TREE_TOKEN_VARIABLE) { printLog("%s", AST_TREE_TOKEN_STRINGS[operand->token]); UNREACHABLE; } - AstTreeVariable *variable = operand->metadata; - AstTree *ret = copyAstTree(variable->value); - astTreeDelete(operand); + AstTree *ret; + if (isLeft) { + ret = operand; + } else { + AstTreeVariable *variable = operand->metadata; + ret = copyAstTree(variable->value); + astTreeDelete(operand); + } return ret; } case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = expr->metadata; - return copyAstTree(variable->value); + if (isLeft) { + return copyAstTree(expr); + } else { + return copyAstTree(variable->value); + } + } + case AST_TREE_TOKEN_OPERATOR_ACCESS: { + NOT_IMPLEMENTED; + AstTreeAccess *metadata = expr->metadata; + AstTree *tree = runExpression(metadata->object, shouldRet, true); + if (tree->token != AST_TREE_TOKEN_VARIABLE) { + UNREACHABLE; + } + AstTreeVariable *variable = tree->metadata; + astTreeDelete(variable->type); + variable->type = copyAstTree(expr->type); + variable->value->metadata = + ((u8 *)variable->value->metadata) + metadata->member.index; + return tree; } - case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_NONE: } UNREACHABLE; diff --git a/src/runner/runner.h b/src/runner/runner.h index efb3eb8..10fd8dc 100644 --- a/src/runner/runner.h +++ b/src/runner/runner.h @@ -10,4 +10,4 @@ bool runAstTree(AstTreeRoot *root); AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, size_t arguments_size); -AstTree *runExpression(AstTree *expr, bool *shouldRet); +AstTree *runExpression(AstTree *expr, bool *shouldRet,bool isLeft); |