aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-06-03 03:15:59 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-06-03 03:15:59 +0330
commitdb6239342ffc6385a0c7659c8a01d2800a57da2c (patch)
tree1fb22c8d68d5e6670868c99c9cb1639591742f91
parentdb42bd4d0064d481d320a0ab2519966419feefec (diff)
first version of code insertion
-rw-r--r--code/main.felan5
-rw-r--r--src/backend/bba.h93
-rw-r--r--src/compiler/ast-tree.c182
-rw-r--r--src/compiler/ast-tree.h6
-rw-r--r--src/compiler/lexer.c4
-rw-r--r--src/compiler/lexer.h1
-rw-r--r--src/compiler/parser.c14
-rw-r--r--src/compiler/parser.h1
8 files changed, 275 insertions, 31 deletions
diff --git a/code/main.felan b/code/main.felan
index fca48b0..f9a8f86 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -1,6 +1,9 @@
@import("basic.felan");
main :: () -> void {
- println(@cast(-1,i32));
+ a := 2;
+ a += @insert("2");
+ print(a);
+ // @insert("print(123);");
};
diff --git a/src/backend/bba.h b/src/backend/bba.h
index 98c081e..2e77d78 100644
--- a/src/backend/bba.h
+++ b/src/backend/bba.h
@@ -5,34 +5,85 @@
typedef enum BBAOperation {
BBA_OPERATION_ASSIGN,
- BBA_OPERATION_CAST,
- // BBA_OPERATION_TYPE_OF,
- // BBA_OPERATION_IMPORT,
- // BBA_OPERATION_IS_COMPTIME,
- BBA_OPERATION_STACK_ALLOC,
- BBA_OPERATION_HEAP_ALLOC,
- BBA_OPERATION_NEG,
- BBA_OPERATION_ADD,
- BBA_OPERATION_SUB,
- BBA_OPERATION_MUL,
- BBA_OPERATION_DIV,
- BBA_OPERATION_MOD,
- BBA_OPERATION_EQUAL,
- BBA_OPERATION_NOT_EQUAL,
- BBA_OPERATION_GREATER,
- BBA_OPERATION_SMALLER,
- BBA_OPERATION_GREATER_OR_EQUAL,
- BBA_OPERATION_SMALLER_OR_EQUAL,
- BBA_OPERATION_PUTC,
+ BBA_OPERATOR_CAST,
+ BBA_OPERATOR_TYPE_OF,
+ BBA_OPERATOR_SIZE_OF,
+ BBA_OPERATOR_IMPORT,
+ BBA_OPERATOR_IS_COMPTIME,
+ BBA_OPERATOR_STACK_ALLOC,
+ BBA_OPERATOR_HEAP_ALLOC,
+ BBA_OPERATOR_NEG,
+ BBA_OPERATOR_ADD,
+ BBA_OPERATOR_SUB,
+ BBA_OPERATOR_MUL,
+ BBA_OPERATOR_DIV,
+ BBA_OPERATOR_MOD,
+ BBA_OPERATOR_EQUAL,
+ BBA_OPERATOR_NOT_EQUAL,
+ BBA_OPERATOR_GREATER,
+ BBA_OPERATOR_SMALLER,
+ BBA_OPERATOR_GREATER_OR_EQUAL,
+ BBA_OPERATOR_SMALLER_OR_EQUAL,
+ BBA_OPERATOR_PUTC,
+ BBA_OPERATOR_C_LIBRARY,
+ BBA_OPERATOR_C_FUNCTION,
+ BBA_OPERATOR_BITWISE_NOT,
+ BBA_OPERATOR_BITWISE_AND,
+ BBA_OPERATOR_BITWISE_XOR,
+ BBA_OPERATOR_BITWISE_OR,
+ BBA_OPERATOR_SHIFT_LEFT,
+ BBA_OPERATOR_SHIFT_RIGHT,
BBA_OPERATION_CALL,
-}BBAOperation;
-typedef struct BBAInstruction {
+ BBA_OPERATOR_CONST_I8,
+ BBA_OPERATOR_CONST_U8,
+ BBA_OPERATOR_CONST_I16,
+ BBA_OPERATOR_CONST_U16,
+ BBA_OPERATOR_CONST_I32,
+ BBA_OPERATOR_CONST_U32,
+ BBA_OPERATOR_CONST_I64,
+ BBA_OPERATOR_CONST_U64,
+
+#ifdef FLOAT_16_SUPPORT
+ BBA_OPERATOR_CONST_F16,
+#endif
+ BBA_OPERATOR_CONST_F32,
+ BBA_OPERATOR_CONST_F64,
+ BBA_OPERATOR_CONST_F128,
+} BBAOperation;
+
+typedef union BBAInstructionValue {
+ struct BBAInstruction *instruction;
+ u8 u8;
+ i8 i8;
+ u16 u16;
+ i16 i16;
+ u32 u32;
+ i32 i32;
+ u64 u64;
+ i64 i64;
+
+#ifdef FLOAT_16_SUPPORT
+ f16 f16;
+#endif
+ f32 f32;
+ f64 f64;
+ f128 f128;
+} BBAInstructionValue;
+
+typedef struct BBAInstruction {
+ BBAOperation operator;
+ BBAInstructionValue *value;
+ size_t value_size;
} BBAInstruction;
typedef struct BBABlock {
+ BBAInstructionValue *params;
+ size_t params_size;
+ BBAInstruction **instructions;
+ size_t instructions_size;
} BBABlock;
typedef struct BBA {
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 7f7720d..a65a2f1 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1,5 +1,6 @@
#include "ast-tree.h"
+#include "compiler/lexer.h"
#include "compiler/parser.h"
#include "runner/runner.h"
#include "utils/file.h"
@@ -213,6 +214,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_BUILTIN_BITWISE_OR",
"AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT",
"AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT",
+ "AST_TREE_TOKEN_BUILTIN_INSERT",
"AST_TREE_TOKEN_KEYWORD_RETURN",
"AST_TREE_TOKEN_KEYWORD_BREAK",
@@ -378,6 +380,7 @@ void astTreePrint(const AstTree *tree, int indent) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_ANY_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -834,6 +837,7 @@ void astTreeDestroy(AstTree tree) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_ANY_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1221,6 +1225,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
return newAstTree(tree->token, NULL,
copyAstTreeBack(tree->type, oldVariables, newVariables,
variables_size, safetyCheck),
@@ -1894,6 +1899,7 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots
.root = root,
.loops = NULL,
.loops_size = 0,
+ .scope = NULL,
};
if (!setAllTypes(tree, helper, NULL, NULL)) {
goto RETURN_ERROR;
@@ -1971,6 +1977,7 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots
.root = root,
.loops = NULL,
.loops_size = 0,
+ .scope = NULL,
};
if (!setAllTypes(tree, helper, NULL, NULL)) {
goto RETURN_ERROR;
@@ -2262,6 +2269,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
goto AFTER_SWITCH;
@@ -2403,6 +2411,8 @@ AstTree *astTreeParse(const ParserNode *parserNode) {
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT);
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT);
+ case PARSER_TOKEN_BUILTIN_INSERT:
+ return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_INSERT);
case PARSER_TOKEN_TYPE_TYPE:
return &AST_TREE_TYPE_TYPE;
case PARSER_TOKEN_TYPE_ANY_TYPE:
@@ -2769,6 +2779,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
printError(node->str_begin, node->str_end, "Unexpected %s",
@@ -3545,6 +3556,7 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
printError(node->str_begin, node->str_end, "Unexpected %s",
@@ -3816,6 +3828,7 @@ bool hasAnyTypeInside(AstTree *type) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -3942,6 +3955,7 @@ bool isConst(AstTree *tree) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_ANY_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -4257,6 +4271,7 @@ AstTree *makeTypeOf(AstTree *value) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_VALUE_OBJECT:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_KEYWORD_RETURN:
@@ -4348,6 +4363,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
@@ -4547,6 +4563,7 @@ AstTree *getValue(AstTree *tree, bool copy) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_ANY_TYPE:
@@ -4711,6 +4728,7 @@ bool isIntType(AstTree *type) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_CONTINUE:
@@ -4834,6 +4852,7 @@ bool isFloatType(AstTree *type) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_CONTINUE:
@@ -4992,6 +5011,7 @@ bool isEqual(AstTree *left, AstTree *right) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_CONTINUE:
@@ -5120,6 +5140,7 @@ bool setAllTypesRoot(AstTreeRoot *root) {
.root = root,
.loops = NULL,
.loops_size = 0,
+ .scope = NULL,
};
for (size_t i = 0; i < root->variables.size; ++i) {
@@ -5422,6 +5443,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesBuiltinCLibrary(tree, helper, functionCall);
case AST_TREE_TOKEN_BUILTIN_C_FUNCTION:
return setTypesBuiltinCFunction(tree, helper, functionCall);
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
+ return setTypesBuiltinInsert(tree, helper, functionCall);
case AST_TREE_TOKEN_TYPE_ARRAY:
return setTypesTypeArray(tree, helper);
case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER:
@@ -5659,8 +5682,10 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) {
return true;
}
- AstTreeVariable *variables[_helper.variables.size + metadata->arguments.size +
- metadata->scope.variables.size];
+ AstTreeVariable **variables =
+ a404m_malloc((_helper.variables.size + metadata->arguments.size +
+ metadata->scope.variables.size) *
+ sizeof(*variables));
for (size_t i = 0; i < _helper.variables.size; ++i) {
variables[i] = _helper.variables.data[i];
@@ -5674,6 +5699,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) {
.root = _helper.root,
.loops = NULL,
.loops_size = 0,
+ .scope = &metadata->scope,
};
AstTreeVariable *deps[helper.dependencies.size];
@@ -5722,6 +5748,15 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) {
if (!setTypesAstVariable(variable, helper)) {
return false;
}
+ size_t variables_capacity =
+ a404m_malloc_usable_size(helper.variables.data) /
+ sizeof(*helper.variables.data);
+ if (variables_capacity == helper.variables.size) {
+ variables_capacity += variables_capacity / 2 + 1;
+ helper.variables.data =
+ a404m_realloc(helper.variables.data,
+ variables_capacity * sizeof(*helper.variables.data));
+ }
helper.variables.data[helper.variables.size++] = variable;
}
if (!setAllTypes(expr, helper, metadata, NULL)) {
@@ -5729,6 +5764,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) {
}
}
+ free(variables);
return true;
}
@@ -5748,6 +5784,7 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper,
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = NULL,
};
if (helper.lookingType == NULL) {
return false;
@@ -5829,6 +5866,7 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = NULL,
};
for (size_t i = 0; i < metadata->parameters_size; ++i) {
@@ -5993,6 +6031,43 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
UNREACHABLE;
}
+ if (metadata->function->token == AST_TREE_TOKEN_BUILTIN_INSERT) {
+ char *code = u8ArrayToCString(metadata->parameters[0].value);
+ LexerNodeArray lexerArray = lexer(code);
+ if (lexerNodeArrayIsError(lexerArray)) {
+ UNREACHABLE;
+ }
+ ParserNode *rootParser = parser(lexerArray);
+ if (rootParser == NULL) {
+ UNREACHABLE;
+ }
+
+ ParserNodeArray *nodeArray = rootParser->metadata;
+ if (_helper.scope == NULL) {
+ if (nodeArray->size != 1) {
+ UNREACHABLE;
+ }
+ AstTree *ast = astTreeParse(nodeArray->data[0]);
+ if (ast == NULL || !setAllTypes(ast, _helper, NULL, NULL)) {
+ return false;
+ }
+ astTreeDestroy(*tree);
+ *tree = *ast;
+ free(ast);
+ } else {
+ for (size_t i = 0; i < nodeArray->size; ++i) {
+ AstTree *tree = astTreeParse(nodeArray->data[i]);
+ if (tree == NULL) {
+ return false;
+ }
+ printLog("%s", AST_TREE_TOKEN_STRINGS[tree->token]);
+ }
+ }
+ parserNodeDelete(rootParser);
+ lexerNodeArrayDestroy(lexerArray);
+ free(code);
+ }
+
return true;
}
@@ -6044,6 +6119,7 @@ bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper,
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = NULL,
};
for (size_t i = 0; i < metadata->parameters_size; ++i) {
@@ -6154,6 +6230,7 @@ bool setTypesAstVariable(AstTreeVariable *variable,
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = NULL,
};
// previously done
@@ -6301,6 +6378,7 @@ bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper _helper,
.root = _helper.root,
.loops = loops,
.loops_size = loops_size,
+ .scope = NULL,
};
if (!setAllTypes(metadata->condition, helper, function, NULL)) {
@@ -6334,7 +6412,8 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper,
AstTreeFunction *function) {
AstTreeScope *metadata = tree->metadata;
- AstTreeVariable *variables[_helper.variables.size + metadata->variables.size];
+ AstTreeVariable **variables = a404m_malloc(
+ (_helper.variables.size + metadata->variables.size) * sizeof(*variables));
for (size_t i = 0; i < _helper.variables.size; ++i) {
variables[i] = _helper.variables.data[i];
@@ -6348,6 +6427,7 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper,
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = metadata,
};
for (size_t i = 0; i < metadata->variables.size; ++i) {
@@ -6367,6 +6447,15 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper,
if (!setTypesAstVariable(variable, helper)) {
return false;
}
+ size_t variables_capacity =
+ a404m_malloc_usable_size(helper.variables.data) /
+ sizeof(*helper.variables.data);
+ if (variables_capacity == helper.variables.size) {
+ variables_capacity += variables_capacity / 2 + 1;
+ helper.variables.data =
+ a404m_realloc(helper.variables.data,
+ variables_capacity * sizeof(*helper.variables.data));
+ }
helper.variables.data[helper.variables.size++] = variable;
}
if (!setAllTypes(expr, helper, function, NULL)) {
@@ -6381,6 +6470,7 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper,
metadata->expressions[metadata->expressions_size - 1]->type);
}
+ free(variables);
return true;
}
@@ -6474,6 +6564,7 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) {
.lookingType = helper.lookingType,
.loops = helper.loops,
.loops_size = helper.loops_size,
+ .scope = NULL,
};
astTreeDelete(value);
@@ -6950,6 +7041,7 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper,
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_CONTINUE:
@@ -7532,6 +7624,65 @@ bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper,
return true;
}
+bool setTypesBuiltinInsert(AstTree *tree, AstTreeSetTypesHelper helper,
+ AstTreeFunctionCall *functionCall) {
+ (void)helper;
+ if (functionCall->parameters_size != 1) {
+ printError(tree->str_begin, tree->str_end, "Too many or too few arguments");
+ return false;
+ }
+
+ const char *str = functionCall->parameters[0].nameBegin;
+ const size_t str_size = functionCall->parameters[0].nameEnd -
+ functionCall->parameters[0].nameBegin;
+
+ static char CODE_STR[] = "code";
+ static size_t CODE_STR_SIZE =
+ sizeof(CODE_STR) / sizeof(*CODE_STR) - sizeof(*CODE_STR);
+
+ if (str_size != 0 && (str_size != CODE_STR_SIZE ||
+ !strnEquals(str, CODE_STR, CODE_STR_SIZE))) {
+ printError(functionCall->parameters[0].nameBegin,
+ functionCall->parameters[0].nameEnd, "Unknown parameter");
+ return false;
+ }
+
+ AstTree *type = functionCall->parameters[0].value->type;
+ AstTree *stringType = makeStringType();
+ if (typeIsEqual(type->type, stringType)) {
+ astTreeDelete(stringType);
+ printError(functionCall->parameters[0].nameBegin,
+ functionCall->parameters[0].nameEnd,
+ "Type mismatch it must be `code`");
+ return false;
+ } else if (!isConst(functionCall->parameters[0].value)) {
+ printError(functionCall->parameters[0].nameBegin,
+ functionCall->parameters[0].nameEnd, "Must be const");
+ return false;
+ }
+ astTreeDelete(stringType);
+
+ AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata));
+ type_metadata->arguments_size = 1;
+ type_metadata->arguments = a404m_malloc(type_metadata->arguments_size *
+ sizeof(*type_metadata->arguments));
+
+ type_metadata->returnType = copyAstTree(type);
+
+ type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){
+ .type = copyAstTree(type),
+ .name_begin = CODE_STR,
+ .name_end = CODE_STR + CODE_STR_SIZE,
+ .str_begin = NULL,
+ .str_end = NULL,
+ .isComptime = false,
+ };
+
+ tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata,
+ &AST_TREE_TYPE_TYPE, NULL, NULL);
+ return true;
+}
+
bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeBracket *metadata = tree->metadata;
@@ -7559,6 +7710,7 @@ bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
.root = helper.root,
.loops = helper.loops,
.loops_size = helper.loops_size,
+ .scope = NULL,
};
for (size_t i = 0; i < metadata->parameters.size; ++i) {
@@ -7595,6 +7747,7 @@ bool setTypesAstInfix(AstTreePureInfix *infix, AstTreeSetTypesHelper _helper) {
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = NULL,
};
if (!setAllTypes(infix->left, helper, NULL, NULL)) {
@@ -7608,8 +7761,10 @@ bool setTypesAstInfix(AstTreePureInfix *infix, AstTreeSetTypesHelper _helper) {
bool setTypesAstFunction(AstTreeFunction *metadata,
AstTreeSetTypesHelper _helper) {
- AstTreeVariable *variables[_helper.variables.size + metadata->arguments.size +
- metadata->scope.variables.size];
+ AstTreeVariable **variables =
+ a404m_malloc((_helper.variables.size + metadata->arguments.size +
+ metadata->scope.variables.size) *
+ sizeof(*variables));
for (size_t i = 0; i < _helper.variables.size; ++i) {
variables[i] = _helper.variables.data[i];
@@ -7623,6 +7778,7 @@ bool setTypesAstFunction(AstTreeFunction *metadata,
.root = _helper.root,
.loops = _helper.loops,
.loops_size = _helper.loops_size,
+ .scope = &metadata->scope,
};
AstTreeVariable *deps[helper.dependencies.size];
@@ -7669,6 +7825,15 @@ bool setTypesAstFunction(AstTreeFunction *metadata,
if (!setTypesAstVariable(variable, helper)) {
return false;
}
+ size_t variables_capacity =
+ a404m_malloc_usable_size(helper.variables.data) /
+ sizeof(*helper.variables.data);
+ if (variables_capacity == helper.variables.size) {
+ variables_capacity += variables_capacity / 2 + 1;
+ helper.variables.data =
+ a404m_realloc(helper.variables.data,
+ variables_capacity * sizeof(*helper.variables.data));
+ }
helper.variables.data[helper.variables.size++] = variable;
}
if (!setAllTypes(expr, helper, metadata, NULL)) {
@@ -7676,6 +7841,7 @@ bool setTypesAstFunction(AstTreeFunction *metadata,
}
}
+ free(variables);
return true;
}
@@ -7835,6 +8001,7 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
.root = helper.root,
.loops = helper.loops,
.loops_size = helper.loops_size,
+ .scope = NULL,
};
for (size_t i = 0; i < functionCall->parameters_size; ++i) {
@@ -8142,6 +8309,7 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata,
.dependencies = helper.dependencies,
.loops = helper.loops,
.loops_size = helper.loops_size,
+ .scope = NULL,
};
for (size_t i = 0; i < newFunction->arguments.size; ++i) {
@@ -8236,6 +8404,7 @@ size_t getSizeOfType(AstTree *type) {
case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_F32:
return 4;
+ case AST_TREE_TOKEN_TYPE_CODE:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_ANY_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -8269,7 +8438,6 @@ size_t getSizeOfType(AstTree *type) {
}
case AST_TREE_TOKEN_OPERATOR_POINTER:
return sizeof(void *);
- case AST_TREE_TOKEN_TYPE_CODE:
case AST_TREE_TOKEN_TYPE_NAMESPACE:
case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER:
case AST_TREE_TOKEN_TYPE_C_LIBRARY:
@@ -8303,6 +8471,7 @@ size_t getSizeOfType(AstTree *type) {
case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_CONTINUE:
@@ -8357,5 +8526,6 @@ size_t getSizeOfType(AstTree *type) {
case AST_TREE_TOKEN_SCOPE:
case AST_TREE_TOKEN_NONE:
}
+ printLog("%s", AST_TREE_TOKEN_STRINGS[type->token]);
UNREACHABLE;
}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 73f4462..89387f9 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -35,7 +35,8 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_BUILTIN_BITWISE_OR,
AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT,
AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT,
- AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT,
+ AST_TREE_TOKEN_BUILTIN_INSERT,
+ AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_INSERT,
AST_TREE_TOKEN_KEYWORD_RETURN,
AST_TREE_TOKEN_KEYWORD_BREAK,
@@ -284,6 +285,7 @@ typedef struct AstTreeSetTypesHelper {
AstTreeRoot *root;
AstTreeWhile **loops;
size_t loops_size;
+ AstTreeScope *scope;
} AstTreeSetTypesHelper;
typedef struct AstTreeStruct {
@@ -524,6 +526,8 @@ bool setTypesBuiltinCLibrary(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall);
bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall);
+bool setTypesBuiltinInsert(AstTree *tree, AstTreeSetTypesHelper helper,
+ AstTreeFunctionCall *functionCall);
bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesAstFunction(AstTreeFunction *function,
AstTreeSetTypesHelper helper);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 08ecc6e..9c27bac 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -39,6 +39,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_BUILTIN_BITWISE_OR",
"LEXER_TOKEN_BUILTIN_SHIFT_LEFT",
"LEXER_TOKEN_BUILTIN_SHIFT_RIGHT",
+ "LEXER_TOKEN_BUILTIN_INSERT",
"LEXER_TOKEN_KEYWORD_TYPE",
"LEXER_TOKEN_KEYWORD_ANY_TYPE",
"LEXER_TOKEN_KEYWORD_VOID",
@@ -256,6 +257,7 @@ static const char *LEXER_BUILTIN_STRINGS[] = {
"bitwise_or",
"shift_left",
"shift_right",
+ "insert",
};
static const LexerToken LEXER_BUILTIN_TOKENS[] = {
LEXER_TOKEN_BUILTIN_CAST,
@@ -286,6 +288,7 @@ static const LexerToken LEXER_BUILTIN_TOKENS[] = {
LEXER_TOKEN_BUILTIN_BITWISE_OR,
LEXER_TOKEN_BUILTIN_SHIFT_LEFT,
LEXER_TOKEN_BUILTIN_SHIFT_RIGHT,
+ LEXER_TOKEN_BUILTIN_INSERT,
};
static const size_t LEXER_BUILTIN_SIZE =
sizeof(LEXER_BUILTIN_TOKENS) / sizeof(*LEXER_BUILTIN_TOKENS);
@@ -565,6 +568,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter,
case LEXER_TOKEN_BUILTIN_BITWISE_OR:
case LEXER_TOKEN_BUILTIN_SHIFT_LEFT:
case LEXER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case LEXER_TOKEN_BUILTIN_INSERT:
case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET:
case LEXER_TOKEN_SYMBOL_OPEN_BRACKET:
case LEXER_TOKEN_KEYWORD_SHAPE_SHIFTER:
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 8d62b14..202b041 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -41,6 +41,7 @@ typedef enum LexerToken {
LEXER_TOKEN_BUILTIN_BITWISE_OR,
LEXER_TOKEN_BUILTIN_SHIFT_LEFT,
LEXER_TOKEN_BUILTIN_SHIFT_RIGHT,
+ LEXER_TOKEN_BUILTIN_INSERT,
LEXER_TOKEN_KEYWORD_TYPE,
LEXER_TOKEN_KEYWORD_ANY_TYPE,
LEXER_TOKEN_KEYWORD_VOID,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 97edae4..2f36289 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -40,6 +40,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_BUILTIN_BITWISE_OR",
"PARSER_TOKEN_BUILTIN_SHIFT_LEFT",
"PARSER_TOKEN_BUILTIN_SHIFT_RIGHT",
+ "PARSER_TOKEN_BUILTIN_INSERT",
"PARSER_TOKEN_VALUE_INT",
"PARSER_TOKEN_VALUE_FLOAT",
@@ -298,6 +299,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_ANY_TYPE:
case PARSER_TOKEN_TYPE_VOID:
@@ -621,6 +623,7 @@ void parserNodeDelete(ParserNode *node) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_ANY_TYPE:
case PARSER_TOKEN_TYPE_VOID:
@@ -972,6 +975,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SHIFT_LEFT);
case LEXER_TOKEN_BUILTIN_SHIFT_RIGHT:
return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SHIFT_RIGHT);
+ case LEXER_TOKEN_BUILTIN_INSERT:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_INSERT);
case LEXER_TOKEN_KEYWORD_TYPE:
return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE);
case LEXER_TOKEN_KEYWORD_ANY_TYPE:
@@ -1311,7 +1316,7 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
case 'I':
case 'u':
case 'U':
- goto DEFAULT;
+ goto DEFAULT;
default:
NOT_IMPLEMENTED;
}
@@ -1319,7 +1324,7 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
}
// fall through
default: {
- DEFAULT:
+ DEFAULT:
ParserNodeIntType type = getIntType(node->str_begin, node->str_end);
u64 value = decimalToU64(node->str_begin,
node->str_end - getIntTypeSize(type), &success);
@@ -1822,6 +1827,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
@@ -2366,6 +2372,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
@@ -2485,6 +2492,7 @@ bool parserIsFunction(ParserNode *node) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_OPERATOR_ACCESS:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -2639,6 +2647,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_OPERATOR_ADDRESS:
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_UNDEFINED:
@@ -2730,6 +2739,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_BUILTIN_BITWISE_OR:
case PARSER_TOKEN_BUILTIN_SHIFT_LEFT:
case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case PARSER_TOKEN_BUILTIN_INSERT:
case PARSER_TOKEN_OPERATOR_ACCESS:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 3f69454..0b89bb3 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -37,6 +37,7 @@ typedef enum ParserToken {
PARSER_TOKEN_BUILTIN_BITWISE_OR,
PARSER_TOKEN_BUILTIN_SHIFT_LEFT,
PARSER_TOKEN_BUILTIN_SHIFT_RIGHT,
+ PARSER_TOKEN_BUILTIN_INSERT,
PARSER_TOKEN_VALUE_INT,
PARSER_TOKEN_VALUE_FLOAT,