aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-30 17:51:26 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-30 17:51:26 +0330
commit15fce202de10352d60c1853e7c8940b3eeca13c9 (patch)
tree88cc3d3ec947e7220bd1d684b8a28af665f07868
parenta2a6bb49368e922af28b9a54669b9f7fe5b2e6a0 (diff)
add functionality to scopeAlloc
-rw-r--r--code/main.felan28
-rw-r--r--src/compiler/ast-tree.c114
-rw-r--r--src/compiler/ast-tree.h6
-rw-r--r--src/runner/runner.c29
4 files changed, 135 insertions, 42 deletions
diff --git a/code/main.felan b/code/main.felan
index 98aa762..8e096e0 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -12,12 +12,28 @@ __sum__ :: (left:*anytype,right:i64) -> (@type_of(left)) {
return @add(left,right);
};
+__sub__ :: (left:*anytype,right:i64) -> (@type_of(left)) {
+ return @sub(left,right);
+};
+
+__get_item__ :: (left:*anytype,index:i64) -> (@type_of(left.*)) {
+ left += index;
+ return left.*;
+};
+
+__set_item__ :: (left:*anytype,index:i64,item:@type_of(left.*)) -> (@type_of(left.*)) {
+ left += index;
+ return left.* = item;
+};
+
+__get_item_address__ :: (left:*anytype,index:i64,item:@type_of(left.*)) -> (@type_of(left)) {
+ left += index;
+ return left;
+};
+
main :: ()->void{
- arr :[10]i64= undefined;
- arr[0] = 2;
- arr[1] = 3;
- p := &arr[0];
- p += 1;
- print(p.*);
+ p := @stack_alloc(i64,10);
+ __set_item__(p,1,0);
+ print(__get_item__(p,1));
};
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index fe9538f..5d2048b 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -773,7 +773,11 @@ void astTreeFunctionDestroy(AstTreeFunction function) {
for (size_t i = 0; i < function.arguments.size; ++i) {
astTreeVariableDelete(function.arguments.data[i]);
}
+ for (size_t i = 0; i < function.scope.stackAllocation_size; ++i) {
+ free(function.scope.stackAllocation[i]);
+ }
astTreeDelete(function.returnType);
+ free(function.scope.stackAllocation);
free(function.scope.expressions);
free(function.scope.variables.data);
free(function.arguments.data);
@@ -1001,6 +1005,10 @@ void astTreeDestroy(AstTree tree) {
for (size_t i = 0; i < metadata->variables.size; ++i) {
astTreeVariableDelete(metadata->variables.data[i]);
}
+ for (size_t i = 0; i < metadata->stackAllocation_size; ++i) {
+ free(metadata->stackAllocation[i]);
+ }
+ free(metadata->stackAllocation);
free(metadata->expressions);
free(metadata->variables.data);
free(metadata);
@@ -1413,6 +1421,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
copyAstTreeBack(metadata->scope.expressions[i], new_oldVariables,
new_newVariables, new_variables_size, safetyCheck);
}
+ new_metadata->scope.stackAllocation_size = 0; // TODO: change later
+ new_metadata->scope.stackAllocation = a404m_malloc(0);
return newAstTree(tree->token, new_metadata,
copyAstTreeBack(tree->type, new_oldVariables,
@@ -1526,6 +1536,9 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
new_metadata->expressions = a404m_malloc(
new_metadata->expressions_size * sizeof(*new_metadata->expressions));
+ new_metadata->stackAllocation_size = 0; // TODO: change later
+ new_metadata->stackAllocation = a404m_malloc(0);
+
const size_t new_variables_size = variables_size + 1;
AstTreeVariables new_oldVariables[new_variables_size];
AstTreeVariables new_newVariables[new_variables_size];
@@ -1762,6 +1775,9 @@ AstTreeFunction *copyAstTreeFunction(AstTreeFunction *metadata,
a404m_malloc(new_metadata->scope.expressions_size *
sizeof(*new_metadata->scope.expressions));
+ new_metadata->scope.stackAllocation_size = 0;
+ new_metadata->scope.stackAllocation = a404m_malloc(0);
+
new_oldVariables[new_variables_size - 1] = metadata->scope.variables;
new_newVariables[new_variables_size - 1] = new_metadata->scope.variables;
@@ -2593,6 +2609,8 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) {
.expressions_size = 0,
.variables.data = a404m_malloc(0),
.variables.size = 0,
+ .stackAllocation = a404m_malloc(0),
+ .stackAllocation_size = 0,
};
AstTreeFunction *function = a404m_malloc(sizeof(*function));
@@ -3308,6 +3326,8 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) {
scope->variables.size = 0;
scope->expressions = a404m_malloc(0);
scope->expressions_size = 0;
+ scope->stackAllocation = a404m_malloc(0);
+ scope->stackAllocation_size = 0;
for (size_t i = 0; i < body->size; ++i) {
const ParserNode *node = body->data[i];
@@ -3696,6 +3716,7 @@ bool hasAnyTypeInside(AstTree *type) {
return hasAnyTypeInside(metadata->operand);
}
case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
return false;
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_RETURN:
@@ -3705,7 +3726,6 @@ bool hasAnyTypeInside(AstTree *type) {
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_KEYWORD_STRUCT:
- 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:
@@ -4463,6 +4483,8 @@ AstTree *getValue(AstTree *tree, bool copy) {
scope->expressions_size = 0;
scope->variables.data = a404m_malloc(0);
scope->variables.size = 0;
+ scope->stackAllocation = a404m_malloc(0);
+ scope->stackAllocation_size = 0;
AstTree scopeTree = {
.token = AST_TREE_TOKEN_SCOPE,
@@ -5122,10 +5144,10 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesOperatorGeneral(tree, helper, STR_MINUS, STR_MINUS_SIZE);
case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
return setTypesOperatorGeneral(tree, helper, STR_LOGICAL_NOT,
- STR_LOGICAL_NOT_SIZE);
+ STR_LOGICAL_NOT_SIZE);
case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT:
return setTypesOperatorGeneral(tree, helper, STR_BITWISE_NOT,
- STR_BITWISE_NOT_SIZE);
+ STR_BITWISE_NOT_SIZE);
case AST_TREE_TOKEN_OPERATOR_SUM:
return setTypesOperatorGeneral(tree, helper, STR_SUM, STR_SUM_SIZE);
case AST_TREE_TOKEN_OPERATOR_SUB:
@@ -5140,38 +5162,38 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesOperatorGeneral(tree, helper, STR_EQUAL, STR_EQUAL_SIZE);
case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
return setTypesOperatorGeneral(tree, helper, STR_NOT_EQUAL,
- STR_NOT_EQUAL_SIZE);
+ STR_NOT_EQUAL_SIZE);
case AST_TREE_TOKEN_OPERATOR_GREATER:
return setTypesOperatorGeneral(tree, helper, STR_GREATER, STR_GREATER_SIZE);
case AST_TREE_TOKEN_OPERATOR_SMALLER:
return setTypesOperatorGeneral(tree, helper, STR_SMALLER, STR_SMALLER_SIZE);
case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
return setTypesOperatorGeneral(tree, helper, STR_GREATER_OR_EQUAL,
- STR_GREATER_OR_EQUAL_SIZE);
+ STR_GREATER_OR_EQUAL_SIZE);
case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
return setTypesOperatorGeneral(tree, helper, STR_SMALLER_OR_EQUAL,
- STR_SMALLER_OR_EQUAL_SIZE);
+ STR_SMALLER_OR_EQUAL_SIZE);
case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND:
return setTypesOperatorGeneral(tree, helper, STR_LOGICAL_AND,
- STR_LOGICAL_AND_SIZE);
+ STR_LOGICAL_AND_SIZE);
case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR:
return setTypesOperatorGeneral(tree, helper, STR_LOGICAL_OR,
- STR_LOGICAL_OR_SIZE);
+ STR_LOGICAL_OR_SIZE);
case AST_TREE_TOKEN_OPERATOR_BITWISE_AND:
return setTypesOperatorGeneral(tree, helper, STR_BITWISE_AND,
- STR_BITWISE_AND_SIZE);
+ STR_BITWISE_AND_SIZE);
case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR:
return setTypesOperatorGeneral(tree, helper, STR_BITWISE_XOR,
- STR_BITWISE_XOR_SIZE);
+ STR_BITWISE_XOR_SIZE);
case AST_TREE_TOKEN_OPERATOR_BITWISE_OR:
return setTypesOperatorGeneral(tree, helper, STR_BITWISE_OR,
- STR_BITWISE_OR_SIZE);
+ STR_BITWISE_OR_SIZE);
case AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT:
return setTypesOperatorGeneral(tree, helper, STR_SHIFT_LEFT,
- STR_SHIFT_LEFT_SIZE);
+ STR_SHIFT_LEFT_SIZE);
case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT:
return setTypesOperatorGeneral(tree, helper, STR_SHIFT_RIGHT,
- STR_SHIFT_RIGHT_SIZE);
+ STR_SHIFT_RIGHT_SIZE);
case AST_TREE_TOKEN_OPERATOR_POINTER:
return setTypesOperatorPointer(tree, helper);
case AST_TREE_TOKEN_OPERATOR_ADDRESS:
@@ -5850,7 +5872,7 @@ bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper) {
}
bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper,
- const char *str, size_t str_size) {
+ const char *str, size_t str_size) {
AstTreeFunctionCall *metadata = tree->metadata;
AstTreeSetTypesHelper helper = {
@@ -6588,29 +6610,39 @@ bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper) {
bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall) {
(void)helper;
- if (functionCall->parameters_size == 1) {
- AstTree *size = NULL;
+ if (functionCall->parameters_size == 2) {
+ AstTree *type = NULL;
+ AstTree *count = NULL;
- static const char SIZE_STR[] = "size";
- static const size_t SIZE_STR_SIZE =
- sizeof(SIZE_STR) / sizeof(*SIZE_STR) - sizeof(*SIZE_STR);
+ static const char TYPE_STR[] = "type";
+ static const size_t TYPE_STR_SIZE =
+ sizeof(TYPE_STR) / sizeof(*TYPE_STR) - sizeof(*TYPE_STR);
+ static const char COUNT_STR[] = "count";
+ static const size_t COUNT_STR_SIZE =
+ sizeof(COUNT_STR) / sizeof(*COUNT_STR) - sizeof(*COUNT_STR);
for (size_t i = 0; i < functionCall->parameters_size; ++i) {
AstTreeFunctionCallParam param = functionCall->parameters[i];
const size_t param_name_size = param.nameEnd - param.nameBegin;
if (param_name_size == 0) {
- if (size == NULL) {
- size = param.value;
+ if (type == NULL) {
+ type = param.value;
+ } else if (count == NULL) {
+ count = param.value;
} else {
printError(param.value->str_begin, param.value->str_end,
"Bad paramter");
return false;
}
- } else if (param_name_size == SIZE_STR_SIZE &&
- strnEquals(param.nameBegin, SIZE_STR, SIZE_STR_SIZE) &&
- size == NULL) {
- size = param.value;
+ } else if (param_name_size == COUNT_STR_SIZE &&
+ strnEquals(param.nameBegin, COUNT_STR, COUNT_STR_SIZE) &&
+ count == NULL) {
+ count = param.value;
+ } else if (param_name_size == TYPE_STR_SIZE &&
+ strnEquals(param.nameBegin, TYPE_STR, TYPE_STR_SIZE) &&
+ type == NULL) {
+ type = param.value;
} else {
printError(param.value->str_begin, param.value->str_end,
"Bad paramter");
@@ -6618,27 +6650,41 @@ bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper,
}
}
- if (size == NULL) {
+ if (count == NULL || type == NULL) {
+ return false;
+ } else if (!typeIsEqual(count->type, &AST_TREE_I64_TYPE) &&
+ !typeIsEqual(count->type, &AST_TREE_U64_TYPE)) {
+ printError(count->str_begin, count->str_end,
+ "Type missmatch, the argument should be `u64` or `i64`");
return false;
- } else if (!typeIsEqual(size->type, &AST_TREE_U64_TYPE)) {
- printError(size->str_begin, size->str_end,
- "Type missmatch, the argument should be `u64`");
+ } else if (!typeIsEqual(type->type, &AST_TREE_TYPE_TYPE)) {
+ printError(type->str_begin, type->str_end,
+ "Type missmatch, the argument should be `type`");
return false;
}
AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata));
- type_metadata->arguments_size = 1;
+ type_metadata->arguments_size = 2;
type_metadata->arguments = a404m_malloc(type_metadata->arguments_size *
sizeof(*type_metadata->arguments));
type_metadata->returnType =
- newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, &AST_TREE_VOID_TYPE,
+ newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, copyAstTree(type),
&AST_TREE_TYPE_TYPE, NULL, NULL);
type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){
- .type = copyAstTree(&AST_TREE_TYPE_TYPE),
- .name_begin = SIZE_STR,
- .name_end = SIZE_STR + SIZE_STR_SIZE,
+ .type = copyAstTree(type->type),
+ .name_begin = COUNT_STR,
+ .name_end = COUNT_STR + COUNT_STR_SIZE,
+ .str_begin = NULL,
+ .str_end = NULL,
+ .isComptime = false,
+ };
+
+ type_metadata->arguments[1] = (AstTreeTypeFunctionArgument){
+ .type = copyAstTree(count->type),
+ .name_begin = TYPE_STR,
+ .name_end = TYPE_STR + TYPE_STR_SIZE,
.str_begin = NULL,
.str_end = NULL,
.isComptime = false,
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 8d63667..6979201 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -202,6 +202,8 @@ typedef struct AstTreeScope {
AstTreeVariables variables;
AstTree **expressions;
size_t expressions_size;
+ u8 **stackAllocation;
+ size_t stackAllocation_size;
} AstTreeScope;
typedef struct AstTreeFunction {
@@ -410,7 +412,7 @@ AstTree *astTreeParseLoopControl(const ParserNode *parserNode,
AstTreeToken token);
AstTree *astTreeParseReturn(const ParserNode *parserNode);
AstTree *astTreeParsePureBinaryOperator(const ParserNode *parserNode,
- AstTreeToken token);
+ AstTreeToken token);
AstTree *astTreeParseBinaryOperator(const ParserNode *parserNode,
AstTreeToken token);
AstTree *astTreeParseUnaryOperator(const ParserNode *parserNode,
@@ -470,7 +472,7 @@ bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall);
bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper helper,
- const char *str, size_t str_size);
+ const char *str, size_t str_size);
bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorAddress(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorDereference(AstTree *tree, AstTreeSetTypesHelper helper);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index d0a9498..30fd555 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -1221,6 +1221,35 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
return newAstTree(AST_TREE_TOKEN_VALUE_C_FUNCTION, metadata,
copyAstTree(function->returnType), NULL, NULL);
}
+ case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: {
+ AstTree *type = arguments[0];
+ AstTree *count = arguments[1];
+
+ size_t stackAllocation_capacity =
+ a404m_malloc_usable_size(scope->stackAllocation) /
+ sizeof(*scope->stackAllocation);
+ if (scope->stackAllocation_size == stackAllocation_capacity) {
+ stackAllocation_capacity += stackAllocation_capacity / 2 + 1;
+ scope->stackAllocation = a404m_realloc(
+ scope->stackAllocation,
+ stackAllocation_capacity * sizeof(*scope->stackAllocation));
+ }
+
+ const size_t sizeOfType = getSizeOfType(type);
+ const size_t size = *(u64 *)count->metadata * sizeOfType;
+ scope->stackAllocation[scope->stackAllocation_size] = a404m_malloc(size);
+ memset(scope->stackAllocation[scope->stackAllocation_size], 0, size);
+
+ AstTreeRawValue *value = a404m_malloc(sizeof(void *));
+ *(void **)value = scope->stackAllocation[scope->stackAllocation_size];
+
+ scope->stackAllocation_size += 1;
+
+ AstTreeTypeFunction *tree_type = tree->type->metadata;
+
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, value,
+ copyAstTree(tree_type->returnType), NULL, NULL);
+ }
case AST_TREE_TOKEN_BUILTIN_IMPORT:
default:
}