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