Skip to content

Commit

Permalink
Commit after conflict resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian13579 committed Feb 28, 2021
2 parents d98b7b3 + db88b88 commit 9a958a1
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 38 deletions.
40 changes: 17 additions & 23 deletions src/semantics/autotype_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ def visit(self, node, scopex):
for idx, typex in zip(current_method.param_names, current_method.param_types):
scope.define_variable(idx, typex)

self.visit(node.body, scope)
ret_type_decl = current_method.return_type.swap_self_type(self.current_type)
self.visit(node.body, scope)
ret_type_expr = node.body.inferenced_type

ret_expr_clone = ret_type_expr.clone()
if not conforms(ret_expr_clone, ret_type_decl):
self.add_error(node, f"Type Error: In Class \'{self.current_type.name}\' method \'{current_method.name}\' return expression type({ret_type_expr.name} does not conforms to declared return type ({ret_type_decl.name}))")
self.add_error(node, f"Type Error: In Class \'{self.current_type.name}\' method \'{current_method.name}\' return expression type({ret_type_expr.name}) does not conforms to declared return type ({ret_type_decl.name})")

node.body.inferenced_type = ret_type_expr

Expand All @@ -81,7 +81,7 @@ def visit(self, node, scope):

condition_clone = condition_type.clone()
if not conforms(condition_clone, bool_type):
self.add_error(node, f"Type Error: If's condition type({condition_type.name} does not conforms to Bool type")
self.add_error(node, f"Type Error: If's condition type({condition_type.name}) does not conforms to Bool type.")

self.visit(node.then_body, scope)
then_type = node.then_body.inferenced_type
Expand Down Expand Up @@ -138,7 +138,7 @@ def visit(self, node, scope):
child = scope.create_child()
for var in node.var_decl_list:
self.visit(var, child)
self.visit(node.in_expr, scope)
self.visit(node.in_expr, child)
node.inferenced_type = node.in_expr.inferenced_type

@visitor.when(VarDeclarationNode)
Expand Down Expand Up @@ -229,13 +229,13 @@ def visit(self, node, scope):
for typex, method in methods:
ret_type = method.return_type.clone()
ret_type.swap_self_type(typex)
smart_add(type_set, heads, ret_type)
for i in range(len(node.args)):
arg, param_type = node.args[i], method.param_types[i]
self.visit(arg, scope)
arg_type = arg.inferenced_type
arg_clone = arg_type.clone()
conforms(arg_clone, param_type)
type_set = smart_add(type_set, heads, ret_type)
#for i in range(len(node.args)):
# arg, param_type = node.args[i], method.param_types[i]
# self.visit(arg, scope)
# arg_type = arg.inferenced_type
# arg_clone = arg_type.clone()
# conforms(arg_clone, param_type)

node.inferenced_type = TypeBag(type_set, heads)
else:
Expand All @@ -256,7 +256,7 @@ def visit(self, node, scope):
self.add_error(node, f"Type Error: Arithmetic Error: Left member type({left_clone.name}) does not conforms to Int type.")
int_type = ErrorType()
if not conforms(right_type, int_type):
self.add_error(node, f"Type Error: Arithmetic Error: Left member type({right_clone.name}) does not conforms to Int type.")
self.add_error(node, f"Type Error: Arithmetic Error: Right member type({right_clone.name}) does not conforms to Int type.")
int_type = ErrorType()

node.inferenced_type = int_type
Expand All @@ -276,21 +276,18 @@ def visit(self, node, scope):
self.add_error(node, f"Type Error: Left expression type({left_type.name}) does not conforms to right expression type({right_type.name})")
node_type = ErrorType()

#node.left.inferenced_type = left_clone
#node.right.inferenced_type = right_clone

node.inferenced_type = node_type

@visitor.when(VariableNode)
def visit(self, node, scope):
def visit(self, node, scope:Scope):
var = scope.find_variable(node.value)
if var:
node.defined = True
var_type = var.type
else:
node.defined = False
var_type = ErrorType()
self.add_error(node, f"Semantic Error: Variable '{node.id}' is not defined.")
self.add_error(node, f"Semantic Error: Variable '{node.value}' is not defined.")
node.inferenced_type = var_type

@visitor.when(NotNode)
Expand Down Expand Up @@ -327,6 +324,7 @@ def visit(self, node, scope):
try:
node_type = self.context.get_type(node.value, selftype=False, autotype=False)
except SemanticError as err:
self.add_error(f"Semantic Error: Could not instantiate type '{node.value}'.")
node_type = ErrorType()
node.inferenced_type = node_type

Expand All @@ -344,10 +342,6 @@ def visit(self, node, scope):

def add_error(self, node:Node, text:str):
line, col = node.get_position() if node else (0, 0)
self.errors.append(f"({line}, {col}) - " + text)
# todo: Revisar los auto types que me hace falta y que no
# todo: completar de manera acorde el autotype collector
# todo: Annadir error en VarDeclarationNode
# todo: Annadir error en MethodCallNode (2)
# todo: annadir error en INsyantiate Node
self.errors.append(((line,col), f"({line}, {col}) - " + text))

