diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-31 15:09:23 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-31 15:09:23 +0330 |
commit | ca6f2ec64941953f0111a64b7acf4cf6fb31929a (patch) | |
tree | 8c0abdcd8d202cdee295e2f4247ac6d1688a09d8 | |
parent | 3c53293e9b2c2f9106da805d26b5eab9dff56225 (diff) |
add array access support to arrays
-rw-r--r-- | code/lib/io.felan | 8 | ||||
-rw-r--r-- | code/lib/operator.felan | 14 | ||||
-rw-r--r-- | code/main.felan | 11 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 31 | ||||
-rw-r--r-- | src/compiler/parser.c | 6 | ||||
-rw-r--r-- | src/runner/runner.c | 125 | ||||
-rw-r--r-- | src/runner/runner.h | 15 |
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); |