Skip to content

Commit

Permalink
Minor changes in AutotypeCollector
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-pino committed Mar 1, 2021
1 parent 0403f3e commit 59aa082
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 37 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,6 @@ src/zTests/Misc/10BiG.cl
.gitignore
./gitignore
.gitignore
src/type_logger.py
src/zTests/Auto/00Simple.cl
src/zTests/Auto/01Assign.cl
74 changes: 38 additions & 36 deletions src/semantics/autotype_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ def visit(self, node, scope):

self.visit(node.expr, scope)
node_expr = node.expr.inferenced_type
conforms(node_expr, node_type)
expr_clone = node_expr.clone()
if not conforms(node_expr, node_type):
self.add_error(node, f"Type Error: In class '{self.current_type.name}' attribue '{node.id}' expression type({expr_clone.name}) does not conforms to declared type ({node_type.name}).")
# What is made error type here!!!

var = scope.find_variable(node.id)
var.type = node_type
Expand All @@ -59,12 +62,11 @@ def visit(self, node, scopex):
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})")
if not conforms(ret_type_expr, ret_type_decl):
self.add_error(node, f"Type Error: In Class \'{self.current_type.name}\' method \'{current_method.name}\' return expression type({ret_expr_clone.name}) does not conforms to declared return type ({ret_type_decl.name})")
ret_type_expr = ErrorType()

node.body.inferenced_type = ret_type_expr

node.inferenced_type = ret_type_decl.clone()
node.inferenced_type = ret_type_expr
ret_type_decl.swap_self_type(self.current_type, back = True)

@visitor.when(BlocksNode)
Expand Down Expand Up @@ -154,16 +156,14 @@ def visit(self, node, scope):
else:
self.add_error(node, f"Semantic Error: Variable \'{node.id}\' already defined in current scope.")
node.defined = False
node_type = ErrorType()

if node.expr:
self.visit(node.expr, scope)
expr_type = node.expr.inferenced_type
expr_clone = expr_type.clone()
if not conforms(expr_clone, node_type):
self.add_error(node, f"Semantic Error: Variable \'{node.id}\' expression type({expr_type.name}) does not conforms to declared type({node_type.name}).")
else:
expr_type = expr_clone
node.expr.inferenced_type = expr_type
if not conforms(expr_type, node_type):
self.add_error(node, f"Semantic Error: Variable \'{node.id}\' expression type({expr_clone.name}) does not conforms to declared type({node_type.name}).")

node.inferenced_type = node_type

Expand All @@ -179,16 +179,19 @@ def visit(self, node, scope:Scope):

self.visit(node.expr, scope)
node_expr = node.expr.inferenced_type
node_type = var_type

if var and var.name != 'self':
node_expr_clone = node.expr.inferenced_type.clone()
if not conforms(node_expr, var_type):
self.add_error(node, "")
self.add_error(node, f"Type Error: Cannot assign new value to variable '{node.id}'. Expression type({node_expr_clone.name}) does not conforms to declared type ({var_type.name}).")
node_type = ErrorType()
var.type = var_type
elif var.name =='self':
self.add_error(node, "Semantic Error: Cannot assign new value. Variable 'self' is Read-Only.")
var_type = ErrorType()
node_type = ErrorType()

node.inferenced_type = var_type
node.inferenced_type = node_type

@visitor.when(MethodCallNode)
def visit(self, node, scope):
Expand All @@ -207,39 +210,43 @@ def visit(self, node, scope):
self.add_error(node, f"Semantic Error: Cannot effect dispatch because expression type({bridge_clone.name}) does not conforms to caller type({caller.name}).")
caller = ErrorType()



methods = None
if len(caller.type_set) > 1:
methods_by_name = self.context.get_method_by_name(node.id, len(node.args))
types = [typex for _, typex in methods_by_name]
conforms(caller, TypeBag(set(types)))
conforms(caller, TypeBag(set(types), types))
if len(caller.type_set):
methods = [(t, t.get_method) for t in caller.heads]
else:
self.add_error(node, f"Semantic Error: There is no method \'{node.id}\' that recieves {len(node.params)} arguments in Types {caller.name}.")
caller = ErrorType()
elif len(caller.type_set) == 1:
caller_type = caller.heads[0]
try:
methods = [(caller_type, caller_type.get_method(node.id))]
except SemanticError:
self.add_error(node, f"Semantic Error: There is no method \'{node.id}\' that recieves {len(node.params)} arguments in Type \'{caller.name}\'.")