# todo: Cambiar self.error a que cada error tengo la tupla de localizacion, asi permite organizar los errores
30 changes: 19 additions & 11 deletions src/semantics/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,37 +111,40 @@ def get_method(self, name:str, local:bool = False, first = None):
def define_method(self, name:str, param_names:list, param_types:list, return_type):
if name in (method.name for method in self.methods):
raise SemanticError(f'Method \'{name}\' already defined in \'{self.name}\'')

try:
parent_method = self.get_method(name)
except SemanticError:
parent_method = None
if parent_method:
error_list = []
return_type.swap_self_type(self)
return_clone = return_type.clone()
parent_method.return_type.swap_self_type(self)
if not conforms(return_type, parent_method.return_type):
error_list.append(f" -> Same return type: Redefined method has \'{return_type.name}\' as return type instead of \'{parent_method.return_type.name}\'.")
error_list.append(f" -> Same return type: Redefined method has \'{return_clone.name}\' as return type instead of \'{parent_method.return_type.name}\'.")
if len(param_types) != len(parent_method.param_types):
error_list.append(f" -> Same amount of params: Redefined method has {len(param_types)} params instead of {len(parent_method.param_types)}.")
else:
count = 0
err = []
for param_type, parent_param_type in zip(param_types, parent_method.param_types):
param_clone = param_type.clone()
if not conforms(param_type, parent_param_type):
err.append(f" -Param number {count} has {param_type.name} as type instead of {parent_param_type.name}")
err.append(f" -Param number {count} has {param_clone.name} as type instead of {parent_param_type.name}")
count += 1
if err:
s = f" -> Same param types:\n" + "\n".join(child for child in err)
error_list.append(s)
return_type.swap_self_type(self, back = True)
parent_method.return_type.swap_self_type(self, back = True)
if error_list:
err = f"Redifined method \"{name}\" in class {self.name} does not have:\n" + "\n".join(child for child in error_list)
err = f"Redifined method \'{name}\' in class \'{self.name}\' does not have:\n" + "\n".join(child for child in error_list)
raise SemanticError(err)

method = Method(name, param_names, param_types, return_type)
self.methods.append(method)

return method

def all_attributes(self, clean=True, first=None):
Expand Down Expand Up @@ -275,6 +278,8 @@ def swap_self_type(self, swap_type, back = False):
if typex.name == remove_type.name:
self.heads[i] = add_type
break

self.name = self.generate_name()
return self

def generate_name(self):
Expand All @@ -287,9 +292,9 @@ def generate_name(self):
return s

def clone(self):
clone = TypeBag(self.type_set, self.heads)
clone.condition_list = self.condition_list
clone.conform_list = self.conform_list
clone = TypeBag(self.type_set.copy(), self.heads.copy())
clone.condition_list = self.condition_list.copy()
clone.conform_list = self.conform_list.copy()
return clone

class SelfType(Type):
Expand Down Expand Up @@ -330,6 +335,9 @@ def swap_self_type(self, swap_type):

def set_conditions(self, *params):
return

def clone(self):
return self

class Context:
def __init__(self) -> None:
Expand Down Expand Up @@ -416,7 +424,7 @@ def find_variable(self, vname, index=None):
return next(x for x in locals if x.name == vname)
except StopIteration:
try:
return self.parent.find_variable(vname, self.index) if self.parent else None
return self.parent.find_variable(vname, self.index) if self.parent is not None else None
except AttributeError:
return None

Expand Down Expand Up @@ -516,7 +524,7 @@ def smart_add(type_set:set, head_list:list, typex:Type):
break
if not there_is:
head_list.append(typex)
return head_list, type_set
return type_set

def auto_add(type_set:set, head_list:list, bag:TypeBag):
type_set = type_set.union(bag.type_set)
Expand All @@ -530,5 +538,5 @@ def auto_add(type_set:set, head_list:list, bag:TypeBag):
aux.pop(head)
break
head_list += [typex for typex in aux]
return head_list, type_set
return type_set

4 changes: 2 additions & 2 deletions src/semantics/type_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,5 @@ def build_default_classes(self):
Io.define_method("in_int", [], [], p_Int)

def add_error(self, node:Node, text:str):
line, col = node.get_position() if node else 0, 0
self.errors.append(f"({line}, {col}) - " + text)
line, col = node.get_position() if node else (0, 0)
self.errors.append(((line,col), f"({line}, {col}) - " + text))
4 changes: 2 additions & 2 deletions src/semantics/type_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ def init_default_classes(self):
self.context.create_type('Bool')

def add_error(self, node:Node, text:str):
line, col = node.get_position() if node else 0, 0
self.errors.append(f"({line}, {col}) - " + text)
line, col = node.get_position() if node else (0, 0)
self.errors.append(((line,col), f"({line}, {col}) - " + text))

0 comments on commit 9a958a1

Please sign in to comment.