aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--code/main.felan8
-rw-r--r--src/compiler/ast-tree.c22
-rw-r--r--src/compiler/parser.c125
-rw-r--r--src/compiler/parser.h1
-rw-r--r--src/runner/runner.c18
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) {