added: more semantic errors checks
This commit is contained in:
parent
f243bb6bfe
commit
d4ce3387b9
|
@ -181,9 +181,11 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
|
||||||
print_ast_to_file(ast, target);
|
print_ast_to_file(ast, target);
|
||||||
Module* module = create_set(ast);
|
Module* module = create_set(ast);
|
||||||
|
|
||||||
|
if (module != NULL) {
|
||||||
run_backend_codegen(module, target);
|
run_backend_codegen(module, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AST_delete_node(ast);
|
AST_delete_node(ast);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <llvm/llvm-ir/func.h>
|
#include <llvm/llvm-ir/func.h>
|
||||||
#include <llvm/llvm-ir/types.h>
|
#include <llvm/llvm-ir/types.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <mem/cache.h>
|
||||||
|
|
||||||
BackendError impl_assign_stmt(
|
BackendError impl_assign_stmt(
|
||||||
LLVMBackendCompileUnit *unit,
|
LLVMBackendCompileUnit *unit,
|
||||||
|
@ -146,12 +147,13 @@ gboolean is_parameter_out(Parameter *param) {
|
||||||
BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
||||||
LLVMBuilderRef builder, LLVMLocalScope *scope,
|
LLVMBuilderRef builder, LLVMLocalScope *scope,
|
||||||
const FunctionCall *call) {
|
const FunctionCall *call) {
|
||||||
|
DEBUG("implementing function call...");
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
GArray *arguments = g_array_new(FALSE, FALSE, sizeof(LLVMValueRef));
|
LLVMValueRef* arguments = mem_alloc(MemoryNamespaceLlvm, sizeof(LLVMValueRef) * call->expressions->len);
|
||||||
|
|
||||||
for (size_t i = 0; i < call->expressions->len; i++) {
|
for (size_t i = 0; i < call->expressions->len; i++) {
|
||||||
Expression *arg = ((Expression *) call->expressions->data) + i;
|
Expression *arg = g_array_index(call->expressions, Expression*, i);
|
||||||
|
|
||||||
LLVMValueRef llvm_arg = NULL;
|
LLVMValueRef llvm_arg = NULL;
|
||||||
err = impl_expr(unit, scope, builder, arg, &llvm_arg);
|
err = impl_expr(unit, scope, builder, arg, &llvm_arg);
|
||||||
|
@ -159,25 +161,30 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter *parameter = g_array_index(call->function->impl.declaration.parameter, Parameter*, i);
|
GArray* param_list;
|
||||||
|
if (call->function->kind == FunctionDeclarationKind) {
|
||||||
|
param_list = call->function->impl.definition.parameter;
|
||||||
|
} else {
|
||||||
|
param_list = call->function->impl.declaration.parameter;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_parameter_out(parameter)) {
|
Parameter parameter = g_array_index(param_list, Parameter, i);
|
||||||
|
|
||||||
|
if (is_parameter_out(¶meter)) {
|
||||||
LLVMValueRef zero = LLVMConstInt(LLVMInt32TypeInContext(unit->context), 0, 0);
|
LLVMValueRef zero = LLVMConstInt(LLVMInt32TypeInContext(unit->context), 0, 0);
|
||||||
llvm_arg = LLVMBuildGEP2(builder, LLVMTypeOf(llvm_arg), llvm_arg, &zero, 1, "");
|
llvm_arg = LLVMBuildGEP2(builder, LLVMTypeOf(llvm_arg), llvm_arg, &zero, 1, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_vals(arguments, &llvm_arg, 1);
|
arguments[i] = llvm_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err.kind == Success) {
|
if (err.kind == Success) {
|
||||||
LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, "");
|
LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name);
|
||||||
LLVMTypeRef llvm_func_type = LLVMTypeOf(llvm_func);
|
LLVMTypeRef llvm_func_type = LLVMTypeOf(llvm_func);
|
||||||
LLVMBuildCall2(builder, llvm_func_type, llvm_func, (LLVMValueRef *) arguments->data, arguments->len,
|
LLVMBuildCall2(builder, llvm_func_type, llvm_func, arguments, call->expressions->len,
|
||||||
"stmt.call");
|
"stmt.call");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_free(arguments, FALSE);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,6 @@ BackendError get_type_impl(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("invalid type kind: %ld", gemstone_type->kind);
|
PANIC("invalid type kind: %ld", gemstone_type->kind);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
206
src/set/set.c
206
src/set/set.c
|
@ -1,7 +1,4 @@
|
||||||
#include <io/files.h>
|
#include <io/files.h>
|
||||||
#include <yacc/parser.tab.h>
|
|
||||||
#include <complex.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
#include <set/types.h>
|
#include <set/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -9,7 +6,6 @@
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
|
||||||
#include <set/set.h>
|
#include <set/set.h>
|
||||||
#include <mem/cache.h>
|
#include <mem/cache.h>
|
||||||
|
|
||||||
|
@ -219,6 +215,8 @@ int set_impl_composite_type(AST_NODE_PTR ast_type, CompositeType *composite) {
|
||||||
composite->scale = composite->scale * nested_type->impl.composite.scale;
|
composite->scale = composite->scale * nested_type->impl.composite.scale;
|
||||||
|
|
||||||
if (composite->scale > 8 || composite->scale < 0.25) {
|
if (composite->scale > 8 || composite->scale < 0.25) {
|
||||||
|
print_diagnostic(current_file, &typeKind->location, Error, "Invalid type scale of composite type: %lf",
|
||||||
|
composite->scale);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,8 +272,9 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) {
|
||||||
|
|
||||||
if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) {
|
if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) {
|
||||||
*type = g_hash_table_lookup(declaredBoxes, typekind);
|
*type = g_hash_table_lookup(declaredBoxes, typekind);
|
||||||
if(currentNode->child_count > 1) {
|
|
||||||
|
|
||||||
|
if (currentNode->child_count > 1) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Box type cannot modified");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
|
@ -299,6 +298,9 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) {
|
||||||
*type = new_type;
|
*type = new_type;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_diagnostic(current_file, ¤tNode->children[currentNode->child_count - 1]->location, Error,
|
||||||
|
"Expected either primitive or composite type");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,14 +332,11 @@ int createRef(AST_NODE_PTR currentNode, Type** reftype) {
|
||||||
assert(currentNode->child_count == 1);
|
assert(currentNode->child_count == 1);
|
||||||
assert(AST_get_node(currentNode, 0)->kind == AST_Type);
|
assert(AST_get_node(currentNode, 0)->kind == AST_Type);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Type *type = malloc(sizeof(Type));
|
Type *type = malloc(sizeof(Type));
|
||||||
Type *referenceType = malloc(sizeof(Type));
|
Type *referenceType = malloc(sizeof(Type));
|
||||||
referenceType->kind = TypeKindReference;
|
referenceType->kind = TypeKindReference;
|
||||||
referenceType->nodePtr = currentNode;
|
referenceType->nodePtr = currentNode;
|
||||||
|
|
||||||
|
|
||||||
int signal = set_get_type_impl(currentNode->children[0], &type);
|
int signal = set_get_type_impl(currentNode->children[0], &type);
|
||||||
if (signal) {
|
if (signal) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
|
@ -436,6 +435,9 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) {
|
||||||
case AST_Type:
|
case AST_Type:
|
||||||
DEBUG("fill Type");
|
DEBUG("fill Type");
|
||||||
status = set_get_type_impl(declaration->children[i], &decl.type);
|
status = set_get_type_impl(declaration->children[i], &decl.type);
|
||||||
|
if (status == SEMANTIC_ERROR) {
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AST_IdentList:
|
case AST_IdentList:
|
||||||
break;
|
break;
|
||||||
|
@ -501,7 +503,8 @@ int getVariableFromScope(const char *name, Variable **variable) {
|
||||||
DEBUG("Found var");
|
DEBUG("Found var");
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
} else if (found > 1) {
|
} else if (found > 1) {
|
||||||
WARN("Variable %s is a parameter and a declared variable. Returning parameter", name);
|
print_diagnostic(current_file, &(*variable)->nodePtr->location, Warning,
|
||||||
|
"Parameter shadows variable of same name: %s", name);
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
DEBUG("nothing found");
|
DEBUG("nothing found");
|
||||||
|
@ -511,7 +514,7 @@ int getVariableFromScope(const char *name, Variable **variable) {
|
||||||
int addVarToScope(Variable *variable) {
|
int addVarToScope(Variable *variable) {
|
||||||
Variable *tmp = NULL;
|
Variable *tmp = NULL;
|
||||||
if (getVariableFromScope(variable->name, &tmp) == SEMANTIC_OK) {
|
if (getVariableFromScope(variable->name, &tmp) == SEMANTIC_OK) {
|
||||||
INFO("this var already exist: ", variable->name);
|
print_diagnostic(current_file, &variable->nodePtr->location, Error, "Variable already exist: ", variable->name);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
GHashTable *currentScope = g_array_index(Scope, GHashTable*, Scope->len - 1);
|
GHashTable *currentScope = g_array_index(Scope, GHashTable*, Scope->len - 1);
|
||||||
|
@ -525,11 +528,11 @@ int fillTablesWithVars(GHashTable *variableTable, const GArray* variables) {
|
||||||
|
|
||||||
for (size_t i = 0; i < variables->len; i++) {
|
for (size_t i = 0; i < variables->len; i++) {
|
||||||
|
|
||||||
|
|
||||||
Variable *var = g_array_index(variables, Variable *, i);
|
Variable *var = g_array_index(variables, Variable *, i);
|
||||||
|
|
||||||
// this variable is discarded, only need status code
|
// this variable is discarded, only need status code
|
||||||
if (g_hash_table_contains(variableTable, (gpointer) var->name)) {
|
if (g_hash_table_contains(variableTable, (gpointer) var->name)) {
|
||||||
|
print_diagnostic(current_file, &var->nodePtr->location, Error, "Variable already exists");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,6 +543,7 @@ int fillTablesWithVars(GHashTable *variableTable, const GArray* variables) {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard("type must be freed")]]
|
[[nodiscard("type must be freed")]]
|
||||||
|
|
||||||
TypeValue createTypeValue(AST_NODE_PTR currentNode) {
|
TypeValue createTypeValue(AST_NODE_PTR currentNode) {
|
||||||
DEBUG("create TypeValue");
|
DEBUG("create TypeValue");
|
||||||
TypeValue value;
|
TypeValue value;
|
||||||
|
@ -552,11 +556,9 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){
|
||||||
case AST_Int:
|
case AST_Int:
|
||||||
type->impl.primitive = Int;
|
type->impl.primitive = Int;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_Float:
|
case AST_Float:
|
||||||
type->impl.primitive = Float;
|
type->impl.primitive = Float;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
||||||
break;
|
break;
|
||||||
|
@ -593,7 +595,8 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_
|
||||||
resultImpl.nodePtr = currentNode;
|
resultImpl.nodePtr = currentNode;
|
||||||
resultImpl.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign);
|
resultImpl.sign = MAX(LeftOperandType->impl.composite.sign, RightOperandType->impl.composite.sign);
|
||||||
resultImpl.scale = MAX(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale);
|
resultImpl.scale = MAX(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale);
|
||||||
resultImpl.primitive = MAX(LeftOperandType->impl.composite.primitive , RightOperandType->impl.composite.primitive);
|
resultImpl.primitive = MAX(LeftOperandType->impl.composite.primitive,
|
||||||
|
RightOperandType->impl.composite.primitive);
|
||||||
|
|
||||||
result->impl.composite = resultImpl;
|
result->impl.composite = resultImpl;
|
||||||
|
|
||||||
|
@ -620,6 +623,7 @@ Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_
|
||||||
result->impl.composite.nodePtr = currentNode;
|
result->impl.composite.nodePtr = currentNode;
|
||||||
} else {
|
} else {
|
||||||
mem_free(result);
|
mem_free(result);
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Incompatible types in expression");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DEBUG("Succsessfully created type");
|
DEBUG("Succsessfully created type");
|
||||||
|
@ -641,6 +645,8 @@ int createTypeCastFromExpression(Expression * expression, Type * resultType, Exp
|
||||||
|
|
||||||
if (expression->result->kind != TypeKindComposite
|
if (expression->result->kind != TypeKindComposite
|
||||||
&& expression->result->kind != TypeKindPrimitive) {
|
&& expression->result->kind != TypeKindPrimitive) {
|
||||||
|
print_diagnostic(current_file, &expression->nodePtr->location, Error,
|
||||||
|
"Expected either primitive or composite type");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
*result = expr;
|
*result = expr;
|
||||||
|
@ -711,7 +717,6 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode,
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ParentExpression->impl.operation.operands->len; i++) {
|
for (size_t i = 0; i < ParentExpression->impl.operation.operands->len; i++) {
|
||||||
Expression *operand = g_array_index(ParentExpression->impl.operation.operands, Expression*, i);
|
Expression *operand = g_array_index(ParentExpression->impl.operation.operands, Expression*, i);
|
||||||
if (!compareTypes(operand->result, ParentExpression->result)) {
|
if (!compareTypes(operand->result, ParentExpression->result)) {
|
||||||
|
@ -724,8 +729,6 @@ int createArithOperation(Expression* ParentExpression, AST_NODE_PTR currentNode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,12 +737,15 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current
|
||||||
ParentExpression->impl.operation.kind = Relational;
|
ParentExpression->impl.operation.kind = Relational;
|
||||||
ParentExpression->impl.operation.nodePtr = currentNode;
|
ParentExpression->impl.operation.nodePtr = currentNode;
|
||||||
ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
|
ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
|
||||||
|
|
||||||
// fill Operands
|
// fill Operands
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
Expression *expression = createExpression(currentNode->children[i]);
|
Expression *expression = createExpression(currentNode->children[i]);
|
||||||
|
|
||||||
if (NULL == expression) {
|
if (NULL == expression) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_val(ParentExpression->impl.operation.operands, expression);
|
g_array_append_val(ParentExpression->impl.operation.operands, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,10 +773,14 @@ int createRelationalOperation(Expression* ParentExpression, AST_NODE_PTR current
|
||||||
ParentExpression->result = result;
|
ParentExpression->result = result;
|
||||||
|
|
||||||
for (size_t i = 0; i < ParentExpression->impl.operation.operands->len; i++) {
|
for (size_t i = 0; i < ParentExpression->impl.operation.operands->len; i++) {
|
||||||
|
|
||||||
Expression *operand = g_array_index(ParentExpression->impl.operation.operands, Expression*, i);
|
Expression *operand = g_array_index(ParentExpression->impl.operation.operands, Expression*, i);
|
||||||
|
|
||||||
if (!compareTypes(operand->result, ParentExpression->result)) {
|
if (!compareTypes(operand->result, ParentExpression->result)) {
|
||||||
|
|
||||||
Expression *expr;
|
Expression *expr;
|
||||||
int status = createTypeCastFromExpression(operand, ParentExpression->result, &expr);
|
int status = createTypeCastFromExpression(operand, ParentExpression->result, &expr);
|
||||||
|
|
||||||
if (status == SEMANTIC_ERROR) {
|
if (status == SEMANTIC_ERROR) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -807,7 +817,7 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode)
|
||||||
ParentExpression->impl.operation.impl.boolean = BooleanXor;
|
ParentExpression->impl.operation.impl.boolean = BooleanXor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("Current node is not an boolean operater");
|
PANIC("Current node is not an boolean operator");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,13 +896,15 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
|
||||||
if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) {
|
if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) {
|
||||||
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error,
|
||||||
|
"Operand must be a variant of primitive type int");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Operand->kind == TypeKindPrimitive) {
|
if (Operand->kind == TypeKindPrimitive) {
|
||||||
if (Operand->impl.primitive == Float) {
|
if (Operand->impl.primitive == Float) {
|
||||||
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error,
|
||||||
|
"Operand must be a variant of primitive type int");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
|
@ -900,7 +912,8 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
|
|
||||||
} else if (Operand->kind == TypeKindComposite) {
|
} else if (Operand->kind == TypeKindComposite) {
|
||||||
if (Operand->impl.composite.primitive == Float) {
|
if (Operand->impl.composite.primitive == Float) {
|
||||||
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error,
|
||||||
|
"Operand must be a variant of primitive type int");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
|
@ -1179,7 +1192,8 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
int status = getVariableFromScope(boxname, &boxVariable);
|
int status = getVariableFromScope(boxname, &boxVariable);
|
||||||
|
|
||||||
if (status == SEMANTIC_ERROR) {
|
if (status == SEMANTIC_ERROR) {
|
||||||
print_diagnostic(current_file, ¤tNode->children[0]->location, Error, "Variable of name `%s` does not exist");
|
print_diagnostic(current_file, ¤tNode->children[0]->location, Error,
|
||||||
|
"Variable of name `%s` does not exist");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
Type *boxType;
|
Type *boxType;
|
||||||
|
@ -1287,20 +1301,24 @@ int createDeref(Expression* ParentExpression, AST_NODE_PTR currentNode) {
|
||||||
Type *indexType = deref.index->result;
|
Type *indexType = deref.index->result;
|
||||||
//indexType can only be a composite or a primitive
|
//indexType can only be a composite or a primitive
|
||||||
if (indexType->kind != TypeKindComposite && indexType->kind != TypeKindPrimitive) {
|
if (indexType->kind != TypeKindComposite && indexType->kind != TypeKindPrimitive) {
|
||||||
|
print_diagnostic(current_file, &AST_get_node(currentNode, 1)->location, Error,
|
||||||
|
"Index must a primitive int or composite variation");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//indexType can only be int
|
//indexType can only be int
|
||||||
if (indexType->kind == TypeKindPrimitive) {
|
if (indexType->kind == TypeKindPrimitive) {
|
||||||
if (indexType->impl.primitive != Int) {
|
if (indexType->impl.primitive != Int) {
|
||||||
|
print_diagnostic(current_file, &AST_get_node(currentNode, 1)->location, Error,
|
||||||
|
"Index must a primitive int or composite variation");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexType->kind == TypeKindComposite) {
|
if (indexType->kind == TypeKindComposite) {
|
||||||
if (indexType->impl.composite.primitive != Int) {
|
if (indexType->impl.composite.primitive != Int) {
|
||||||
|
print_diagnostic(current_file, &AST_get_node(currentNode, 1)->location, Error,
|
||||||
|
"Index must a primitive int or composite variation");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1309,12 +1327,14 @@ int createDeref(Expression* ParentExpression, AST_NODE_PTR currentNode) {
|
||||||
|
|
||||||
//variable has to be made
|
//variable has to be made
|
||||||
if (deref.index == NULL) {
|
if (deref.index == NULL) {
|
||||||
|
print_diagnostic(current_file, &AST_get_node(currentNode, 1)->location, Error, "Invalid index");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//variable can only be a reference
|
//variable can only be a reference
|
||||||
if (deref.variable->result->kind != TypeKindReference) {
|
if (deref.variable->result->kind != TypeKindReference) {
|
||||||
|
print_diagnostic(current_file, &AST_get_node(currentNode, 0)->location, Error,
|
||||||
|
"Only references can be dereferenced");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,7 +1352,6 @@ int createAddressOf(Expression* ParentExpression, AST_NODE_PTR currentNode) {
|
||||||
address_of.variable = createExpression(AST_get_node(currentNode, 0));
|
address_of.variable = createExpression(AST_get_node(currentNode, 0));
|
||||||
|
|
||||||
if (address_of.variable == NULL) {
|
if (address_of.variable == NULL) {
|
||||||
|
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,14 +1477,12 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
case AST_Dereference:
|
case AST_Dereference:
|
||||||
expression->kind = ExpressionKindDereference;
|
expression->kind = ExpressionKindDereference;
|
||||||
if (createDeref(expression, currentNode)) {
|
if (createDeref(expression, currentNode)) {
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AST_AddressOf:
|
case AST_AddressOf:
|
||||||
expression->kind = ExpressionKindAddressOf;
|
expression->kind = ExpressionKindAddressOf;
|
||||||
if (createAddressOf(expression, currentNode)) {
|
if (createAddressOf(expression, currentNode)) {
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1479,7 +1496,6 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool compareTypes(Type *leftType, Type *rightType) {
|
bool compareTypes(Type *leftType, Type *rightType) {
|
||||||
if (leftType->kind != rightType->kind) {
|
if (leftType->kind != rightType->kind) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1544,16 +1560,16 @@ bool compareTypes(Type * leftType, Type * rightType) {
|
||||||
varType = assign.variable->impl.definiton.declaration.type;
|
varType = assign.variable->impl.definiton.declaration.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool result = compareTypes(varType, assign.value->result);
|
bool result = compareTypes(varType, assign.value->result);
|
||||||
if (result == FALSE) {
|
if (result == FALSE) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Assignment expression has incompatible type");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParentStatement->impl.assignment = assign;
|
ParentStatement->impl.assignment = assign;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int createStatement(Block *block, AST_NODE_PTR currentNode);
|
int createStatement(Block *block, AST_NODE_PTR currentNode);
|
||||||
|
|
||||||
int fillBlock(Block *block, AST_NODE_PTR currentNode) {
|
int fillBlock(Block *block, AST_NODE_PTR currentNode) {
|
||||||
|
@ -1563,7 +1579,6 @@ int fillBlock(Block * block,AST_NODE_PTR currentNode){
|
||||||
GHashTable *lowerScope = g_hash_table_new(g_str_hash, g_str_equal);
|
GHashTable *lowerScope = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
g_array_append_val(Scope, lowerScope);
|
g_array_append_val(Scope, lowerScope);
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
int signal = createStatement(block, AST_get_node(currentNode, i));
|
int signal = createStatement(block, AST_get_node(currentNode, i));
|
||||||
if (signal) {
|
if (signal) {
|
||||||
|
@ -1600,8 +1615,6 @@ int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
|
int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
|
||||||
If ifbranch;
|
If ifbranch;
|
||||||
ifbranch.nodePtr = currentNode;
|
ifbranch.nodePtr = currentNode;
|
||||||
|
@ -1611,11 +1624,12 @@ int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
ifbranch.conditon = expression;
|
ifbranch.conditon = expression;
|
||||||
int status = fillBlock(&ifbranch.block, currentNode->children[1]);
|
|
||||||
|
|
||||||
|
int status = fillBlock(&ifbranch.block, currentNode->children[1]);
|
||||||
if (status) {
|
if (status) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parentbranch->ifBranch = ifbranch;
|
Parentbranch->ifBranch = ifbranch;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
@ -1699,13 +1713,12 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
|
||||||
AST_NODE_PTR argsListNode = AST_get_node(currentNode, 1);
|
AST_NODE_PTR argsListNode = AST_get_node(currentNode, 1);
|
||||||
AST_NODE_PTR nameNode = AST_get_node(currentNode, 0);
|
AST_NODE_PTR nameNode = AST_get_node(currentNode, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunctionCall funcall;
|
FunctionCall funcall;
|
||||||
Function *fun = NULL;
|
Function *fun = NULL;
|
||||||
if (nameNode->kind == AST_Ident) {
|
if (nameNode->kind == AST_Ident) {
|
||||||
int result = getFunction(nameNode->value, &fun);
|
int result = getFunction(nameNode->value, &fun);
|
||||||
if (result == SEMANTIC_ERROR) {
|
if (result == SEMANTIC_ERROR) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Unknown function: `%s`", nameNode);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1721,6 +1734,7 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
|
||||||
|
|
||||||
int result = getFunction(name, &fun);
|
int result = getFunction(name, &fun);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Unknown function: `%s`", nameNode);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1741,6 +1755,8 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count != paramCount) {
|
if (count != paramCount) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Expected %d arguments instead of %d", paramCount,
|
||||||
|
count);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1759,13 +1775,11 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
|
||||||
}
|
}
|
||||||
funcall.expressions = expressions;
|
funcall.expressions = expressions;
|
||||||
|
|
||||||
|
parentStatement->kind = StatementKindFunctionCall;
|
||||||
parentStatement->impl.call = funcall;
|
parentStatement->impl.call = funcall;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int createStatement(Block *Parentblock, AST_NODE_PTR currentNode) {
|
int createStatement(Block *Parentblock, AST_NODE_PTR currentNode) {
|
||||||
DEBUG("create Statement");
|
DEBUG("create Statement");
|
||||||
|
|
||||||
|
@ -1777,13 +1791,12 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
if (status) {
|
if (status) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < variable->len ; i++){
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < variable->len; i++) {
|
||||||
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
||||||
statement->nodePtr = currentNode;
|
statement->nodePtr = currentNode;
|
||||||
statement->kind = StatementKindDeclaration;
|
statement->kind = StatementKindDeclaration;
|
||||||
|
|
||||||
|
|
||||||
statement->impl.variable = g_array_index(variable, Variable *, i);
|
statement->impl.variable = g_array_index(variable, Variable *, i);
|
||||||
g_array_append_val(Parentblock->statemnts, statement);
|
g_array_append_val(Parentblock->statemnts, statement);
|
||||||
}
|
}
|
||||||
|
@ -1793,11 +1806,10 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
case AST_Def: {
|
case AST_Def: {
|
||||||
GArray *variable = g_array_new(FALSE, FALSE, sizeof(Variable *));
|
GArray *variable = g_array_new(FALSE, FALSE, sizeof(Variable *));
|
||||||
|
|
||||||
int status = createDef(currentNode, &variable);
|
if (createDef(currentNode, &variable)) {
|
||||||
|
|
||||||
if(status){
|
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < variable->len; i++) {
|
for (size_t i = 0; i < variable->len; i++) {
|
||||||
|
|
||||||
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
Statement *statement = mem_alloc(MemoryNamespaceSet, sizeof(Statement));
|
||||||
|
@ -1848,6 +1860,7 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
if (result == SEMANTIC_ERROR) {
|
if (result == SEMANTIC_ERROR) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
g_array_append_val(Parentblock->statemnts, statement);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("Node is not a statement");
|
PANIC("Node is not a statement");
|
||||||
|
@ -1857,7 +1870,6 @@ int createStatement(Block * Parentblock , AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) {
|
int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) {
|
||||||
assert(currentNode->kind == AST_Parameter);
|
assert(currentNode->kind == AST_Parameter);
|
||||||
DEBUG("start param");
|
DEBUG("start param");
|
||||||
|
@ -1884,8 +1896,7 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){
|
||||||
PANIC("IO_Qualifier has not the right amount of children");
|
PANIC("IO_Qualifier has not the right amount of children");
|
||||||
}
|
}
|
||||||
|
|
||||||
int signal = set_get_type_impl(paramdecl->children[0], &(decl.type));
|
if (set_get_type_impl(paramdecl->children[0], &(decl.type))) {
|
||||||
if(signal){
|
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
Parameter param;
|
Parameter param;
|
||||||
|
@ -1907,8 +1918,8 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){
|
||||||
paramvar->impl.declaration.qualifier = Local;
|
paramvar->impl.declaration.qualifier = Local;
|
||||||
paramvar->impl.declaration.type = param.impl.declaration.type;
|
paramvar->impl.declaration.type = param.impl.declaration.type;
|
||||||
|
|
||||||
|
|
||||||
if (g_hash_table_contains(functionParameter, param.name)) {
|
if (g_hash_table_contains(functionParameter, param.name)) {
|
||||||
|
print_diagnostic(current_file, ¶m.nodePtr->location, Error, "Names of function parameters must be unique");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_hash_table_insert(functionParameter, (gpointer) param.name, paramvar);
|
g_hash_table_insert(functionParameter, (gpointer) param.name, paramvar);
|
||||||
|
@ -1917,15 +1928,12 @@ int createParam(GArray * Paramlist ,AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
|
||||||
DEBUG("start fundef");
|
DEBUG("start fundef");
|
||||||
AST_NODE_PTR nameNode = currentNode->children[0];
|
AST_NODE_PTR nameNode = currentNode->children[0];
|
||||||
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
||||||
AST_NODE_PTR statementlist = currentNode->children[2];
|
AST_NODE_PTR statementlist = currentNode->children[2];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunctionDefinition fundef;
|
FunctionDefinition fundef;
|
||||||
|
|
||||||
fundef.nodePtr = currentNode;
|
fundef.nodePtr = currentNode;
|
||||||
|
@ -1942,17 +1950,15 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
for (size_t j = 0; j < paramlist->child_count; j++) {
|
for (size_t j = 0; j < paramlist->child_count; j++) {
|
||||||
|
|
||||||
DEBUG("param child count: %i", AST_get_node(paramlist, j)->child_count);
|
DEBUG("param child count: %i", AST_get_node(paramlist, j)->child_count);
|
||||||
int signal = createParam(fundef.parameter ,AST_get_node(paramlist, j));
|
|
||||||
//all params per list
|
|
||||||
|
|
||||||
if (signal){
|
if (createParam(fundef.parameter, AST_get_node(paramlist, j))) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG("End of Paramlist");
|
DEBUG("End of Paramlist");
|
||||||
}
|
}
|
||||||
int signal = fillBlock(fundef.body, statementlist);
|
|
||||||
if(signal){
|
if (fillBlock(fundef.body, statementlist)) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1961,8 +1967,6 @@ int createFunDef(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
Parentfunction->impl.definition = fundef;
|
Parentfunction->impl.definition = fundef;
|
||||||
Parentfunction->name = fundef.name;
|
Parentfunction->name = fundef.name;
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compareParameter(GArray *leftParameter, GArray *rightParameter) {
|
bool compareParameter(GArray *leftParameter, GArray *rightParameter) {
|
||||||
|
@ -1998,22 +2002,25 @@ bool compareParameter(GArray *leftParameter,GArray *rightParameter) {
|
||||||
int addFunction(const char *name, Function *function) {
|
int addFunction(const char *name, Function *function) {
|
||||||
if (function->kind == FunctionDefinitionKind) {
|
if (function->kind == FunctionDefinitionKind) {
|
||||||
if (g_hash_table_contains(definedFunctions, name)) {
|
if (g_hash_table_contains(definedFunctions, name)) {
|
||||||
|
print_diagnostic(current_file, &function->nodePtr->location, Error, "Multiple definition of function: `%s`", function->name);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_hash_table_insert(declaredFunctions, (gpointer) name, function);
|
g_hash_table_insert(declaredFunctions, (gpointer) name, function);
|
||||||
} else if (function->kind == FunctionDeclarationKind) {
|
} else if (function->kind == FunctionDeclarationKind) {
|
||||||
if (g_hash_table_contains(declaredFunctions, name)) {
|
if (g_hash_table_contains(declaredFunctions, name)) {
|
||||||
Function *declaredFunction = g_hash_table_lookup(declaredFunctions, name);
|
Function *declaredFunction = g_hash_table_lookup(declaredFunctions, name);
|
||||||
bool result = compareParameter(declaredFunction->impl.declaration.parameter, function->impl.declaration.parameter);
|
bool result = compareParameter(declaredFunction->impl.declaration.parameter,
|
||||||
|
function->impl.declaration.parameter);
|
||||||
|
// a function can have multiple declartations but all have to be identical
|
||||||
if (result == FALSE) {
|
if (result == FALSE) {
|
||||||
|
print_diagnostic(current_file, &function->nodePtr->location, Error, "Divergent declaration of function: `%s`", function->name);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
//a function can have multiple declartations but all have to be identical
|
|
||||||
}
|
}
|
||||||
g_hash_table_insert(declaredFunctions, (gpointer) name, function);
|
g_hash_table_insert(declaredFunctions, (gpointer) name, function);
|
||||||
}
|
}
|
||||||
return SEMANTIC_OK;
|
|
||||||
|
|
||||||
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFunction(const char *name, Function **function) {
|
int getFunction(const char *name, Function **function) {
|
||||||
|
@ -2035,15 +2042,12 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
AST_NODE_PTR nameNode = currentNode->children[0];
|
AST_NODE_PTR nameNode = currentNode->children[0];
|
||||||
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
AST_NODE_PTR paramlistlist = currentNode->children[1];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunctionDeclaration fundecl;
|
FunctionDeclaration fundecl;
|
||||||
|
|
||||||
fundecl.nodePtr = currentNode;
|
fundecl.nodePtr = currentNode;
|
||||||
fundecl.name = nameNode->value;
|
fundecl.name = nameNode->value;
|
||||||
fundecl.parameter = mem_alloc(MemoryNamespaceSet, sizeof(GArray));
|
fundecl.parameter = mem_alloc(MemoryNamespaceSet, sizeof(GArray));
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < paramlistlist->child_count; i++) {
|
for (size_t i = 0; i < paramlistlist->child_count; i++) {
|
||||||
|
|
||||||
//all parameter lists
|
//all parameter lists
|
||||||
|
@ -2051,9 +2055,7 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
for (size_t j = 0; j < paramlistlist->child_count; j++) {
|
for (size_t j = 0; j < paramlistlist->child_count; j++) {
|
||||||
|
|
||||||
int signal = createParam(fundecl.parameter ,paramlist->children[i]);
|
if (createParam(fundecl.parameter, paramlist->children[i])) {
|
||||||
//all params per list
|
|
||||||
if (signal){
|
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2066,19 +2068,17 @@ int createFunDecl(Function * Parentfunction ,AST_NODE_PTR currentNode){
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int createFunction(Function *function, AST_NODE_PTR currentNode) {
|
||||||
int createFunction(Function ** function, AST_NODE_PTR currentNode){
|
|
||||||
assert(currentNode->kind == AST_Fun);
|
assert(currentNode->kind == AST_Fun);
|
||||||
Function * fun = mem_alloc(MemoryNamespaceSet,sizeof(Function));
|
|
||||||
functionParameter = g_hash_table_new(g_str_hash, g_str_equal);
|
functionParameter = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
|
||||||
if (currentNode->child_count == 2) {
|
if (currentNode->child_count == 2) {
|
||||||
int signal = createFunDecl(fun, currentNode);
|
int signal = createFunDecl(function, currentNode);
|
||||||
if (signal) {
|
if (signal) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
} else if (currentNode->child_count == 3) {
|
} else if (currentNode->child_count == 3) {
|
||||||
int signal = createFunDef(fun, currentNode);
|
int signal = createFunDef(function, currentNode);
|
||||||
if (signal) {
|
if (signal) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2086,21 +2086,17 @@ int createFunction(Function ** function, AST_NODE_PTR currentNode){
|
||||||
PANIC("function should have 2 or 3 children");
|
PANIC("function should have 2 or 3 children");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
g_hash_table_destroy(functionParameter);
|
g_hash_table_destroy(functionParameter);
|
||||||
|
functionParameter = NULL;
|
||||||
|
|
||||||
int result = addFunction(fun->name,fun);
|
int result = addFunction(function->name, function);
|
||||||
if (result == SEMANTIC_ERROR) {
|
if (result == SEMANTIC_ERROR) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*function = fun;
|
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
|
int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
|
||||||
|
|
||||||
Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
||||||
|
@ -2159,7 +2155,7 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode){
|
||||||
int createBoxFunction(const char *boxName, Type *ParentBoxType, AST_NODE_PTR currentNode) {
|
int createBoxFunction(const char *boxName, Type *ParentBoxType, AST_NODE_PTR currentNode) {
|
||||||
Function *function = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
Function *function = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
||||||
|
|
||||||
int result = createFunction(&function,currentNode);
|
int result = createFunction(function, currentNode);
|
||||||
if (result == SEMANTIC_ERROR) {
|
if (result == SEMANTIC_ERROR) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2195,7 +2191,6 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){
|
||||||
boxType->nodePtr = currentNode;
|
boxType->nodePtr = currentNode;
|
||||||
boxType->impl.box = box;
|
boxType->impl.box = box;
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; boxMemberList->child_count; i++) {
|
for (size_t i = 0; boxMemberList->child_count; i++) {
|
||||||
switch (boxMemberList->children[i]->kind) {
|
switch (boxMemberList->children[i]->kind) {
|
||||||
case AST_Decl:
|
case AST_Decl:
|
||||||
|
@ -2224,10 +2219,7 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode){
|
||||||
}
|
}
|
||||||
g_hash_table_insert(boxes, (gpointer) boxName, box);
|
g_hash_table_insert(boxes, (gpointer) boxName, box);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) {
|
int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) {
|
||||||
|
@ -2235,7 +2227,6 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){
|
||||||
AST_NODE_PTR typeNode = currentNode->children[0];
|
AST_NODE_PTR typeNode = currentNode->children[0];
|
||||||
AST_NODE_PTR nameNode = currentNode->children[1];
|
AST_NODE_PTR nameNode = currentNode->children[1];
|
||||||
|
|
||||||
|
|
||||||
Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type));
|
||||||
int status = set_get_type_impl(typeNode, &type);
|
int status = set_get_type_impl(typeNode, &type);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
@ -2248,10 +2239,15 @@ int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode){
|
||||||
def->type = type;
|
def->type = type;
|
||||||
|
|
||||||
if (g_hash_table_contains(types, (gpointer) def->name)) {
|
if (g_hash_table_contains(types, (gpointer) def->name)) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Multiple definition of type: `%s`",
|
||||||
|
nameNode->value);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_hash_table_insert(types, (gpointer) def->name, def);
|
g_hash_table_insert(types, (gpointer) def->name, def);
|
||||||
|
|
||||||
if (g_hash_table_contains(declaredComposites, (gpointer) def->name)) {
|
if (g_hash_table_contains(declaredComposites, (gpointer) def->name)) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Multiple definition of type: `%s`",
|
||||||
|
nameNode->value);
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_hash_table_insert(declaredComposites, (gpointer) def->name, def->type);
|
g_hash_table_insert(declaredComposites, (gpointer) def->name, def->type);
|
||||||
|
@ -2270,7 +2266,6 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
//create scope
|
//create scope
|
||||||
Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable *));
|
Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable *));
|
||||||
|
|
||||||
|
|
||||||
//building current scope for module
|
//building current scope for module
|
||||||
GHashTable *globalscope = g_hash_table_new(g_str_hash, g_str_equal);
|
GHashTable *globalscope = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
globalscope = g_hash_table_new(g_str_hash, g_str_equal);
|
globalscope = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
@ -2292,24 +2287,16 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
DEBUG("created Module struct");
|
DEBUG("created Module struct");
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
DEBUG("created Child with type: %i", currentNode->children[i]->kind);
|
DEBUG("created Child with type: %i", currentNode->children[i]->kind);
|
||||||
switch (currentNode->children[i]->kind) {
|
switch (currentNode->children[i]->kind) {
|
||||||
|
|
||||||
case AST_Decl: {
|
case AST_Decl: {
|
||||||
GArray *vars;
|
GArray *vars = NULL;
|
||||||
int status = createDecl(currentNode->children[i], &vars);
|
int status = createDecl(currentNode->children[i], &vars);
|
||||||
if (status) {
|
if (status) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) {
|
if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) {
|
||||||
// TODO: this diagnostic will highlight entire declaration of
|
|
||||||
// of variables even if just one of the declared variables
|
|
||||||
// is duplicate. Consider moving this diagnostic to
|
|
||||||
// `fillTablesWithVars` for more precise messaging.
|
|
||||||
print_diagnostic(current_file, ¤tNode->children[i]->location, Error,
|
|
||||||
"Variable already declared");
|
|
||||||
INFO("var already exists");
|
INFO("var already exists");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2322,6 +2309,10 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
if (status) {
|
if (status) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (fillTablesWithVars(variables, vars) == SEMANTIC_ERROR) {
|
||||||
|
INFO("var already exists");
|
||||||
|
break;
|
||||||
|
}
|
||||||
DEBUG("created Definition successfully");
|
DEBUG("created Definition successfully");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2330,27 +2321,27 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
if (status) {
|
if (status) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("created Box successfully");
|
DEBUG("created Box successfully");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AST_Fun: {
|
case AST_Fun: {
|
||||||
DEBUG("start function");
|
DEBUG("start function");
|
||||||
Function *function = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
Function *function = mem_alloc(MemoryNamespaceSet, sizeof(Function));
|
||||||
int status = createFunction(&function,currentNode->children[i]);
|
|
||||||
if(status == SEMANTIC_ERROR) {
|
if (createFunction(function, currentNode->children[i]) == SEMANTIC_ERROR) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_hash_table_contains(functions, function->name)) {
|
if (g_hash_table_contains(functions, function->name)) {
|
||||||
|
print_diagnostic(current_file, &function->impl.definition.nodePtr->location, Error,
|
||||||
|
"Multiple definition of function: `%s`", function->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert(functions, (gpointer) function->name, function);
|
g_hash_table_insert(functions, (gpointer) function->name, function);
|
||||||
if (status){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
DEBUG("created function successfully");
|
DEBUG("created function successfully");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
case AST_Typedef: {
|
case AST_Typedef: {
|
||||||
int status = createTypeDef(types, currentNode->children[i]);
|
int status = createTypeDef(types, currentNode->children[i]);
|
||||||
|
@ -2367,12 +2358,9 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
default:
|
default:
|
||||||
INFO("Provided source file could not be parsed because of semantic error.");
|
INFO("Provided source file could not be parsed because of semantic error.");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG("created set successfully");
|
DEBUG("created set successfully");
|
||||||
return rootModule;
|
return rootModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue