From c506c3458a07485169cc38ce27d5cf21601136c2 Mon Sep 17 00:00:00 2001 From: A404M Date: Thu, 5 Jun 2025 16:24:21 +0330 Subject: trying to add macro --- Makefile | 8 ++++---- code/main.felan | 8 ++------ src/compiler/ast-tree.c | 52 +++++++++++++++++++++++-------------------------- src/compiler/ast-tree.h | 2 ++ src/compiler/lexer.c | 6 +++++- src/compiler/lexer.h | 1 + src/compiler/parser.c | 48 ++++++++++++++++++++++++++++++++++++--------- src/compiler/parser.h | 2 ++ 8 files changed, 79 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index d713229..a2e443e 100644 --- a/Makefile +++ b/Makefile @@ -75,11 +75,11 @@ test/big.felan: Makefile echo "main :: () -> void {" > $@ for((n = 0;n < 1000000;n++)); do echo " print('1');" >> $@; done echo "};" >> $@ - echo "libc :: @c_library(\"/lib/libc.so.6\");" >> $@ - echo "putchar :: @c_function(libc,\"putchar\",(i32)->i32);" >> $@ + # echo "libc :: @c_library(\"/lib/libc.so.6\");" >> $@ + # echo "putchar :: @c_function(libc,\"putchar\",(i32)->i32);" >> $@ echo "print :: (value:u8) -> void {" >> $@ - echo " putchar(@cast(value,i32));" >> $@ - # echo " @putc(value);" >> $@ + # echo " putchar(@cast(value,i32));" >> $@ + echo " @putc(value);" >> $@ echo "};" >> $@ # $@ = left hand of : diff --git a/code/main.felan b/code/main.felan index 03f4ba1..b570c08 100644 --- a/code/main.felan +++ b/code/main.felan @@ -1,6 +1,6 @@ @import("basic.felan"); -t :: (comptime formatter : string) -> string { +t :: (comptime formatter : string) macro -> string { i := 0; in := 0; opening := 0; @@ -28,12 +28,8 @@ t :: (comptime formatter : string) -> string { main :: () -> void { a := '2'; // @insert("a = '3';a = '5';"); - s :: t("hello {a = '1';}"); + s :: t("hello"); @insert(s); print_char(a); }; -p :: (comptime s:string)->void{ - print(1234); -}; - diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index fd83905..2b79e14 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -1353,6 +1353,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], new_metadata->arguments_size = metadata->arguments_size; new_metadata->arguments = a404m_malloc(sizeof(*new_metadata->arguments) * new_metadata->arguments_size); + new_metadata->isMacro = metadata->isMacro; for (size_t i = 0; i < metadata->arguments_size; ++i) { AstTreeTypeFunctionArgument arg = metadata->arguments[i]; new_metadata->arguments[i].str_begin = arg.str_begin; @@ -1392,6 +1393,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], new_metadata->arguments = copyAstTreeVariables(metadata->arguments, oldVariables, newVariables, variables_size, safetyCheck); + new_metadata->isMacro = metadata->isMacro; size_t new_variables_size = variables_size + 2; AstTreeVariables new_oldVariables[new_variables_size]; @@ -1756,6 +1758,7 @@ AstTreeFunction *copyAstTreeFunction(AstTreeFunction *metadata, new_metadata->arguments = copyAstTreeVariables(metadata->arguments, oldVariables, newVariables, variables_size, safetyCheck); + new_metadata->isMacro = metadata->isMacro; const size_t new_variables_size = variables_size + 2; AstTreeVariables new_oldVariables[new_variables_size]; @@ -2630,6 +2633,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { function->arguments.data = a404m_malloc(0); function->arguments.size = 0; + function->isMacro = node_metadata->isMacro; for (size_t i = 0; i < node_arguments->size; ++i) { const ParserNode *arg = node_arguments->data[i]; @@ -2846,6 +2850,7 @@ AstTree *astTreeParseTypeFunction(const ParserNode *parserNode) { typeFunction->arguments = a404m_malloc(arguments_size * sizeof(*typeFunction->arguments)); typeFunction->arguments_size = 0; + typeFunction->isMacro = metadata->isMacro; for (size_t i = 0; i < node_arguments->size; ++i) { const ParserNode *node_argument = node_arguments->data[i]; @@ -4176,24 +4181,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_FUNCTION: { AstTreeFunction *function = value->metadata; - AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); - type_metadata->arguments_size = function->arguments.size; - type_metadata->arguments = a404m_malloc(function->arguments.size * - sizeof(*type_metadata->arguments)); - type_metadata->returnType = copyAstTree(function->returnType); - - for (size_t i = 0; i < function->arguments.size; ++i) { - AstTreeVariable *arg = function->arguments.data[i]; - type_metadata->arguments[i].name_begin = arg->name_begin; - type_metadata->arguments[i].name_end = arg->name_end; - type_metadata->arguments[i].str_begin = arg->name_begin; - type_metadata->arguments[i].str_end = arg->name_end; - type_metadata->arguments[i].type = copyAstTree(arg->type); - type_metadata->arguments[i].isComptime = arg->isConst; - } - - return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, - &AST_TREE_TYPE_TYPE, value->str_begin, value->str_end); + return makeTypeOfFunction(function, value->str_begin, value->str_end); } case AST_TREE_TOKEN_VALUE_VOID: return &AST_TREE_VOID_TYPE; @@ -4305,6 +4293,7 @@ AstTree *makeTypeOfFunction(AstTreeFunction *function, const char *str_begin, type_metadata->arguments = a404m_malloc(function->arguments.size * sizeof(*type_metadata->arguments)); type_metadata->returnType = copyAstTree(function->returnType); + type_metadata->isMacro = function->isMacro; for (size_t i = 0; i < function->arguments.size; ++i) { AstTreeVariable *arg = function->arguments.data[i]; @@ -5696,6 +5685,8 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) { return true; } + // TODO: do something about macros + AstTreeSetTypesHelper helper = { .lookingType = NULL, .dependencies = _helper.dependencies, @@ -6726,6 +6717,7 @@ bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 2; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(to); @@ -6797,6 +6789,7 @@ bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(&AST_TREE_TYPE_TYPE); @@ -6863,6 +6856,7 @@ bool setTypesBuiltinSizeOf(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(&AST_TREE_U64_TYPE); @@ -6925,6 +6919,7 @@ bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(&AST_TREE_NAMESPACE_TYPE); @@ -7013,6 +7008,7 @@ bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 2; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, copyAstTree(type), @@ -7198,6 +7194,7 @@ AFTER_SWITCH: type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(type); @@ -7279,6 +7276,7 @@ bool setTypesBuiltinBinaryAlsoPointer(AstTree *tree, type_metadata->arguments_size = 2; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(left->type); @@ -7361,6 +7359,7 @@ bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 2; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(left->type); @@ -7441,6 +7440,7 @@ bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 2; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(retType); @@ -7502,6 +7502,7 @@ bool setTypesBuiltinPutc(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(&AST_TREE_VOID_TYPE); @@ -7567,6 +7568,7 @@ bool setTypesBuiltinCLibrary(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(&AST_TREE_C_LIBRARY_TYPE); @@ -7669,6 +7671,7 @@ bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 3; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; AstTreeCFunctionType *retType = a404m_malloc(sizeof(*retType)); retType->funcType = copyAstTree(funcType); @@ -7750,6 +7753,7 @@ bool setTypesBuiltinInsert(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments_size = 1; type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); + type_metadata->isMacro = false; type_metadata->returnType = copyAstTree(type); @@ -8275,6 +8279,8 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, AstTreeFunction *newFunction = copyAstTreeFunction(shapeShifter->function, NULL, NULL, 0, true); + newFunction->isMacro = shapeShifter->function->isMacro; + AstTreeFunctionCallParam initedArguments[newFunction->arguments.size]; size_t initedArguments_size = newFunction->arguments.size; @@ -8455,16 +8461,6 @@ char *u8ArrayToCString(AstTree *tree) { .variables.data = a404m_malloc(0), .variables.size = 0, }; - /* -printLog("%s", AST_TREE_TOKEN_STRINGS[tree->token]); - -if (tree->token == AST_TREE_TOKEN_VARIABLE) { -AstTreeVariable *variable = tree->metadata; -printLog("%s", AST_TREE_TOKEN_STRINGS[variable->value->token]); - AstTreeObject *object = variable->value->metadata; -printLog("%d", object->items_size); -} - */ AstTree *treeValue = getValue(tree, true, &scope); diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index eac7722..7a88f28 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -213,6 +213,7 @@ typedef struct AstTreeFunction { AstTreeVariables arguments; AstTreeScope scope; AstTree *returnType; + bool isMacro; } AstTreeFunction; typedef struct AstTreeTypeFunctionArgument { @@ -228,6 +229,7 @@ typedef struct AstTreeTypeFunction { AstTreeTypeFunctionArgument *arguments; size_t arguments_size; AstTree *returnType; + bool isMacro; } AstTreeTypeFunction; typedef struct AstTreeFunctionCallParam { diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 9c27bac..43a0850 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -3,6 +3,7 @@ #include "utils/log.h" #include "utils/memory.h" #include "utils/string.h" +#include const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET", @@ -137,6 +138,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_OPEN_BRACKET", "LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET", "LEXER_TOKEN_KEYWORD_LAZY", + "LEXER_TOKEN_KEYWORD_MACRO", "LEXER_TOKEN_NONE", }; @@ -201,7 +203,7 @@ static const char *LEXER_KEYWORD_STRINGS[] = { "else", "while", "comptime", "null", "struct", "undefined", "code", "lazy", "namespace", "shape_shifter", "break", "continue", - "c_library", "c_function", + "c_library", "c_function", "macro", }; static const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_ANY_TYPE, @@ -224,6 +226,7 @@ static const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_NAMESPACE, LEXER_TOKEN_KEYWORD_SHAPE_SHIFTER, LEXER_TOKEN_KEYWORD_BREAK, LEXER_TOKEN_KEYWORD_CONTINUE, LEXER_TOKEN_KEYWORD_C_LIBRARY, LEXER_TOKEN_KEYWORD_C_FUNCTION, + LEXER_TOKEN_KEYWORD_MACRO, }; static const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -500,6 +503,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_KEYWORD_CODE: case LEXER_TOKEN_KEYWORD_NAMESPACE: case LEXER_TOKEN_KEYWORD_LAZY: + case LEXER_TOKEN_KEYWORD_MACRO: case LEXER_TOKEN_NUMBER: case LEXER_TOKEN_CHAR: case LEXER_TOKEN_STRING: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 2e9807d..e868900 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -153,6 +153,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_OPEN_BRACKET, LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET, LEXER_TOKEN_KEYWORD_LAZY, + LEXER_TOKEN_KEYWORD_MACRO, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index ed51742..d5906a5 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -6,6 +6,7 @@ #include "utils/memory.h" #include "utils/string.h" #include "utils/time.h" +#include const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_ROOT", @@ -1179,6 +1180,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserStruct(node, end, parent); case LEXER_TOKEN_KEYWORD_LAZY: case LEXER_TOKEN_KEYWORD_ELSE: + case LEXER_TOKEN_KEYWORD_MACRO: case LEXER_TOKEN_BUILTIN: case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: @@ -1767,16 +1769,26 @@ ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin, ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent) { - LexerNode *paramsNode = node - 1; + LexerNode *paramsOrFlagNode = node - 1; LexerNode *retTypeNode = node + 1; - if (paramsNode < begin || paramsNode->parserNode == NULL) { + if (paramsOrFlagNode < begin) { printError(node->str_begin, node->str_end, "No params"); return NULL; } else if (retTypeNode >= end || retTypeNode->parserNode == NULL) { printError(node->str_begin, node->str_end, "No return type"); return NULL; } - ParserNode *params = getUntilCommonParent(paramsNode->parserNode, parent); + LexerNode *macroFlagNode = NULL; + if (paramsOrFlagNode->token == LEXER_TOKEN_KEYWORD_MACRO) { + macroFlagNode = paramsOrFlagNode; + paramsOrFlagNode -= 1; + } + if (paramsOrFlagNode < begin || paramsOrFlagNode->parserNode == NULL) { + printError(node->str_begin, node->str_end, "No params"); + return NULL; + } + ParserNode *params = + getUntilCommonParent(paramsOrFlagNode->parserNode, parent); ParserNode *retType = getUntilCommonParent(retTypeNode->parserNode, parent); LexerNode *bodyNode = @@ -1936,19 +1948,37 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, metadata->arguments = params; metadata->returnType = retType; + ParserNode *parserNode = + newParserNode(PARSER_TOKEN_FUNCTION_DEFINITION, params->str_begin, + body->str_end, metadata, parent); + + if (macroFlagNode != NULL) { + metadata->isMacro = true; + macroFlagNode->parserNode = parserNode; + } else { + metadata->isMacro = false; + } + return params->parent = retType->parent = body->parent = node->parserNode = - newParserNode(PARSER_TOKEN_FUNCTION_DEFINITION, - params->str_begin, body->str_end, metadata, - parent); + parserNode; } else { ParserNodeTypeFunctionMetadata *metadata = a404m_malloc(sizeof(*metadata)); metadata->arguments = params; metadata->returnType = retType; - return params->parent = retType->parent = node->parserNode = - newParserNode(PARSER_TOKEN_TYPE_FUNCTION, params->str_begin, - retType->str_end, metadata, parent); + ParserNode *parserNode = + newParserNode(PARSER_TOKEN_TYPE_FUNCTION, params->str_begin, + retType->str_end, metadata, parent); + + if (macroFlagNode != NULL) { + metadata->isMacro = true; + macroFlagNode->parserNode = parserNode; + } else { + metadata->isMacro = false; + } + + return params->parent = retType->parent = node->parserNode = parserNode; } } diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 0b89bb3..3db1d3d 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -149,6 +149,7 @@ typedef struct ParserNode { typedef struct ParserNodeTypeFunctionMetadata { ParserNode *arguments; ParserNode *returnType; + bool isMacro; } ParserNodeTypeFunctionMetadata; typedef struct ParserNodeVariableMetadata { @@ -163,6 +164,7 @@ typedef struct ParserNodeFunctionDefnitionMetadata { ParserNode *arguments; ParserNode *returnType; ParserNode *body; + bool isMacro; } ParserNodeFunctionDefnitionMetadata; typedef struct ParserNodeArray { -- cgit v1.2.3