From 5d43a23a42725d9e88be76ce04260dbd4b57d370 Mon Sep 17 00:00:00 2001 From: A404M Date: Fri, 4 Apr 2025 22:12:17 +0330 Subject: add undefined and fix some struct stuff --- code/main.felan | 2 +- src/compiler/ast-tree.c | 45 ++++++++++++++++++++++++++++++++++++++------- src/compiler/ast-tree.h | 2 ++ src/compiler/lexer.c | 12 +++++++----- src/compiler/lexer.h | 1 + src/compiler/parser.c | 12 +++++++++++- src/compiler/parser.h | 3 ++- src/runner/runner.c | 2 ++ 8 files changed, 64 insertions(+), 15 deletions(-) diff --git a/code/main.felan b/code/main.felan index f755d37..7428511 100644 --- a/code/main.felan +++ b/code/main.felan @@ -11,6 +11,6 @@ st :: struct { }; main :: () -> void { - print_u64 1234; + a : st = undefined; }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 261e13b..4c37703 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -113,6 +113,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_KEYWORD_WHILE", "AST_TREE_TOKEN_KEYWORD_COMPTIME", "AST_TREE_TOKEN_KEYWORD_STRUCT", + "AST_TREE_TOKEN_KEYWORD_UNDEFINED", "AST_TREE_TOKEN_TYPE_FUNCTION", "AST_TREE_TOKEN_TYPE_TYPE", @@ -222,6 +223,7 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VARIABLE_DEFINE: goto RETURN_SUCCESS; case AST_TREE_TOKEN_OPERATOR_POINTER: @@ -495,6 +497,7 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VARIABLE_DEFINE: return; @@ -691,6 +694,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_VALUE_VOID: return tree; case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: return newAstTree( tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), @@ -947,6 +951,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], new_metadata->variables = copyAstTreeVariables( metadata->variables, oldVariables, newVariables, variables_size); + new_metadata->id = metadata->id; return newAstTree( tree->token, new_metadata, @@ -980,6 +985,12 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables, for (size_t i = 0; i < result.size; ++i) { result.data[i] = a404m_malloc(sizeof(*result.data[i])); + result.data[i]->name_begin = variables.data[i]->name_begin; + result.data[i]->name_end = variables.data[i]->name_end; + result.data[i]->isConst = variables.data[i]->isConst; + result.data[i]->type = + copyAstTreeBack(variables.data[i]->type, new_oldVariables, + new_newVariables, new_variables_size); if (variables.data[i]->value != NULL) { result.data[i]->value = copyAstTreeBack(variables.data[i]->value, new_oldVariables, @@ -987,12 +998,6 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables, } else { result.data[i]->value = NULL; } - 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; } return result; @@ -1075,6 +1080,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { switch (node_metadata->value->token) { case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: @@ -1298,6 +1304,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { sizeof(AstTreeBool)); case PARSER_TOKEN_KEYWORD_NULL: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_NULL); + case PARSER_TOKEN_KEYWORD_UNDEFINED: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_UNDEFINED); case PARSER_TOKEN_KEYWORD_PRINT_U64: return astTreeParsePrintU64(parserNode, helper); case PARSER_TOKEN_KEYWORD_RETURN: @@ -1526,6 +1534,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: @@ -2068,6 +2077,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: @@ -2201,6 +2211,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2364,6 +2375,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -2378,6 +2390,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2487,6 +2500,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2565,6 +2579,7 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2734,6 +2749,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesValueFloat(tree, helper); case AST_TREE_TOKEN_VALUE_NULL: return setTypesValueNull(tree, helper); + case AST_TREE_TOKEN_VALUE_UNDEFINED: + return setTypesValueUndefined(tree, helper); case AST_TREE_TOKEN_FUNCTION: return setTypesFunction(tree, helper); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -2944,6 +2961,19 @@ bool setTypesValueNull(AstTree *tree, AstTreeSetTypesHelper helper) { if (helper.lookingType == NULL) { printError(tree->str_begin, tree->str_end, "Can't find type of null"); return false; + } else if (helper.lookingType->token == AST_TREE_TOKEN_OPERATOR_POINTER) { + printError(tree->str_begin, tree->str_end, + "Null must have type of a pointer"); + return false; + } + tree->type = copyAstTree(helper.lookingType); + return true; +} + +bool setTypesValueUndefined(AstTree *tree, AstTreeSetTypesHelper helper) { + if (helper.lookingType == NULL) { + printError(tree->str_begin, tree->str_end, "Can't find type of undefined"); + return false; } tree->type = copyAstTree(helper.lookingType); return true; @@ -3295,7 +3325,8 @@ bool setTypesAstVariable(AstTreeVariable *variable, if (variable->type == NULL) { return false; } else if (variable->value != NULL) { - if (!typeIsEqual(variable->value->type, variable->type)) { + if (variable->value != NULL && + !typeIsEqual(variable->value->type, variable->type)) { printError(variable->name_begin, variable->name_end, "Type mismatch value = %s but type = %s", AST_TREE_TOKEN_STRINGS[variable->value->type->token], diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index a62e195..00f477c 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -39,6 +39,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VARIABLE, AST_TREE_TOKEN_VARIABLE_DEFINE, AST_TREE_TOKEN_VALUE_NULL, + AST_TREE_TOKEN_VALUE_UNDEFINED, AST_TREE_TOKEN_VALUE_INT, AST_TREE_TOKEN_VALUE_FLOAT, AST_TREE_TOKEN_VALUE_BOOL, @@ -273,6 +274,7 @@ bool setTypesValueBool(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueNull(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesValueUndefined(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper, diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 618851d..16e8ee5 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -37,6 +37,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_COMPTIME", "LEXER_TOKEN_KEYWORD_NULL", "LEXER_TOKEN_KEYWORD_STRUCT", + "LEXER_TOKEN_KEYWORD_UNDEFINED", "LEXER_TOKEN_NUMBER", @@ -112,10 +113,10 @@ const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); const char *LEXER_KEYWORD_STRINGS[] = { - "type", "void", "i8", "u8", "i16", "u16", "i32", - "u32", "i64", "u64", "f16", "f32", "f64", "f128", - "bool", "print_u64", "return", "true", "false", "if", "else", - "while", "comptime", "null", "struct", + "type", "void", "i8", "u8", "i16", "u16", "i32", + "u32", "i64", "u64", "f16", "f32", "f64", "f128", + "bool", "print_u64", "return", "true", "false", "if", "else", + "while", "comptime", "null", "struct", "undefined", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, @@ -130,7 +131,7 @@ const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE, LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_KEYWORD_NULL, - LEXER_TOKEN_KEYWORD_STRUCT, + LEXER_TOKEN_KEYWORD_STRUCT, LEXER_TOKEN_KEYWORD_UNDEFINED, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -285,6 +286,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_COMPTIME: case LEXER_TOKEN_KEYWORD_NULL: case LEXER_TOKEN_KEYWORD_STRUCT: + case LEXER_TOKEN_KEYWORD_UNDEFINED: case LEXER_TOKEN_NUMBER: case LEXER_TOKEN_SYMBOL_EOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 6daa893..6862c0d 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -30,6 +30,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_KEYWORD_STRUCT, + LEXER_TOKEN_KEYWORD_UNDEFINED, LEXER_TOKEN_NUMBER, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index d7fbade..2c7e6a6 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -42,6 +42,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_KEYWORD_COMPTIME", "PARSER_TOKEN_KEYWORD_NULL", "PARSER_TOKEN_KEYWORD_STRUCT", + "PARSER_TOKEN_KEYWORD_UNDEFINED", "PARSER_TOKEN_CONSTANT", "PARSER_TOKEN_VARIABLE", @@ -102,7 +103,8 @@ static constexpr ParserOrder PARSER_ORDER[] = { LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, - LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_NUMBER, ), + LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_NUMBER, + LEXER_TOKEN_KEYWORD_UNDEFINED, ), }, { .ltr = false, @@ -207,6 +209,7 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_INT: { ParserNodeIntMetadata *metadata = node->metadata; @@ -458,6 +461,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_BOOL: { ParserNodeBoolMetadata *metadata = node->metadata; @@ -708,6 +712,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F128); case LEXER_TOKEN_KEYWORD_NULL: return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_NULL); + case LEXER_TOKEN_KEYWORD_UNDEFINED: + return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_UNDEFINED); case LEXER_TOKEN_KEYWORD_PRINT_U64: return parserPrintU64(node, end, parent); case LEXER_TOKEN_KEYWORD_RETURN: @@ -1212,6 +1218,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_KEYWORD_STRUCT: @@ -1692,6 +1699,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_STRUCT: return true; case PARSER_TOKEN_ROOT: @@ -1733,6 +1741,7 @@ bool isType(ParserNode *node) { return true; case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_FUNCTION_DEFINITION: @@ -1818,6 +1827,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_COMPTIME: case PARSER_TOKEN_SYMBOL_PARENTHESIS: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 317e913..bb843e2 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -38,6 +38,7 @@ typedef enum ParserToken { PARSER_TOKEN_KEYWORD_COMPTIME, PARSER_TOKEN_KEYWORD_NULL, PARSER_TOKEN_KEYWORD_STRUCT, + PARSER_TOKEN_KEYWORD_UNDEFINED, PARSER_TOKEN_CONSTANT, PARSER_TOKEN_VARIABLE, @@ -82,7 +83,7 @@ extern const char *PARSER_TOKEN_STRINGS[]; typedef struct ParserOrder { bool ltr; size_t size; - LexerToken data[21]; + LexerToken data[22]; } ParserOrder; typedef struct ParserNode { diff --git a/src/runner/runner.c b/src/runner/runner.c index 12000ea..94907a7 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -782,6 +782,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_VALUE_NULL: + case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -812,6 +813,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet) { AstTreeVariable *variable = expr->metadata; return copyAstTree(variable->value); } + case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_NONE: } UNREACHABLE; -- cgit v1.2.3