aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-31 15:09:23 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-31 15:09:23 +0330
commitca6f2ec64941953f0111a64b7acf4cf6fb31929a (patch)
tree8c0abdcd8d202cdee295e2f4247ac6d1688a09d8
parent3c53293e9b2c2f9106da805d26b5eab9dff56225 (diff)
add array access support to arrays
-rw-r--r--code/lib/io.felan8
-rw-r--r--code/lib/operator.felan14
-rw-r--r--code/main.felan11
-rw-r--r--src/compiler/ast-tree.c31
-rw-r--r--src/compiler/parser.c6
-rw-r--r--src/runner/runner.c125
-rw-r--r--src/runner/runner.h15
7 files changed, 147 insertions, 63 deletions
diff --git a/code/lib/io.felan b/code/lib/io.felan
index 3019092..ff697e2 100644
--- a/code/lib/io.felan
+++ b/code/lib/io.felan
@@ -6,10 +6,10 @@ puts :: @c_function(libc,"puts",(*u8)->i32);
putchar :: @c_function(libc,"putchar",(i32)->void);
print :: (value:string) -> void {
- i :u64= 0;
- while i < value.length {
+ i := 0;
+ while i < @cast(value.length,i64) {
print_char(value[i]);
- i += @cast(1,u64);
+ i += 1;
}
};
@@ -59,7 +59,7 @@ _print_signed :: (comptime t:type, value:t) -> i32 {
_print_unsigned :: (comptime t:type, value:t) -> void {
NUMBERS_SIZE :: 21;
- numbers : [NUMBERS_SIZE]u8 = undefined;
+ numbers := @stack_alloc(NUMBERS_SIZE,u8);
i := NUMBERS_SIZE - 1;
numbers[i] = '\0';
diff --git a/code/lib/operator.felan b/code/lib/operator.felan
index 3da070a..b7ac63a 100644
--- a/code/lib/operator.felan
+++ b/code/lib/operator.felan
@@ -790,7 +790,6 @@ __shift_right__ :: (left:i64,right:i64) -> i64 {
return @shift_right(left,right);
};
-
//---------------------- Pointers ------------------------
__sum__ :: (left:*anytype,right:i64) -> (@type_of(left)) {
@@ -813,3 +812,16 @@ __get_item_address__ :: (left:*anytype,index:i64) -> (@type_of(left)) {
return (left + index);
};
+//---------------------- Array ------------------------
+
+__get_item__ :: (left:[]anytype,index:i64) -> (@type_of(left.ptr.*)) {
+ return (left.ptr + index).*;
+};
+
+__set_item__ :: (left:[]anytype,index:i64,item:@type_of(left.ptr.*)) -> (@type_of(left.ptr.*)) {
+ return (left.ptr + index).* = item;
+};
+
+__get_item_address__ :: (left:[]anytype,index:i64) -> (@type_of(left.ptr)) {
+ return (left.ptr + index);
+};
diff --git a/code/main.felan b/code/main.felan
index b1a55b9..def8750 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -1,6 +1,7 @@
// @import("basic.felan");
-@import("lib/memory.felan");
+// @import("lib/memory.felan");
@import("lib/operator.felan");
+@import("lib/types.felan");
print :: (value:**anytype)->void{
if comptime @type_of(value.*) == u8 {
@@ -11,12 +12,8 @@ print :: (value:**anytype)->void{
};
main :: () -> void {
- a := malloc(10,u8);
- a[0] = '1';
- b := &a[2];
- b.* = '9';
+ a : [23]u8 = undefined;
+ a[0] = '2';
@putc(a[0]);
- @putc(b.*);
- free(a);
};
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 0563086..e9d6430 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -8,6 +8,7 @@
#include "utils/string.h"
#include "utils/time.h"
#include "utils/type.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -691,12 +692,13 @@ void astTreePrint(const AstTree *tree, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
- case AST_TREE_TOKEN_NONE:
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:
+ goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -2968,7 +2970,7 @@ AstTree *astTreeParseIntValue(const ParserNode *parserNode) {
case PARSER_NODE_INT_TYPE_U8: {
u8 *metadata = a404m_malloc(sizeof(*metadata));
*metadata = node_metadata->value;
- return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I8_TYPE,
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_U8_TYPE,
parserNode->str_begin, parserNode->str_end);
}
case PARSER_NODE_INT_TYPE_I16: {
@@ -2980,7 +2982,7 @@ AstTree *astTreeParseIntValue(const ParserNode *parserNode) {
case PARSER_NODE_INT_TYPE_U16: {
u16 *metadata = a404m_malloc(sizeof(*metadata));
*metadata = node_metadata->value;
- return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I16_TYPE,
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_U16_TYPE,
parserNode->str_begin, parserNode->str_end);
}
case PARSER_NODE_INT_TYPE_I32: {
@@ -2992,7 +2994,7 @@ AstTree *astTreeParseIntValue(const ParserNode *parserNode) {
case PARSER_NODE_INT_TYPE_U32: {
u32 *metadata = a404m_malloc(sizeof(*metadata));
*metadata = node_metadata->value;
- return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I32_TYPE,
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_U32_TYPE,
parserNode->str_begin, parserNode->str_end);
}
case PARSER_NODE_INT_TYPE_I64: {
@@ -3004,7 +3006,7 @@ AstTree *astTreeParseIntValue(const ParserNode *parserNode) {
case PARSER_NODE_INT_TYPE_U64: {
u64 *metadata = a404m_malloc(sizeof(*metadata));
*metadata = node_metadata->value;
- return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I64_TYPE,
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_U64_TYPE,
parserNode->str_begin, parserNode->str_end);
}
}
@@ -6411,10 +6413,21 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) {
static const char LENGTH_STR[] = "length";
static const size_t LENGTH_STR_SIZE =
sizeof(LENGTH_STR) / sizeof(*LENGTH_STR) - sizeof(*LENGTH_STR);
+ static const char PTR_STR[] = "ptr";
+ static const size_t PTR_STR_SIZE =
+ sizeof(PTR_STR) / sizeof(*PTR_STR) - sizeof(*PTR_STR);
+
if (LENGTH_STR_SIZE == size && strnEquals(LENGTH_STR, str, size)) {
- metadata->member.index = 0;
+ metadata->member.index = 1;
tree->type = copyAstTree(&AST_TREE_U64_TYPE);
return true;
+ } else if (PTR_STR_SIZE == size && strnEquals(PTR_STR, str, size)) {
+ metadata->member.index = 0;
+ AstTreeBracket *arrayType = metadata->object->type->metadata;
+ tree->type = newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER,
+ copyAstTree(arrayType->operand),
+ &AST_TREE_TYPE_TYPE, NULL, NULL);
+ return true;
}
printError(metadata->member.name.begin, metadata->member.name.end,
@@ -7516,8 +7529,14 @@ bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
printError(metadata->operand->str_begin, metadata->operand->str_end,
"Expected type");
return false;
+ } else if (!isConst(metadata->operand)) {
+ printError(metadata->operand->str_begin, metadata->operand->str_end,
+ "Epxected const");
+ return false;
}
+ metadata->operand = getValue(metadata->operand, false);
+
if (metadata->parameters.size == 0) {
// left empty
} else if (metadata->parameters.size == 1) {
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 903a8af..97edae4 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -1307,6 +1307,11 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
parserNode = newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin,
node->str_end, metadata, parent);
break;
+ case 'i':
+ case 'I':
+ case 'u':
+ case 'U':
+ goto DEFAULT;
default:
NOT_IMPLEMENTED;
}
@@ -1314,6 +1319,7 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
}
// fall through
default: {
+ DEFAULT:
ParserNodeIntType type = getIntType(node->str_begin, node->str_end);
u64 value = decimalToU64(node->str_begin,
node->str_end - getIntTypeSize(type), &success);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 432a750..59e1889 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -124,20 +124,22 @@
}
#endif
-void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value) {
+void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value,
+ AstTreeScope *scope) {
if (variable->isConst) {
printLog("Can't assign to const");
UNREACHABLE;
}
- runnerVariableSetValueWihtoutConstCheck(variable, value);
+ runnerVariableSetValueWihtoutConstCheck(variable, value, scope);
}
void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
- AstTree *value) {
+ AstTree *value,
+ AstTreeScope *scope) {
if (variable->value != NULL) {
astTreeDelete(variable->value);
}
- AstTree *raw = toRawValue(value);
+ AstTree *raw = toRawValue(value, scope);
if (raw == NULL) {
variable->value = value;
} else {
@@ -153,6 +155,16 @@ bool runAstTree(AstTreeRoots roots) {
AstTreeVariable *mainVariable = NULL;
+ AstTreeScope *scope = a404m_malloc(sizeof(*scope));
+ *scope = (AstTreeScope){
+ .expressions = a404m_malloc(0),
+ .expressions_size = 0,
+ .variables.data = a404m_malloc(0),
+ .variables.size = 0,
+ .stackAllocation = a404m_malloc(0),
+ .stackAllocation_size = 0,
+ };
+
for (size_t i = 0; i < roots.size; ++i) {
AstTreeRoot *root = roots.data[i];
for (size_t i = 0; i < root->variables.size; ++i) {
@@ -168,7 +180,8 @@ bool runAstTree(AstTreeRoots roots) {
mainVariable = variable;
}
if (!variable->isConst) {
- runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue);
+ runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue,
+ scope);
}
}
}
@@ -186,21 +199,24 @@ bool runAstTree(AstTreeRoots roots) {
return false;
}
- AstTree *res = runAstTreeFunction(main, NULL, 0, false);
+ AstTree *res = runAstTreeFunction(main, NULL, 0, scope, false);
const bool ret = res == &AST_TREE_VOID_VALUE;
astTreeDelete(res);
astTreeDelete(main);
+ astTreeDelete(
+ newAstTree(AST_TREE_TOKEN_SCOPE, scope, &AST_TREE_VOID_TYPE, NULL, NULL));
return ret;
}
AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
- size_t arguments_size, bool isComptime) {
+ size_t arguments_size, AstTreeScope *scope,
+ bool isComptime) {
AstTreeFunction *function = tree->metadata;
for (size_t i = 0; i < arguments_size; ++i) {
AstTree *param = arguments[i];
AstTreeVariable *arg = function->arguments.data[i];
- runnerVariableSetValueWihtoutConstCheck(arg, param);
+ runnerVariableSetValueWihtoutConstCheck(arg, param, scope);
}
bool shouldRet = false;
@@ -627,6 +643,7 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
*(AstTreeBool *)ret->metadata = typeIsEqual(left, right);
break;
default:
+ printLog("%s", AST_TREE_TOKEN_STRINGS[left->token]);
UNREACHABLE;
}
return ret;
@@ -1376,7 +1393,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
return args[i];
}
}
- result = runAstTreeFunction(function, args, args_size, isComptime);
+ result = runAstTreeFunction(function, args, args_size, scope, isComptime);
} else if (function->token >= AST_TREE_TOKEN_BUILTIN_BEGIN &&
function->token <= AST_TREE_TOKEN_BUILTIN_END) {
for (size_t i = 0; i < args_size; ++i) {
@@ -1443,7 +1460,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
if (right->token != AST_TREE_TOKEN_RAW_VALUE) {
UNREACHABLE;
}
- if (l->token != AST_TREE_TOKEN_RAW_VALUE ||
+ if (l->token != AST_TREE_TOKEN_RAW_VALUE &&
l->type->token != AST_TREE_TOKEN_OPERATOR_POINTER) {
UNREACHABLE;
}
@@ -1466,7 +1483,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
astTreeDelete(l);
return right;
}
- runnerVariableSetValue(left, right);
+ runnerVariableSetValue(left, right, scope);
astTreeDelete(l);
return copyAstTree(left->value);
} else if (l->token == AST_TREE_TOKEN_RAW_VALUE) {
@@ -1512,7 +1529,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
return value;
}
}
- runnerVariableSetValue(variable, value);
+ runnerVariableSetValue(variable, value, scope);
return &AST_TREE_VOID_VALUE;
}
case AST_TREE_TOKEN_KEYWORD_IF: {
@@ -1720,7 +1737,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
AstTree *value =
runExpression(variable->value, scope, shouldRet, false, isComptime,
breakCount, shouldContinue, false);
- runnerVariableSetValue(variable, value);
+ runnerVariableSetValue(variable, value, scope);
}
return copyAstTree(variable->value);
}
@@ -1728,7 +1745,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
case AST_TREE_TOKEN_OPERATOR_ACCESS: {
AstTreeAccess *metadata = expr->metadata;
AstTree *tree =
- runExpression(metadata->object, scope, shouldRet, true, isComptime,
+ runExpression(metadata->object, scope, shouldRet, false, isComptime,
breakCount, shouldContinue, false);
if (discontinue(*shouldRet, *breakCount)) {
return tree;
@@ -1779,7 +1796,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
newAstTree(AST_TREE_TOKEN_VALUE_UNDEFINED,
NULL, copyAstTree(member->type),
variable->value->str_begin,
- variable->value->str_end));
+ variable->value->str_end),
+ scope);
}
}
@@ -1787,7 +1805,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
variable,
newAstTree(AST_TREE_TOKEN_VALUE_OBJECT, newMetadata,
copyAstTree(variable->type),
- variable->value->str_begin, variable->value->str_end));
+ variable->value->str_begin, variable->value->str_end),
+ scope);
}
AstTreeObject *object = variable->value->metadata;
AstTreeVariable *var = object->variables.data[metadata->member.index];
@@ -1802,24 +1821,13 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
UNREACHABLE;
} else if (tree->token == AST_TREE_TOKEN_RAW_VALUE) {
if (tree->type->token == AST_TREE_TOKEN_TYPE_ARRAY) {
- AstTreeBracket *array_metadata = tree->type->metadata;
- if (metadata->member.index != 0) {
- UNREACHABLE;
- } else {
- if (array_metadata->parameters.size == 1) {
- AstTree *sizeTree = runExpression(
- array_metadata->parameters.data[0], scope, shouldRet, false,
- isComptime, breakCount, shouldContinue, false);
- astTreeDelete(tree);
- return sizeTree;
- } else {
- u64 *value = a404m_malloc(sizeof(*value));
- *value = a404m_malloc_usable_size(tree->metadata);
- astTreeDelete(tree);
- return newAstTree(AST_TREE_TOKEN_RAW_VALUE, value,
- &AST_TREE_U64_TYPE, NULL, NULL);
- }
- }
+ u64 *tree_value = tree->metadata;
+
+ u64 *value = a404m_malloc(sizeof(*value));
+ *value = tree_value[metadata->member.index];
+ astTreeDelete(tree);
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, value, copyAstTree(expr->type),
+ NULL, NULL);
}
size_t index = 0;
AstTreeStruct *type = tree->type->metadata;
@@ -1922,7 +1930,7 @@ bool discontinue(bool shouldRet, u32 breakCount) {
return shouldRet || breakCount > 0;
}
-AstTree *toRawValue(AstTree *value) {
+AstTree *toRawValue(AstTree *value, AstTreeScope *scope) {
switch (value->token) {
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_NULL: {
@@ -1934,9 +1942,48 @@ AstTree *toRawValue(AstTree *value) {
value->str_end);
}
case AST_TREE_TOKEN_VALUE_UNDEFINED: {
- const size_t size = getSizeOfType(value->type);
- AstTreeRawValue *rawValue = a404m_malloc(size);
- memset(rawValue, 0, size);
+ size_t size;
+ AstTreeRawValue *rawValue;
+ if (value->type->token == AST_TREE_TOKEN_TYPE_ARRAY) {
+ struct Array {
+ void *data;
+ size_t size;
+ };
+ size = sizeof(struct Array);
+ rawValue = a404m_malloc(size);
+ struct Array *array = (void *)rawValue;
+
+ AstTreeBracket *bracket = value->type->metadata;
+
+ 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));
+ }
+
+ if (bracket->parameters.size != 1) {
+ UNREACHABLE;
+ }
+
+ const size_t sizeOfType = getSizeOfType(bracket->operand);
+ const size_t size =
+ *(u64 *)bracket->parameters.data[0]->metadata * sizeOfType;
+ scope->stackAllocation[scope->stackAllocation_size] = a404m_malloc(size);
+ // memset(scope->stackAllocation[scope->stackAllocation_size], 0, size);
+
+ array->data = scope->stackAllocation[scope->stackAllocation_size];
+ array->size = *(u64 *)bracket->parameters.data[0]->metadata;
+
+ scope->stackAllocation_size += 1;
+ } else {
+ size = getSizeOfType(value->type);
+ rawValue = a404m_malloc(size);
+ memset(rawValue, 0, size);
+ }
return newAstTree(AST_TREE_TOKEN_RAW_VALUE, rawValue,
copyAstTree(value->type), value->str_begin,
value->str_end);
@@ -1981,7 +2028,7 @@ AstTree *toRawValue(AstTree *value) {
size_t filledSize = 0;
for (size_t i = 0; i < object->variables.size; ++i) {
AstTreeVariable *variable = object->variables.data[i];
- AstTree *variableValue = toRawValue(variable->value);
+ AstTree *variableValue = toRawValue(variable->value, scope);
size_t variableValueSize = getSizeOfType(variableValue);
if (variableValue == NULL) {
NOT_IMPLEMENTED;
diff --git a/src/runner/runner.h b/src/runner/runner.h
index 66ad757..16103cc 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -3,15 +3,18 @@
#include "compiler/ast-tree.h"
#include <ffi.h>
-void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value);
+void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value,
+ AstTreeScope *scope);
void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
- AstTree *value);
+ AstTree *value,
+ AstTreeScope *scope);
AstTree *runnerVariableGetValue(AstTreeVariable *variable);
bool runAstTree(AstTreeRoots roots);
AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
- size_t arguments_size, bool isComptime);
+ size_t arguments_size, AstTreeScope *scope,
+ bool isComptime);
AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
AstTree **arguments);
@@ -21,15 +24,15 @@ AstTree *runAstTreeCFunction(AstTree *tree, AstTree **arguments,
AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
bool isLeft, bool isComptime, u32 *breakCount,
- bool *shouldContinue,bool needOwnership);
+ bool *shouldContinue, bool needOwnership);
AstTree *getForVariable(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
bool isLeft, bool isComptime, u32 *breakCount,
- bool *shouldContinue, bool isLazy,bool needOwnership);
+ bool *shouldContinue, bool isLazy, bool needOwnership);
bool discontinue(bool shouldRet, u32 breakCount);
-AstTree *toRawValue(AstTree *value);
+AstTree *toRawValue(AstTree *value, AstTreeScope *scope);
AstTree *castTo(AstTree *value, AstTree *to);