summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-14 12:55:08 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-14 12:55:08 +0330
commit038bbfc95cf79e1be48b1926e9893e2a12a3b92a (patch)
tree7cfcf33b7f431acbb2edb4201dfc30f7e08acf3d /src
parentf6a2a2ed20376f6ba677248b0dcf5d0ddceaeef7 (diff)
add arrays
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c386
-rw-r--r--src/compiler/ast-tree.h13
-rw-r--r--src/compiler/lexer.c12
-rw-r--r--src/compiler/lexer.h3
-rw-r--r--src/compiler/parser.c178
-rw-r--r--src/compiler/parser.h11
-rw-r--r--src/runner/runner.c75
7 files changed, 667 insertions, 11 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 04f8d54..1ac05e1 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -5,6 +5,7 @@
#include "utils/log.h"
#include "utils/memory.h"
#include "utils/string.h"
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -119,6 +120,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_KEYWORD_STRUCT",
"AST_TREE_TOKEN_TYPE_FUNCTION",
+ "AST_TREE_TOKEN_TYPE_ARRAY",
"AST_TREE_TOKEN_TYPE_TYPE",
"AST_TREE_TOKEN_TYPE_VOID",
"AST_TREE_TOKEN_TYPE_I8",
@@ -166,6 +168,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_OPERATOR_ADDRESS",
"AST_TREE_TOKEN_OPERATOR_DEREFERENCE",
"AST_TREE_TOKEN_OPERATOR_ACCESS",
+ "AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS",
"AST_TREE_TOKEN_SCOPE",
@@ -491,6 +494,28 @@ void astTreePrint(const AstTree *tree, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = tree->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("operand=\n");
+ astTreePrint(metadata->operand, indent + 1);
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("paramters=[\n");
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ AstTree *param = metadata->parameters.data[i];
+ astTreePrint(param, indent + 2);
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("]");
+ }
+ goto RETURN_SUCCESS;
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -730,6 +755,17 @@ void astTreeDestroy(AstTree tree) {
free(metadata);
}
return;
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = tree.metadata;
+ astTreeDelete(metadata->operand);
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ astTreeDelete(metadata->parameters.data[i]);
+ }
+ free(metadata->parameters.data);
+ free(metadata);
+ }
+ return;
case AST_TREE_TOKEN_NONE:
}
printLog("token = %d", tree.token);
@@ -905,8 +941,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
AstTreeInfix *metadata = tree->metadata;
AstTreeInfix *new_metadata = a404m_malloc(sizeof(*new_metadata));
- new_metadata->left = copyAstTreeBack(
- metadata->left, oldVariables, newVariables, variables_size);
+ new_metadata->left = copyAstTreeBack(metadata->left, oldVariables,
+ newVariables, variables_size);
new_metadata->right = copyAstTreeBack(metadata->right, oldVariables,
newVariables, variables_size);
return newAstTree(
@@ -1115,6 +1151,29 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size),
tree->str_begin, tree->str_end);
}
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = tree->metadata;
+ AstTreeBracket *new_metadata = a404m_malloc(sizeof(*new_metadata));
+
+ new_metadata->operand = copyAstTreeBack(metadata->operand, oldVariables,
+ newVariables, variables_size);
+
+ new_metadata->parameters.size = metadata->parameters.size;
+ new_metadata->parameters.data = a404m_malloc(
+ sizeof(*new_metadata->parameters.data) * new_metadata->parameters.size);
+
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ new_metadata->parameters.data[i] =
+ copyAstTreeBack(metadata->parameters.data[i], oldVariables,
+ newVariables, variables_size);
+ }
+
+ return newAstTree(
+ tree->token, new_metadata,
+ copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size),
+ tree->str_begin, tree->str_end);
+ }
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token %d", tree->token);
@@ -1314,6 +1373,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_BUILTIN:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
goto AFTER_SWITCH;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_KEYWORD_PUTC:
@@ -1593,6 +1654,11 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseParenthesis(parserNode, helper);
case PARSER_TOKEN_KEYWORD_STRUCT:
return astTreeParseStruct(parserNode, helper);
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ return astTreeParseBracket(parserNode, helper, AST_TREE_TOKEN_TYPE_ARRAY);
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
+ return astTreeParseBracket(parserNode, helper,
+ AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS);
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_NONE:
@@ -1744,6 +1810,8 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
case PARSER_TOKEN_OPERATOR_LOGICAL_AND:
case PARSER_TOKEN_OPERATOR_LOGICAL_OR:
case PARSER_TOKEN_BUILTIN:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
printError(node->str_begin, node->str_end, "Unexpected %s",
PARSER_TOKEN_STRINGS[node->token]);
goto RETURN_ERROR;
@@ -2079,8 +2147,11 @@ RETURN_ERROR:
AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
- if (node_metadata->value == NULL ||
- node_metadata->name->token != PARSER_TOKEN_IDENTIFIER) {
+ if (node_metadata->value == NULL) {
+ printError(parserNode->str_begin, parserNode->str_end,
+ "Must have a value (or use undefined)");
+ return NULL;
+ } else if (node_metadata->name->token != PARSER_TOKEN_IDENTIFIER) {
printError(parserNode->str_begin, parserNode->str_end, "Not supported");
return NULL;
}
@@ -2279,6 +2350,8 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
case PARSER_TOKEN_OPERATOR_LOGICAL_AND:
case PARSER_TOKEN_OPERATOR_LOGICAL_OR:
case PARSER_TOKEN_BUILTIN:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
printError(node->str_begin, node->str_end, "Unexpected %s",
PARSER_TOKEN_STRINGS[node->token]);
goto RETURN_ERROR;
@@ -2433,6 +2506,32 @@ AstTree *astTreeParseBuiltin(ParserNode *parserNode, AstTreeHelper *helper) {
parserNode->str_begin, parserNode->str_end);
}
+AstTree *astTreeParseBracket(ParserNode *parserNode, AstTreeHelper *helper,
+ AstTreeToken token) {
+ ParserNodeBracketMetadata *node_metadata = parserNode->metadata;
+
+ AstTreeBracket *metadata = a404m_malloc(sizeof(*metadata));
+
+ metadata->operand = astTreeParse(node_metadata->operand, helper);
+
+ metadata->parameters.size = node_metadata->params->size;
+ metadata->parameters.data = a404m_malloc(sizeof(*metadata->parameters.data) *
+ metadata->parameters.size);
+
+ for (size_t i = 0; i < node_metadata->params->size; ++i) {
+ ParserNode *node_param = node_metadata->params->data[i];
+
+ if (node_param->token == PARSER_TOKEN_SYMBOL_COMMA) {
+ node_param = (ParserNodeSingleChildMetadata *)node_param->metadata;
+ }
+
+ metadata->parameters.data[i] = astTreeParse(node_param, helper);
+ }
+
+ return newAstTree(token, metadata, NULL, parserNode->str_begin,
+ parserNode->str_end);
+}
+
bool isFunction(AstTree *value) {
return value->type->token == AST_TREE_TOKEN_TYPE_FUNCTION;
}
@@ -2534,6 +2633,16 @@ bool isConst(AstTree *tree) {
AstTreeAccess *metadata = tree->metadata;
return isConst(metadata->object);
}
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = tree->metadata;
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ if (!isConst(metadata->parameters.data[i])) {
+ return false;
+ }
+ }
+ return isConst(metadata->operand);
+ }
case AST_TREE_TOKEN_NONE:
}
printLog("Unknown token '%d'", tree->token);
@@ -2638,6 +2747,16 @@ bool isConstByValue(AstTree *tree) {
AstTreeAccess *metadata = tree->metadata;
return isConstByValue(metadata->object);
}
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = tree->metadata;
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ if (!isConstByValue(metadata->parameters.data[i])) {
+ return false;
+ }
+ }
+ return isConstByValue(metadata->operand);
+ }
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -2665,6 +2784,7 @@ AstTree *makeTypeOf(AstTree *value) {
case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_OPERATOR_POINTER:
case AST_TREE_TOKEN_KEYWORD_STRUCT:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
return &AST_TREE_TYPE_TYPE;
case AST_TREE_TOKEN_OPERATOR_ADDRESS: {
AstTreeSingleChild *metadata = value->metadata;
@@ -2760,6 +2880,11 @@ AstTree *makeTypeOf(AstTree *value) {
}
UNREACHABLE;
}
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = value->metadata;
+
+ return copyAstTree(metadata->operand);
+ }
case AST_TREE_TOKEN_BUILTIN:
case AST_TREE_TOKEN_VALUE_OBJECT:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
@@ -2835,6 +2960,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_OPERATOR_ACCESS:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
return false;
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -2855,15 +2981,36 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_TYPE_F128:
return type1->token == type0->token;
case AST_TREE_TOKEN_OPERATOR_POINTER: {
- if (type1->token != AST_TREE_TOKEN_OPERATOR_POINTER) {
+ if (type1->token != type0->token) {
return false;
}
AstTreeSingleChild *type0_metadata = type0->metadata;
AstTreeSingleChild *type1_metadata = type1->metadata;
return typeIsEqual(type0_metadata, type1_metadata);
}
+ case AST_TREE_TOKEN_TYPE_ARRAY: {
+ if (type1->token != type0->token)
+ return false;
+
+ AstTreeBracket *type0_metadata = type0->metadata;
+ AstTreeBracket *type1_metadata = type1->metadata;
+
+ if (!typeIsEqual(type0_metadata->operand, type1_metadata->operand) ||
+ type0_metadata->parameters.size != type1_metadata->parameters.size) {
+ return false;
+ }
+
+ for (size_t i = 0; i < type0_metadata->parameters.size; ++i) {
+ if (!isEqual(type0_metadata->parameters.data[i],
+ type1_metadata->parameters.data[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
case AST_TREE_TOKEN_TYPE_FUNCTION:
- if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) {
+ if (type1->token != type0->token) {
return false;
}
AstTreeTypeFunction *type0_metadata = type0->metadata;
@@ -2882,7 +3029,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
}
return true;
case AST_TREE_TOKEN_KEYWORD_STRUCT: {
- if (type1->token != AST_TREE_TOKEN_KEYWORD_STRUCT)
+ if (type1->token != type0->token)
return false;
AstTreeStruct *type0_metadata = type0->metadata;
@@ -2966,7 +3113,9 @@ AstTree *getValue(AstTree *tree) {
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
- case AST_TREE_TOKEN_SCOPE: {
+ case AST_TREE_TOKEN_SCOPE:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
bool shouldRet = false;
AstTree *value = runExpression(tree, &shouldRet, false);
if (value == NULL) {
@@ -2986,6 +3135,147 @@ AstTree *getValue(AstTree *tree) {
UNREACHABLE;
}
+bool isIntType(AstTree *type) {
+ switch (type->token) {
+ case AST_TREE_TOKEN_TYPE_I8:
+ case AST_TREE_TOKEN_TYPE_U8:
+ case AST_TREE_TOKEN_TYPE_I16:
+ case AST_TREE_TOKEN_TYPE_U16:
+ case AST_TREE_TOKEN_TYPE_I32:
+ case AST_TREE_TOKEN_TYPE_U32:
+ case AST_TREE_TOKEN_TYPE_I64:
+ case AST_TREE_TOKEN_TYPE_U64:
+ return true;
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_BUILTIN:
+ case AST_TREE_TOKEN_KEYWORD_PUTC:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_IF:
+ case AST_TREE_TOKEN_KEYWORD_WHILE:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
+ case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_VALUE_VOID:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_VALUE_NULL:
+ case AST_TREE_TOKEN_VALUE_UNDEFINED:
+ case AST_TREE_TOKEN_VALUE_INT:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
+ case AST_TREE_TOKEN_VALUE_BOOL:
+ case AST_TREE_TOKEN_VALUE_OBJECT:
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_PLUS:
+ case AST_TREE_TOKEN_OPERATOR_MINUS:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
+ case AST_TREE_TOKEN_OPERATOR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_GREATER:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER:
+ case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_POINTER:
+ case AST_TREE_TOKEN_OPERATOR_ADDRESS:
+ case AST_TREE_TOKEN_OPERATOR_DEREFERENCE:
+ case AST_TREE_TOKEN_OPERATOR_ACCESS:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
+ case AST_TREE_TOKEN_SCOPE:
+ return false;
+ case AST_TREE_TOKEN_NONE:
+ }
+ UNREACHABLE;
+}
+
+bool isEqual(AstTree *left, AstTree *right) {
+ if (left->token != right->token) {
+ return false;
+ }
+ switch (left->token) {
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_I8:
+ case AST_TREE_TOKEN_TYPE_U8:
+ case AST_TREE_TOKEN_TYPE_I16:
+ case AST_TREE_TOKEN_TYPE_U16:
+ case AST_TREE_TOKEN_TYPE_I32:
+ case AST_TREE_TOKEN_TYPE_U32:
+ case AST_TREE_TOKEN_TYPE_I64:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
+ case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_VALUE_VOID:
+ return true;
+ case AST_TREE_TOKEN_VALUE_INT: {
+ AstTreeInt *left_metadata = left->metadata;
+ AstTreeInt *right_metadata = right->metadata;
+
+ return *left_metadata == *right_metadata;
+ }
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_BUILTIN:
+ case AST_TREE_TOKEN_KEYWORD_PUTC:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_IF:
+ case AST_TREE_TOKEN_KEYWORD_WHILE:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_VALUE_NULL:
+ case AST_TREE_TOKEN_VALUE_UNDEFINED:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
+ case AST_TREE_TOKEN_VALUE_BOOL:
+ case AST_TREE_TOKEN_VALUE_OBJECT:
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_PLUS:
+ case AST_TREE_TOKEN_OPERATOR_MINUS:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
+ case AST_TREE_TOKEN_OPERATOR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_GREATER:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER:
+ case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_POINTER:
+ case AST_TREE_TOKEN_OPERATOR_ADDRESS:
+ case AST_TREE_TOKEN_OPERATOR_DEREFERENCE:
+ case AST_TREE_TOKEN_OPERATOR_ACCESS:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND:
+ case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR:
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
+ case AST_TREE_TOKEN_SCOPE:
+ case AST_TREE_TOKEN_NONE:
+ }
+ UNREACHABLE;
+}
+
bool setAllTypesRoot(AstTreeRoot *root) {
AstTreeSetTypesHelper setTypesHelper = {
.lookingType = NULL,
@@ -3109,6 +3399,10 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesOperatorAccess(tree, helper);
case AST_TREE_TOKEN_BUILTIN:
return setTypesBuiltin(tree, helper, functionCall);
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ return setTypesTypeArray(tree, helper);
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
+ return setTypesArrayAccess(tree, helper);
case AST_TREE_TOKEN_NONE:
}
printError(tree->str_begin, tree->str_end, "Unknown token %d", tree->token);
@@ -4169,6 +4463,82 @@ bool setTypesBuiltin(AstTree *tree, AstTreeSetTypesHelper helper,
UNREACHABLE;
}
+bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
+ AstTreeBracket *metadata = tree->metadata;
+
+ if (!setAllTypes(metadata->operand, helper, NULL, NULL)) {
+ return false;
+ } else if (!typeIsEqual(metadata->operand->type, &AST_TREE_TYPE_TYPE)) {
+ printError(metadata->operand->str_begin, metadata->operand->str_end,
+ "Expected type");
+ return false;
+ }
+
+ if (metadata->parameters.size != 1) {
+ printError(tree->str_begin, tree->str_end,
+ "Multiple param in array is not yet supported");
+ return false;
+ }
+
+ AstTreeSetTypesHelper newHelper = {
+ .lookingType = &AST_TREE_U64_TYPE,
+ .dependencies = helper.dependencies,
+ };
+
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ AstTree *param = metadata->parameters.data[i];
+ if (!setAllTypes(param, newHelper, NULL, NULL)) {
+ return false;
+ } else if (!isIntType(param->type)) {
+ printError(param->str_begin, param->str_end,
+ "Should only be int (for now)");
+ return false;
+ }
+ }
+
+ tree->type = copyAstTree(&AST_TREE_TYPE_TYPE);
+ return true;
+}
+
+bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper _helper) {
+ AstTreeBracket *metadata = tree->metadata;
+
+ AstTreeSetTypesHelper helper = {
+ .lookingType = NULL,
+ .dependencies = _helper.dependencies,
+ };
+
+ if (!setAllTypes(metadata->operand, helper, NULL, NULL)) {
+ return false;
+ } else if (metadata->operand->type->token != AST_TREE_TOKEN_TYPE_ARRAY) {
+ printError(metadata->operand->str_begin, metadata->operand->str_end,
+ "Expected array");
+ return false;
+ }
+
+ if (metadata->parameters.size != 1) {
+ printError(tree->str_begin, tree->str_end,
+ "Multiple param in array is not yet supported");
+ return false;
+ }
+
+ for (size_t i = 0; i < metadata->parameters.size; ++i) {
+ AstTree *param = metadata->parameters.data[i];
+ if (!setAllTypes(param, helper, NULL, NULL)) {
+ return false;
+ } else if (!isIntType(param->type)) {
+ printError(param->str_begin, param->str_end,
+ "Should only be int (for now)");
+ return false;
+ }
+ }
+
+ AstTreeBracket *operand_metadata = metadata->operand->type->metadata;
+
+ tree->type = copyAstTree(operand_metadata->operand);
+ return true;
+}
+
bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper _helper) {
AstTreeSetTypesHelper helper = {
.lookingType = NULL,
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 1605328..1c39ecb 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -17,6 +17,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_KEYWORD_STRUCT,
AST_TREE_TOKEN_TYPE_FUNCTION,
+ AST_TREE_TOKEN_TYPE_ARRAY,
AST_TREE_TOKEN_TYPE_TYPE,
AST_TREE_TOKEN_STATIC_VARS_BEGIN = AST_TREE_TOKEN_TYPE_TYPE,
AST_TREE_TOKEN_TYPE_VOID,
@@ -69,6 +70,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT,
AST_TREE_TOKEN_OPERATOR_LOGICAL_AND,
AST_TREE_TOKEN_OPERATOR_LOGICAL_OR,
+ AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS,
AST_TREE_TOKEN_SCOPE,
@@ -235,6 +237,11 @@ typedef struct AstTreeAccess {
} member;
} AstTreeAccess;
+typedef struct AstTreeBracket {
+ AstTree *operand;
+ AstTrees parameters;
+} AstTreeBracket;
+
typedef enum AstTreeBuiltinToken {
AST_TREE_BUILTIN_TOKEN_CAST,
AST_TREE_BUILTIN_TOKEN_TYPE_OF,
@@ -307,6 +314,8 @@ AstTree *astTreeParseStruct(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseAccessOperator(ParserNode *parserNode,
AstTreeHelper *helper, AstTreeToken token);
AstTree *astTreeParseBuiltin(ParserNode *parserNode, AstTreeHelper *helper);
+AstTree *astTreeParseBracket(ParserNode *parserNode, AstTreeHelper *helper,
+ AstTreeToken token);
bool isFunction(AstTree *value);
bool isConst(AstTree *tree);
@@ -315,6 +324,8 @@ AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(AstTree *type0, AstTree *type1);
bool typeIsEqualBack(const AstTree *type0, const AstTree *type1);
AstTree *getValue(AstTree *tree);
+bool isIntType(AstTree *type);
+bool isEqual(AstTree *left, AstTree *right);
bool setAllTypesRoot(AstTreeRoot *root);
bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
@@ -359,6 +370,8 @@ bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesBuiltin(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall);
+bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper);
+bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesAstVariable(AstTreeVariable *variable,
AstTreeSetTypesHelper helper);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 43502aa..53d9f05 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -12,6 +12,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET",
"LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS",
+ "LEXER_TOKEN_SYMBOL_CLOSE_BRACKET",
"LEXER_TOKEN_IDENTIFIER",
"LEXER_TOKEN_BUILTIN",
"LEXER_TOKEN_KEYWORD_TYPE",
@@ -41,6 +42,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL_FUNCTION_ARROW",
"LEXER_TOKEN_SYMBOL_POINTER",
"LEXER_TOKEN_KEYWORD_STRUCT",
+ "LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT",
"LEXER_TOKEN_SYMBOL_DEREFERENCE",
"LEXER_TOKEN_SYMBOL_ACCESS",
@@ -90,6 +92,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL",
"LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS",
+ "LEXER_TOKEN_SYMBOL_OPEN_BRACKET",
"LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET",
"LEXER_TOKEN_NONE",
@@ -98,7 +101,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
const char *LEXER_SYMBOL_STRINGS[] = {
";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=",
"/=", "%=", ",", "+", "-", "*", "/", "%", "==", "!=", ">",
- ">=", "<", "<=", "&", ".*", ".", "!", "&&", "||",
+ ">=", "<", "<=", "&", ".*", ".", "!", "&&", "||", "[", "]",
};
const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_EOL,
@@ -132,6 +135,8 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_LOGICAL_NOT,
LEXER_TOKEN_SYMBOL_LOGICAL_AND,
LEXER_TOKEN_SYMBOL_LOGICAL_OR,
+ LEXER_TOKEN_SYMBOL_OPEN_BRACKET,
+ LEXER_TOKEN_SYMBOL_CLOSE_BRACKET,
};
const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
@@ -387,6 +392,8 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_SYMBOL_LOGICAL_AND:
case LEXER_TOKEN_SYMBOL_LOGICAL_OR:
case LEXER_TOKEN_BUILTIN:
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET:
+ case LEXER_TOKEN_SYMBOL_OPEN_BRACKET:
if (*array_size == array->size) {
*array_size += 1 + *array_size / 2;
array->data =
@@ -401,6 +408,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
array->size += 1;
// goto RETURN_SUCCESS;
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT:
case LEXER_TOKEN_NONE:
goto RETURN_SUCCESS;
}
@@ -436,6 +444,8 @@ bool isSymbol(char c) {
case ',':
case '(':
case ')':
+ case '[':
+ case ']':
case '{':
case '}':
return true;
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index d7145e1..ad82b5a 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -10,6 +10,7 @@ typedef enum LexerToken {
LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS,
LEXER_TOKEN_ORDER1 = LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS,
+ LEXER_TOKEN_SYMBOL_CLOSE_BRACKET,
LEXER_TOKEN_IDENTIFIER,
LEXER_TOKEN_BUILTIN,
LEXER_TOKEN_KEYWORD_TYPE,
@@ -40,6 +41,7 @@ typedef enum LexerToken {
LEXER_TOKEN_ORDER2 = LEXER_TOKEN_SYMBOL_FUNCTION_ARROW,
LEXER_TOKEN_SYMBOL_POINTER,
LEXER_TOKEN_KEYWORD_STRUCT,
+ LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT,
LEXER_TOKEN_SYMBOL_DEREFERENCE,
LEXER_TOKEN_ORDER3 = LEXER_TOKEN_SYMBOL_DEREFERENCE,
@@ -101,6 +103,7 @@ typedef enum LexerToken {
LEXER_TOKEN_SYMBOL,
LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS,
+ LEXER_TOKEN_SYMBOL_OPEN_BRACKET,
LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET,
LEXER_TOKEN_NONE,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index ba8f20a..ae2db33 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -53,6 +53,8 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_SYMBOL_EOL",
"PARSER_TOKEN_SYMBOL_CURLY_BRACKET",
+ "PARSER_TOKEN_SYMBOL_BRACKET_LEFT",
+ "PARSER_TOKEN_SYMBOL_BRACKET_RIGHT",
"PARSER_TOKEN_SYMBOL_PARENTHESIS",
"PARSER_TOKEN_SYMBOL_COMMA",
@@ -182,7 +184,10 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_PARENTHESIS: {
const ParserNodeArray *metadata = node->metadata;
- printf(",children=[\n");
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("children=[\n");
for (size_t i = 0; i < metadata->size; ++i) {
parserNodePrint(metadata->data[i], indent + 1);
printf(",\n");
@@ -192,6 +197,27 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: {
+ const ParserNodeBracketMetadata *metadata = node->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("operand=\n");
+ parserNodePrint(metadata->operand, indent + 1);
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("params=[\n");
+ for (size_t i = 0; i < metadata->params->size; ++i) {
+ parserNodePrint(metadata->params->data[i], indent + 1);
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("]");
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_TYPE_TYPE:
@@ -456,6 +482,18 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: {
+ ParserNodeBracketMetadata *metadata = node->metadata;
+ parserNodeDelete(metadata->operand);
+ for (size_t i = 0; i < metadata->params->size; ++i) {
+ parserNodeDelete(metadata->params->data[i]);
+ }
+ free(metadata->params->data);
+ free(metadata->params);
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_TYPE_TYPE:
@@ -747,6 +785,10 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserParenthesis(node, begin, parent);
case LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET:
return parserCurlyBrackets(node, begin, parent);
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET:
+ return parserBracketsRight(node, begin, parent, conti);
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT:
+ return parserBracketsLeft(node, begin, end, parent);
case LEXER_TOKEN_SYMBOL_FUNCTION_ARROW:
return parserFunction(node, begin, end, parent);
case LEXER_TOKEN_SYMBOL_COLON:
@@ -865,6 +907,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET:
+ case LEXER_TOKEN_SYMBOL_OPEN_BRACKET:
case LEXER_TOKEN_NONE:
break;
}
@@ -1213,6 +1256,131 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin,
}
}
+ParserNode *parserBracketsRight(LexerNode *closing, LexerNode *begin,
+ ParserNode *parent, bool *conti) {
+ LexerNode *opening = NULL;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+ if (iter->parserNode == NULL &&
+ iter->token == LEXER_TOKEN_SYMBOL_OPEN_BRACKET) {
+ opening = iter;
+ break;
+ }
+ }
+
+ if (opening == NULL) {
+ printError(closing->str_begin, closing->str_end, "No opening for bracket");
+ return NULL;
+ }
+
+ LexerNode *beforeNode = opening - 1;
+ ParserNode *before;
+ if (beforeNode < begin || beforeNode->parserNode == NULL ||
+ (before = getUntilCommonParent(beforeNode->parserNode, parent)) == NULL ||
+ !isExpression(before)) {
+ closing->token = LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT;
+ *conti = true;
+ return NULL;
+ }
+
+ ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
+ parserNode->parent = parent;
+
+ before->parent = parserNode;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+ if (iter->parserNode != NULL) {
+ ParserNode *pNode =
+ getUntilCommonParents(iter->parserNode, parent, parserNode);
+ if (pNode == NULL) {
+ printLog(pNode->str_begin, pNode->str_end, "Bad node");
+ return NULL;
+ } else {
+ pNode->parent = parserNode;
+ }
+ } else if (iter == opening) {
+ break;
+ }
+ }
+
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+
+ parserNode->token = PARSER_TOKEN_SYMBOL_BRACKET_RIGHT;
+ parserNode->str_begin = before->str_begin;
+ parserNode->str_end = closing->str_end;
+
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ ParserNodeBracketMetadata *metadata = malloc(sizeof(*metadata));
+ metadata->operand = before;
+ metadata->params = parserNode->metadata;
+ parserNode->metadata = metadata;
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
+}
+
+ParserNode *parserBracketsLeft(LexerNode *closing, LexerNode *begin,
+ LexerNode *end, ParserNode *parent) {
+ LexerNode *afterNode = closing + 1;
+ ParserNode *after;
+ if (afterNode >= end || afterNode->parserNode == NULL ||
+ (after = getUntilCommonParent(afterNode->parserNode, parent)) == NULL ||
+ !isExpression(after)) {
+ printLog(closing->str_begin, closing->str_end,
+ "Bad bracket can't be parsed");
+ return NULL;
+ }
+
+ ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
+ parserNode->parent = parent;
+
+ after->parent = parserNode;
+
+ LexerNode *opening = NULL;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+
+ if (iter->parserNode != NULL) {
+ ParserNode *pNode =
+ getUntilCommonParents(iter->parserNode, parent, parserNode);
+ if (pNode == NULL) {
+ printLog(pNode->str_begin, pNode->str_end, "Bad node");
+ return NULL;
+ } else {
+ pNode->parent = parserNode;
+ }
+ } else if (iter->token == LEXER_TOKEN_SYMBOL_OPEN_BRACKET) {
+ opening = iter;
+ break;
+ }
+ }
+
+ if (opening == NULL) {
+ printError(closing->str_begin, closing->str_end, "No opening for bracket");
+ return NULL;
+ }
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+
+ parserNode->token = PARSER_TOKEN_SYMBOL_BRACKET_LEFT;
+ parserNode->str_begin = opening->str_begin;
+ parserNode->str_end = after->str_end;
+
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ ParserNodeBracketMetadata *metadata = malloc(sizeof(*metadata));
+ metadata->operand = after;
+ metadata->params = parserNode->metadata;
+ parserNode->metadata = metadata;
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
+}
+
ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin,
ParserNode *parent) {
ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
@@ -1323,6 +1491,8 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_OPERATOR_ACCESS:
case PARSER_TOKEN_OPERATOR_ASSIGN:
@@ -1752,6 +1922,8 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_PUTC:
@@ -1844,6 +2016,8 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_COMPTIME:
@@ -1956,6 +2130,8 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_CONSTANT:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 9464ca2..120ae39 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -49,6 +49,8 @@ typedef enum ParserToken {
PARSER_TOKEN_SYMBOL_EOL,
PARSER_TOKEN_SYMBOL_CURLY_BRACKET,
+ PARSER_TOKEN_SYMBOL_BRACKET_LEFT,
+ PARSER_TOKEN_SYMBOL_BRACKET_RIGHT,
PARSER_TOKEN_SYMBOL_PARENTHESIS,
PARSER_TOKEN_SYMBOL_COMMA,
@@ -159,6 +161,11 @@ typedef struct ParserNodeWhileMetadata {
ParserNode *body;
} ParserNodeWhileMetadata;
+typedef struct ParserNodeBracketMetadata {
+ ParserNode *operand;
+ ParserNodeArray *params;
+} ParserNodeBracketMetadata;
+
void parserNodePrint(const ParserNode *node, int indent);
void parserNodeDelete(ParserNode *node);
@@ -192,6 +199,10 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin,
ParserNode *parent);
ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin,
ParserNode *parent);
+ParserNode *parserBracketsRight(LexerNode *closing, LexerNode *begin,
+ ParserNode *parent, bool *conti);
+ParserNode *parserBracketsLeft(LexerNode *closing, LexerNode *begin,
+ LexerNode *end, ParserNode *parent);
ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *parent);
ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 2f4b32f..075e3a4 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -438,6 +438,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
if (!conti) {
break;
}
+ astTreeDelete(ret);
ret = runExpression(metadata->body, shouldRet, isLeft);
}
return ret;
@@ -1121,6 +1122,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
case AST_TREE_TOKEN_VALUE_OBJECT:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_BUILTIN:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
return copyAstTree(expr);
case AST_TREE_TOKEN_OPERATOR_ADDRESS: {
AstTreeSingleChild *metadata = expr->metadata;
@@ -1160,7 +1162,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
case AST_TREE_TOKEN_OPERATOR_ACCESS: {
AstTreeAccess *metadata = expr->metadata;
AstTree *tree = runExpression(metadata->object, shouldRet, true);
- if (tree->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT) {
+ if (tree->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT &&
+ tree->token != AST_TREE_TOKEN_VARIABLE) {
UNREACHABLE;
}
AstTreeVariable *variable = tree->metadata;
@@ -1217,6 +1220,76 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
return newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, newMetadata,
copyAstTree(expr->type), expr->str_begin, expr->str_end);
}
+ case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
+ AstTreeBracket *metadata = expr->metadata;
+ AstTree *operand = runExpression(metadata->operand, shouldRet, true);
+
+ if (operand->token != AST_TREE_TOKEN_VARIABLE) {
+ UNREACHABLE;
+ } else if (metadata->parameters.size != 1) {
+ UNREACHABLE;
+ }
+
+ AstTree *array_indexNode =
+ runExpression(metadata->parameters.data[0], shouldRet, false);
+
+ if (array_indexNode->token != AST_TREE_TOKEN_VALUE_INT) {
+ UNREACHABLE;
+ }
+
+ AstTreeInt index = *(AstTreeInt *)array_indexNode->metadata;
+ astTreeDelete(array_indexNode);
+
+ AstTreeVariable *variable = operand->metadata;
+ astTreeDelete(operand);
+ if (variable->value->token == AST_TREE_TOKEN_VALUE_UNDEFINED) {
+ AstTreeBracket *array_type_metadata = variable->type->metadata;
+ if (array_type_metadata->parameters.size != 1) {
+ UNREACHABLE;
+ }
+ AstTree *arraySize_tree = runExpression(
+ array_type_metadata->parameters.data[0], shouldRet, false);
+ if (arraySize_tree->token != AST_TREE_TOKEN_VALUE_INT) {
+ UNREACHABLE;
+ }
+ AstTreeInt array_size = *(AstTreeInt *)arraySize_tree->metadata;
+ astTreeDelete(arraySize_tree);
+
+ AstTreeObject *newMetadata = a404m_malloc(sizeof(*newMetadata));
+
+ newMetadata->variables = (AstTreeVariables){
+ .data =
+ a404m_malloc(array_size * sizeof(*newMetadata->variables.data)),
+ .size = array_size,
+ };
+
+ for (size_t i = 0; i < array_size; ++i) {
+ AstTreeVariable *member = a404m_malloc(sizeof(*member));
+ member->name_begin = member->name_end = NULL;
+ member->isConst = false;
+ member->type = copyAstTree(array_type_metadata->operand);
+ member->value = newAstTree(
+ AST_TREE_TOKEN_VALUE_UNDEFINED, NULL, copyAstTree(member->type),
+ variable->value->str_begin, variable->value->str_end);
+ newMetadata->variables.data[i] = member;
+ }
+
+ runnerVariableSetValue(variable, newAstTree(AST_TREE_TOKEN_VALUE_OBJECT,
+ newMetadata,
+ copyAstTree(variable->type),
+ variable->value->str_begin,
+ variable->value->str_end));
+ }
+ AstTreeObject *object = variable->value->metadata;
+ AstTreeVariable *var = object->variables.data[index];
+
+ if (isLeft) {
+ return newAstTree(AST_TREE_TOKEN_VARIABLE, var, copyAstTree(var->type),
+ var->name_begin, var->name_end);
+ } else {
+ return copyAstTree(var->value);
+ }
+ }
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;