From 81c83f4233dba3851333cb69ab9727659e253d1b Mon Sep 17 00:00:00 2001 From: A404M Date: Sat, 24 May 2025 12:30:50 +0330 Subject: fixing some problems in parsing adding more stuff to the example --- Makefile | 4 +- code/main.felan | 8 +++- src/compiler/ast-tree.c | 22 +++++++++ src/compiler/parser.c | 125 +++++++++++++++++++++++++++++++++++++++++++++--- src/compiler/parser.h | 1 + src/runner/runner.c | 18 ++++++- 6 files changed, 167 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index c590681..c7b3eec 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,9 @@ INC_DIRS := $(SRC_DIR) INC_FLAGS := $(addprefix -I,$(INC_DIRS)) # OP_FLAG := -Ofast -# OP_FLAG := -O3 +OP_FLAG := -O3 # OP_FLAG := -Oz -OP_FLAG := -g +# OP_FLAG := -g # CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -DPRINT_STATISTICS -DPRINT_COMPILE_TREE $(OP_FLAG) CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -lffi -DPRINT_STATISTICS $(OP_FLAG) diff --git a/code/main.felan b/code/main.felan index d8c6ec3..0258e17 100644 --- a/code/main.felan +++ b/code/main.felan @@ -11,16 +11,20 @@ BeginDrawing :: @c_function(raylib,"BeginDrawing",()->void); EndDrawing :: @c_function(raylib,"EndDrawing",()->void); CloseWindow :: @c_function(raylib,"CloseWindow",()->void); ClearBackground :: @c_function(raylib,"ClearBackground",(color:u32)->void); +DrawText :: @c_function(raylib,"DrawText",(*u8,i32,i32,i32,u32)->void); main :: ()->void{ - b := "hello\0"; + b := "raylib [core] example - basic window\0"; + c := "Congrats! You created your first window!\0"; str := &b[0]; + str2 := &c[0]; screenWidth :i32: 800; screenHeight :i32: 450; InitWindow(screenWidth,screenHeight,str); - while WindowShouldClose() == false { + while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(@cast(4294967295,u32)); + DrawText(str2,@cast(190,i32),@cast(200,i32),@cast(20,i32),@cast(4278190080,u32)); EndDrawing(); } CloseWindow(); diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index a4159d1..07ff036 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -670,6 +670,8 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: } UNREACHABLE; @@ -3541,6 +3543,8 @@ bool isConst(AstTree *tree) { return isConst(metadata->function); } case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: { return true; @@ -3793,6 +3797,8 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_RAW_VALUE: case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED: case AST_TREE_TOKEN_NONE: @@ -3878,6 +3884,8 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -4145,6 +4153,8 @@ AstTree *getValue(AstTree *tree, bool copy) { } case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: { if (copy) { return copyAstTree(tree); @@ -4221,6 +4231,8 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -4322,6 +4334,8 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -4456,6 +4470,8 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VALUE_OBJECT: @@ -4801,6 +4817,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: return setTypesArrayAccess(tree, helper); case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: case AST_TREE_TOKEN_RAW_VALUE: case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED: @@ -6485,6 +6503,8 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, goto AFTER_SWITCH; case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: case AST_TREE_TOKEN_BUILTIN_SIZE_OF: @@ -7591,6 +7611,8 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: diff --git a/src/compiler/parser.c b/src/compiler/parser.c index f85c412..3e4c8f6 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1365,12 +1365,19 @@ ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent) { ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin, ParserNode *parent, bool *conti) { LexerNode *opening = NULL; + int in = 0; for (LexerNode *iter = closing - 1; iter >= begin; --iter) { - if (iter->parserNode == NULL && - iter->token == LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS) { - opening = iter; - break; + if (iter->parserNode == NULL) { + if (iter->token == LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS) { + if (in == 0) { + opening = iter; + break; + } + in -= 1; + } else if (iter->token == LEXER_TOKEN_SYMBOL_FUNCTION_CALL) { + in += 1; + } } } @@ -1384,7 +1391,7 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin, ParserNode *before; if (beforeNode >= begin && beforeNode->parserNode != NULL && (before = getUntilCommonParent(beforeNode->parserNode, parent)) != NULL && - isExpression(before)) { + parserIsFunction(before)) { closing->token = LEXER_TOKEN_SYMBOL_FUNCTION_CALL; *conti = true; return NULL; @@ -1456,7 +1463,7 @@ ParserNode *parserFunctionCall(LexerNode *closing, LexerNode *begin, ParserNode *before; if (beforeNode < begin || beforeNode->parserNode == NULL || (before = getUntilCommonParent(beforeNode->parserNode, parent)) == NULL || - !isExpression(before)) { + !parserIsFunction(before)) { printError(closing->str_begin, closing->str_end, "Bad function call"); UNREACHABLE; } @@ -2291,6 +2298,112 @@ bool isExpression(ParserNode *node) { UNREACHABLE; } +bool parserIsFunction(ParserNode *node) { + switch (node->token) { + case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_BUILTIN_CAST: + case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: + case PARSER_TOKEN_BUILTIN_IMPORT: + case PARSER_TOKEN_BUILTIN_IS_COMPTIME: + case PARSER_TOKEN_BUILTIN_STACK_ALLOC: + case PARSER_TOKEN_BUILTIN_HEAP_ALLOC: + case PARSER_TOKEN_BUILTIN_NEG: + case PARSER_TOKEN_BUILTIN_ADD: + case PARSER_TOKEN_BUILTIN_SUB: + case PARSER_TOKEN_BUILTIN_MUL: + case PARSER_TOKEN_BUILTIN_DIV: + case PARSER_TOKEN_BUILTIN_MOD: + case PARSER_TOKEN_BUILTIN_EQUAL: + case PARSER_TOKEN_BUILTIN_NOT_EQUAL: + case PARSER_TOKEN_BUILTIN_GREATER: + case PARSER_TOKEN_BUILTIN_SMALLER: + case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: + case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_OPERATOR_ACCESS: + case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: + return true; + case PARSER_TOKEN_CONSTANT: + case PARSER_TOKEN_VARIABLE: + case PARSER_TOKEN_SYMBOL_PARENTHESIS: + case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: + case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: + case PARSER_TOKEN_FUNCTION_DEFINITION: + case PARSER_TOKEN_KEYWORD_RETURN: + case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUB_ASSIGN: + case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN: + 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_DEREFERENCE: + case PARSER_TOKEN_OPERATOR_PLUS: + case PARSER_TOKEN_OPERATOR_MINUS: + case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_OPERATOR_EQUAL: + case PARSER_TOKEN_OPERATOR_NOT_EQUAL: + case PARSER_TOKEN_OPERATOR_GREATER: + case PARSER_TOKEN_OPERATOR_SMALLER: + case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_VALUE_INT: + case PARSER_TOKEN_VALUE_FLOAT: + case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: + case PARSER_TOKEN_VALUE_STRING: + case PARSER_TOKEN_KEYWORD_IF: + case PARSER_TOKEN_KEYWORD_WHILE: + case PARSER_TOKEN_KEYWORD_COMPTIME: + case PARSER_TOKEN_TYPE_TYPE: + case PARSER_TOKEN_TYPE_FUNCTION: + case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_I8: + case PARSER_TOKEN_TYPE_U8: + case PARSER_TOKEN_TYPE_I16: + case PARSER_TOKEN_TYPE_U16: + case PARSER_TOKEN_TYPE_I32: + case PARSER_TOKEN_TYPE_U32: + case PARSER_TOKEN_TYPE_I64: + case PARSER_TOKEN_TYPE_U64: +#ifdef FLOAT_16_SUPPORT + case PARSER_TOKEN_TYPE_F16: +#endif + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: + case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: + case PARSER_TOKEN_TYPE_SHAPE_SHIFTER: + case PARSER_TOKEN_TYPE_C_LIBRARY: + case PARSER_TOKEN_TYPE_C_FUNCTION: + case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_KEYWORD_UNDEFINED: + case PARSER_TOKEN_KEYWORD_BREAK: + case PARSER_TOKEN_KEYWORD_CONTINUE: + case PARSER_TOKEN_KEYWORD_STRUCT: + case PARSER_TOKEN_ROOT: + case PARSER_TOKEN_SYMBOL_EOL: + case PARSER_TOKEN_SYMBOL_COMMA: + return false; + case PARSER_TOKEN_NONE: + } + UNREACHABLE; +} + bool isType(ParserNode *node) { switch (node->token) { case PARSER_TOKEN_TYPE_TYPE: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 6ef1427..1b202c3 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -272,6 +272,7 @@ ParserNode *parserStruct(LexerNode *node, LexerNode *end, ParserNode *parent); bool isAllArguments(const ParserNodeArray *nodes); bool isExpression(ParserNode *node); +bool parserIsFunction(ParserNode *node); bool isType(ParserNode *node); bool isValue(ParserNode *node); diff --git a/src/runner/runner.c b/src/runner/runner.c index 9cb67f8..bedb2c6 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1704,6 +1704,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, variable->value->token); UNREACHABLE; } + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: { UNREACHABLE; } @@ -1829,6 +1831,8 @@ AstTree *toRawValue(AstTree *value) { copyAstTree(value->type), value->str_begin, value->str_end); } + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -1908,6 +1912,11 @@ AstTree *toRawValue(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_C_FUNCTION: } return NULL; } @@ -2048,6 +2057,8 @@ AstTree *castTo(AstTree *tree, AstTree *to) { case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: + case AST_TREE_TOKEN_VALUE_C_LIBRARY: + case AST_TREE_TOKEN_VALUE_C_FUNCTION: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -2078,8 +2089,13 @@ AstTree *castTo(AstTree *tree, AstTree *to) { case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: - UNREACHABLE; + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_C_FUNCTION: } + UNREACHABLE; } ffi_type *toFFIType(AstTree *type) { -- cgit v1.2.3