caller = ErrorType()

if methods:
type_set = set()
heads = []
for typex, method in methods:
ret_type = method.return_type.clone()
ret_type.swap_self_type(typex)
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)
for i in range(len(node.args)):
arg = node.args[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:
node.inferenced_type = ErrorType()
node.inferenced_caller = caller

@visitor.when(ArithmeticNode)
def visit(self, node, scope):
Expand All @@ -253,11 +260,9 @@ def visit(self, node, scope):

int_type = self.context.get_type("Int")
if not conforms(left_type, int_type):
self.add_error(node, f"Type Error: Arithmetic Error: Left member type({left_clone.name}) does not conforms to Int type.")
int_type = ErrorType()
self.add_error(node.left, f"Type Error: Arithmetic Error: Left member type({left_clone.name}) does not conforms to Int type.")
if not conforms(right_type, 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()
self.add_error(node.right, f"Type Error: Arithmetic Error: Right member type({right_clone.name}) does not conforms to Int type.")

node.inferenced_type = int_type

Expand All @@ -269,14 +274,13 @@ def visit(self, node, scope):
self.visit(node.right, scope)
right_type = node.right.inferenced_type

node_type = self.context.get_type("Bool")
bool_type = self.context.get_type("Bool")
left_clone = left_type.clone()
right_clone = right_type.clone()
if not conforms(left_clone, right_type) and not conforms(right_clone, left_type):
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.inferenced_type = node_type
node.inferenced_type = bool_type

@visitor.when(VariableNode)
def visit(self, node, scope:Scope):
Expand All @@ -295,21 +299,21 @@ def visit(self, node, scope):
self.visit(node.expr, scope)
expr_type = node.expr.inferenced_type
expr_clone = expr_type.clone()
node_type = self.context.get_type("Bool")
if not conforms(expr_clone, node_type):
self.add_error(node, f"Type Error: Not's expresion type({expr_type.name} does not conforms to Bool type")
node_type = ErrorType()
bool_type = self.context.get_type("Bool")
if not conforms(expr_type, bool_type):
self.add_error(node, f"Type Error: Not's expresion type({expr_clone.name} does not conforms to Bool type")

node.inferenced_type = node_type
node.inferenced_type = bool_type

@visitor.when(ComplementNode)
def visit(self, node, scope):
self.visit(node.expr, scope)
expr_type = node.expr.inferenced_type
expr_clone = expr_type.clone()
node_type = self.context.get_type("Int")

if not conforms(expr_type, node_type):
self.add_error(node, f"Type Error: Not's expresion type({expr_type.name} does not conforms to Int type")
self.add_error(node, f"Type Error: Not's expresion type({expr_clone.name} does not conforms to Int type")
node_type = ErrorType()

node.inferenced_type = node_type
Expand Down Expand Up @@ -342,6 +346,4 @@ 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(((line,col), f"({line}, {col}) - " + text))

# todo: Cambiar self.error a que cada error tengo la tupla de localizacion, asi permite organizar los errores
self.errors.append(((line,col), f"({line}, {col}) - " + text))
7 changes: 6 additions & 1 deletion src/semantics/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def define_attribute(self, name:str, typex):
self.attributes.append(attribute)
return attribute
else:
raise SemanticError(f'Attribute "{name}" is already defined in {self.name}.')
raise SemanticError(f'Attribute "{name}" is already defined in "{self.name}".')

def get_attribute(self, name:str, first=None):
if not first:
Expand Down Expand Up @@ -506,6 +506,11 @@ def join_list(type_list):
join_result = join(join_result, type_i)
return join_result

def equal(bag1:TypeBag, bag2:TypeBag):
set1 = bag1.type_set
set2 = bag2.type_set
return len(set1) == len(set2) and len(set1.intersection(set2)) == len(set2)

def smart_add(type_set:set, head_list:list, typex:Type):
if isinstance(typex, TypeBag):
return auto_add(type_set, head_list, typex)
Expand Down

0 comments on commit 59aa082

Please sign in to comment.