diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/ast-tree.c | 197 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 8 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/runner/runner.c | 68 |
4 files changed, 152 insertions, 123 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index ef5e6a7..d4b4114 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -113,7 +113,6 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_KEYWORD_WHILE", "AST_TREE_TOKEN_KEYWORD_COMPTIME", "AST_TREE_TOKEN_KEYWORD_STRUCT", - "AST_TREE_TOKEN_KEYWORD_UNDEFINED", "AST_TREE_TOKEN_TYPE_FUNCTION", "AST_TREE_TOKEN_TYPE_TYPE", @@ -137,9 +136,11 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_VARIABLE", "AST_TREE_TOKEN_VARIABLE_DEFINE", "AST_TREE_TOKEN_VALUE_NULL", + "AST_TREE_TOKEN_VALUE_UNDEFINED", "AST_TREE_TOKEN_VALUE_INT", "AST_TREE_TOKEN_VALUE_FLOAT", "AST_TREE_TOKEN_VALUE_BOOL", + "AST_TREE_TOKEN_VALUE_OBJECT", "AST_TREE_TOKEN_OPERATOR_ASSIGN", "AST_TREE_TOKEN_OPERATOR_PLUS", @@ -268,6 +269,27 @@ void astTreePrint(const AstTree *tree, int indent) { printf(",value=%b", *metadata); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_VALUE_OBJECT: { + AstTreeObject *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("["); + for (size_t i = 0; i < metadata->variables.size; ++i) { + AstTreeVariable *variable = metadata->variables.data[i]; + for (int i = 0; i < indent + 1; ++i) + printf(" "); + printf("{name=%.*s,value=\n", + (int)(variable->name_end - variable->name_begin), + variable->name_begin); + astTreePrint(variable->value, indent + 2); + printf(",\n"); + } + for (int i = 0; i < indent; ++i) + printf(" "); + printf("]"); + } + goto RETURN_SUCCESS; case AST_TREE_TOKEN_TYPE_FUNCTION: { AstTreeTypeFunction *metadata = tree->metadata; printf(",\n"); @@ -538,6 +560,16 @@ void astTreeDestroy(AstTree tree) { free(metadata); return; } + case AST_TREE_TOKEN_VALUE_OBJECT: { + AstTreeObject *metadata = tree.metadata; + for (size_t i = 0; i < metadata->variables.size; ++i) { + AstTreeVariable *variable = metadata->variables.data[i]; + astTreeVariableDelete(variable); + } + free(metadata->variables.data); + free(metadata); + return; + } case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: @@ -731,22 +763,40 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], AstTreeBool *metadata = tree->metadata; AstTreeBool *newMetadata = a404m_malloc(sizeof(*newMetadata)); *newMetadata = *metadata; - return newAstTree(tree->token, newMetadata, tree->type, tree->str_begin, - tree->str_end); + return newAstTree( + tree->token, newMetadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_VALUE_INT: { AstTreeInt *metadata = tree->metadata; AstTreeInt *newMetadata = a404m_malloc(sizeof(*newMetadata)); *newMetadata = *metadata; - return newAstTree(tree->token, newMetadata, tree->type, tree->str_begin, - tree->str_end); + return newAstTree( + tree->token, newMetadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_VALUE_FLOAT: { AstTreeFloat *metadata = tree->metadata; AstTreeFloat *newMetadata = a404m_malloc(sizeof(*newMetadata)); *newMetadata = *metadata; - return newAstTree(tree->token, newMetadata, tree->type, tree->str_begin, - tree->str_end); + return newAstTree( + tree->token, newMetadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); + } + case AST_TREE_TOKEN_VALUE_OBJECT: { + AstTreeObject *metadata = tree->metadata; + AstTreeObject *newMetadata = a404m_malloc(sizeof(*newMetadata)); + + newMetadata->variables = copyAstTreeVariables( + metadata->variables, oldVariables, newVariables, variables_size); + + return newAstTree( + tree->token, newMetadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: { @@ -990,7 +1040,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], AstTreeAccess *metadata = tree->metadata; AstTreeAccess *new_metadata = a404m_malloc(sizeof(*new_metadata)); - new_metadata->object = metadata->object; + new_metadata->object = copyAstTreeBack(metadata->object, oldVariables, + newVariables, variables_size); new_metadata->member = metadata->member; return newAstTree( @@ -1766,7 +1817,7 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) { AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token, size_t metadata_size) { - void *metadata = a404m_malloc(sizeof(metadata)); + void *metadata = a404m_malloc(metadata_size); memcpy(metadata, parserNode->metadata, metadata_size); return newAstTree(token, metadata, NULL, parserNode->str_begin, @@ -2266,6 +2317,9 @@ bool isFunction(AstTree *value) { } bool isConst(AstTree *tree, AstTreeHelper *helper) { + if (tree->type == NULL) { + UNREACHABLE; + } switch (tree->token) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -2289,6 +2343,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { 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_KEYWORD_COMPTIME: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_KEYWORD_STRUCT: @@ -2461,6 +2516,7 @@ AstTree *makeTypeOf(AstTree *value) { } UNREACHABLE; } + case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -2488,6 +2544,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { 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_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: @@ -2599,6 +2656,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { 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_VARIABLE: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_OPERATOR_ASSIGN: @@ -2738,6 +2796,19 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, } return false; } + case AST_TREE_TOKEN_VALUE_OBJECT: { + AstTreeObject *metadata = tree->metadata; + for (size_t i = 0; i < metadata->variables.size; ++i) { + AstTreeVariable *variable = metadata->variables.data[i]; + if (variable->value != NULL) { + if (isCircularDependenciesBack(helper, variable, variable->value, + checkedVariables)) { + return true; + } + } + } + return false; + } case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_FUNCTION: { return false; @@ -2847,6 +2918,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesValueNull(tree, helper); case AST_TREE_TOKEN_VALUE_UNDEFINED: return setTypesValueUndefined(tree, helper); + case AST_TREE_TOKEN_VALUE_OBJECT: + return setTypesValueObject(tree, helper); case AST_TREE_TOKEN_FUNCTION: return setTypesFunction(tree, helper); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -3011,34 +3084,34 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { } bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { - if (typeIsEqual(helper.lookingType, &AST_TREE_F16_TYPE)) { + if (helper.lookingType == NULL || + typeIsEqual(helper.lookingType, &AST_TREE_F64_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; - f16 newValue = value; + f64 newValue = value; *(AstTreeFloat *)tree->metadata = value; if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } - tree->type = &AST_TREE_F16_TYPE; - } else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) { + tree->type = &AST_TREE_F64_TYPE; + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F16_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; - f32 newValue = value; + f16 newValue = value; *(AstTreeFloat *)tree->metadata = value; if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } - tree->type = &AST_TREE_F32_TYPE; - } else if (typeIsEqual(helper.lookingType, &AST_TREE_F64_TYPE) || - helper.lookingType == NULL) { + tree->type = &AST_TREE_F16_TYPE; + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; - f64 newValue = value; + f32 newValue = value; *(AstTreeFloat *)tree->metadata = value; if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } - tree->type = &AST_TREE_F64_TYPE; + tree->type = &AST_TREE_F32_TYPE; } else if (typeIsEqual(helper.lookingType, &AST_TREE_F128_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; @@ -3077,6 +3150,12 @@ bool setTypesValueUndefined(AstTree *tree, AstTreeSetTypesHelper helper) { return true; } +bool setTypesValueObject(AstTree *tree, AstTreeSetTypesHelper helper) { + (void)tree; + (void)helper; + NOT_IMPLEMENTED; +} + bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeFunction *metadata = tree->metadata; @@ -3571,17 +3650,14 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { const size_t size = metadata->member.name.end - metadata->member.name.begin; const char *str = metadata->member.name.begin; - size_t index = 0; - for (size_t i = 0; i < struc->variables.size; ++i) { AstTreeVariable *member = struc->variables.data[i]; const size_t member_size = member->name_end - member->name_begin; - if (member_size == size && strncmp(member->name_begin, str, size)) { - metadata->member.index = index; + if (member_size == size && strncmp(member->name_begin, str, size) == 0) { + metadata->member.index = i; tree->type = copyAstTree(member->type); return true; } - index += sizeOfType(member->type); } printError(metadata->member.name.begin, metadata->member.name.end, @@ -3600,76 +3676,3 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) { return setAllTypes(&infix->right, newHelper, NULL); } - -size_t sizeOfType(AstTree *type) { - switch (type->token) { - case AST_TREE_TOKEN_TYPE_TYPE: - UNREACHABLE; - case AST_TREE_TOKEN_TYPE_VOID: - return 0; - case AST_TREE_TOKEN_TYPE_I8: - case AST_TREE_TOKEN_TYPE_U8: - case AST_TREE_TOKEN_TYPE_BOOL: - return 1; - case AST_TREE_TOKEN_TYPE_I16: - case AST_TREE_TOKEN_TYPE_U16: - case AST_TREE_TOKEN_TYPE_F16: - return 2; - case AST_TREE_TOKEN_TYPE_I32: - case AST_TREE_TOKEN_TYPE_U32: - case AST_TREE_TOKEN_TYPE_F32: - return 4; - case AST_TREE_TOKEN_TYPE_I64: - case AST_TREE_TOKEN_TYPE_U64: - case AST_TREE_TOKEN_TYPE_F64: - case AST_TREE_TOKEN_TYPE_FUNCTION: - return 8; - case AST_TREE_TOKEN_TYPE_F128: - return 16; - case AST_TREE_TOKEN_KEYWORD_STRUCT: { - AstTreeStruct *metadata = type->metadata; - size_t size = 0; - for (size_t i = 0; i < metadata->variables.size; ++i) { - size += sizeOfType(metadata->variables.data[i]->type); - } - return size; - } - 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_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_SCOPE: - case AST_TREE_TOKEN_FUNCTION: - case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - 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_NONE: - } - printError(type->str_begin, type->str_end, "Bad token %d", type->token); - UNREACHABLE; -} diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index fdc797e..d8e9f9a 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -43,6 +43,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VALUE_INT, AST_TREE_TOKEN_VALUE_FLOAT, AST_TREE_TOKEN_VALUE_BOOL, + AST_TREE_TOKEN_VALUE_OBJECT, AST_TREE_TOKEN_OPERATOR_ASSIGN, AST_TREE_TOKEN_OPERATOR_PLUS, @@ -156,6 +157,10 @@ typedef f128 AstTreeFloat; typedef bool AstTreeBool; +typedef struct AstTreeObject { + AstTreeVariables variables; +} AstTreeObject; + typedef AstTree AstTreeSingleChild; typedef struct AstTreeInfix { @@ -291,6 +296,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueNull(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueUndefined(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesValueObject(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper, @@ -320,5 +326,3 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper helper); bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper); - -size_t sizeOfType(AstTree *type); @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) { return 1; } - const int ret = run(argv[1], true); + const int ret = run(argv[1], false); fileDelete(); return ret; } diff --git a/src/runner/runner.c b/src/runner/runner.c index a335f85..c6a8bf0 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -76,17 +76,17 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments, shouldRet = false; - AstTree *ret = &AST_TREE_VOID_VALUE; - for (size_t i = 0; i < function->scope.expressions_size; ++i) { - astTreeDelete(ret); - ret = runExpression(function->scope.expressions[i], &shouldRet, false); + AstTree *ret = + runExpression(function->scope.expressions[i], &shouldRet, false); if (shouldRet) { - break; + return ret; + } else { + astTreeDelete(ret); } } - return ret; + return &AST_TREE_VOID_VALUE; } AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { @@ -100,16 +100,11 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { } case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = expr->metadata; - if (metadata->function->token == AST_TREE_TOKEN_VARIABLE) { - AstTreeVariable *variable = metadata->function->metadata; - AstTree *function = copyAstTree(variable->value); - AstTree *result = runAstTreeFunction(function, metadata->parameters, - metadata->parameters_size); - astTreeDelete(function); - return result; - } else { - UNREACHABLE; - } + AstTree *function = runExpression(metadata->function, shouldRet, false); + AstTree *result = runAstTreeFunction(function, metadata->parameters, + metadata->parameters_size); + astTreeDelete(function); + return result; } case AST_TREE_TOKEN_OPERATOR_ASSIGN: { AstTreeInfix *metadata = expr->metadata; @@ -120,6 +115,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { AstTreeVariable *left = l->metadata; runnerVariableSetValue(left, runExpression(&metadata->right, shouldRet, false)); + astTreeDelete(l); return copyAstTree(left->value); } case AST_TREE_TOKEN_KEYWORD_RETURN: { @@ -785,6 +781,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VALUE_FLOAT: + case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_STRUCT: @@ -822,18 +819,43 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { } } case AST_TREE_TOKEN_OPERATOR_ACCESS: { - NOT_IMPLEMENTED; AstTreeAccess *metadata = expr->metadata; AstTree *tree = runExpression(metadata->object, shouldRet, true); - if (tree->token != AST_TREE_TOKEN_VARIABLE) { + if (tree->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT) { UNREACHABLE; } AstTreeVariable *variable = tree->metadata; - astTreeDelete(variable->type); - variable->type = copyAstTree(expr->type); - variable->value->metadata = - ((u8 *)variable->value->metadata) + metadata->member.index; - return tree; + astTreeDelete(tree); + if (variable->value->token == AST_TREE_TOKEN_VALUE_UNDEFINED) { + AstTreeStruct *struc = variable->type->metadata; + AstTreeObject *newMetadata = a404m_malloc(sizeof(*newMetadata)); + + newMetadata->variables = + copyAstTreeVariables(struc->variables, NULL, NULL, 0); + + for (size_t i = 0; i < newMetadata->variables.size; ++i) { + AstTreeVariable *member = newMetadata->variables.data[i]; + runnerVariableSetValue(member, + newAstTree(AST_TREE_TOKEN_VALUE_UNDEFINED, NULL, + copyAstTree(member->type), + variable->value->str_begin, + variable->value->str_end)); + } + + 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[metadata->member.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: } |