Example #1
0
 def visit(self, node):
     try:
         self.current_type = self.context.get_type(node.id, node.pos)
     except SemanticError as error:
         self.current_type = ErrorType()
         self.errors.append(error)    
     if node.parent is not None:
         if node.parent in ['Int', 'String', 'Bool']:
             self.errors.append(SemanticError(INHERIT_ERROR % (node.id, node.parent), *node.parent_pos))
         try:
             parent = self.context.get_type(node.parent, node.parent_pos)
         except SemanticError:
             self.errors.append(TypesError(INHERIT_UNDEFINED % (node.id, node.parent), *node.parent_pos))
             parent = None
         try:
             current = parent
             while current is not None:
                 if current.name == self.current_type.name:
                     raise SemanticError(CIRCULAR_DEPENDENCY %(self.current_type.name, self.current_type.name) , *node.pos)
                 current = current.parent
         except SemanticError as e:
             parent = ErrorType()
             self.errors.append(e)
         self.current_type.set_parent(parent)    
     for feature in node.features:
         self.visit(feature)
Example #2
0
 def visit(self, node, scope):
     parent = self.current_type.parent
     self.current_method = method = self.current_type.get_method(
         node.id, node.pos)
     if parent is not None:
         try:
             old_meth = parent.get_method(node.id, node.pos)
             if old_meth.return_type.name != method.return_type.name:
                 self.errors.append(
                     SemanticError(
                         WRONG_SIGNATURE_RETURN %
                         (node.id, method.return_type.name,
                          old_meth.return_type.name), *node.type_pos))
             if len(method.param_names) != len(old_meth.param_names):
                 self.errors.append(
                     SemanticError(WRONG_NUMBER_PARAM % node.id, *node.pos))
             for (name, param), type1, type2 in zip(node.params,
                                                    method.param_types,
                                                    old_meth.param_types):
                 if type1.name != type2.name:
                     self.errors.append(
                         SemanticError(
                             WRONG_SIGNATURE_PARAMETER %
                             (name, type1.name, type2.name), *param.pos))
         except SemanticError:
             pass
     result = self.visit(node.body, scope)
     return_type = get_type(method.return_type, self.current_type)
     if not result.conforms_to(return_type):
         self.errors.append(
             TypesError(RETURN_TYPE_ERROR % (result.name, return_type.name),
                        *node.type_pos))
Example #3
0
 def visit(self, node, scope):
     cond = self.visit(node.cond, scope)
     if cond.name != 'Bool':
         self.errors.append(
             TypesError(PREDICATE_ERROR % ('if', 'Bool'), *node.pos))
     true_type = self.visit(node.stm, scope)
     false_type = self.visit(node.else_stm, scope)
     return get_common_basetype([false_type, true_type])
Example #4
0
 def visit(self, node, scope):
     try:
         type_ = self.context.get_type(node.lex, node.pos)
     except SemanticError:
         type_ = ErrorType()
         self.errors.append(
             TypesError(NEW_UNDEFINED_CLASS % node.lex, *node.pos))
     return get_type(type_, self.current_type)
Example #5
0
 def visit(self, node, scope):
     vinfo = self.find_variable(scope, node.id)
     vtype = get_type(vinfo.type, self.current_type)
     typex = self.visit(node.expr, scope)
     if not typex.conforms_to(vtype):
         self.errors.append(
             TypesError(UNCONFORMS_TYPE % (typex.name, node.id, vtype.name),
                        *node.pos))
     return typex
Example #6
0
 def visit(self, node, scope):
     ltype = self.visit(node.expr, scope)
     int_type = IntType()
     if ltype != int_type:
         self.errors.append(
             TypesError(
                 UOPERATION_NOT_DEFINED % ('~', ltype.name, int_type.name),
                 *node.pos))
         return ErrorType()
     return int_type
Example #7
0
 def visit(self, node, scope):
     ltype = self.visit(node.expr, scope)
     typex = BoolType()
     if ltype != typex:
         self.errors.append(
             TypesError(
                 UOPERATION_NOT_DEFINED % ('not', ltype.name, typex.name),
                 *node.pos))
         return ErrorType()
     return typex
Example #8
0
 def visit(self, node, scope):
     ltype = self.visit(node.left, scope)
     rtype = self.visit(node.right, scope)
     if (ltype == IntType() or rtype == IntType() or ltype == StringType()
             or rtype == StringType() or ltype == BoolType()
             or rtype == BoolType()) and ltype != rtype:
         self.errors.append(TypesError(COMPARISON_ERROR, *node.pos))
         return ErrorType()
     else:
         return BoolType()
Example #9
0
 def visit(self, node, scope):
     vtype = self.get_type(node.type, node.type_pos)
     vtype = get_type(vtype, self.current_type)
     if node.expr != None:
         typex = self.visit(node.expr, scope)
         if not typex.conforms_to(vtype):
             self.errors.append(
                 TypesError(
                     UNCONFORMS_TYPE % (typex.name, node.id, vtype.name),
                     *node.type_pos))
         return typex
     return vtype
Example #10
0
 def visit(self, node:AttrDeclarationNode):
     try:
         attr_type = self.context.get_type(node.type, node.pos)
     except SemanticError as error:
         attr_type = ErrorType(node.type_pos)
         self.errors.append(TypesError(ATTR_TYPE_UNDEFINED %(node.type, node.id), *node.type_pos))      
     if node.id == 'self':
         self.errors.append(SemanticError(SELF_ATTR, *node.pos)) 
     try:
         self.current_type.define_attribute(node.id, attr_type, node.pos)
     except SemanticError as error:
         self.errors.append(error)  
Example #11
0
 def visit(self, node, scope):
     attr = self.current_type.get_attribute(node.id, node.pos)
     vartype = get_type(attr.type, self.current_type)
     self.current_index = attr.index
     typex = self.visit(node.expr, scope)
     self.current_index = None
     if not typex.conforms_to(vartype):
         self.errors.append(
             TypesError(
                 ATTR_TYPE_ERROR % (typex.name, attr.name, vartype.name),
                 *node.pos))
         return ErrorType()
     return typex
Example #12
0
 def binary_operation(self, node, scope, operator):
     ltype = self.visit(node.left, scope)
     rtype = self.visit(node.right, scope)
     int_type = IntType()
     if ltype != int_type or rtype != int_type:
         self.errors.append(
             TypesError(
                 BOPERATION_NOT_DEFINED %
                 (ltype.name, operator, rtype.name), *node.pos))
         return ErrorType()
     if operator == '<' or operator == '<=':
         return BoolType()
     return int_type
Example #13
0
 def visit(self, node, scope):
     obj = self.visit(node.obj, scope)
     typex = self.get_type(node.type, node.type_pos)
     if not obj.conforms_to(typex):
         self.errors.append(
             TypesError(
                 INCOMPATIBLE_TYPES_DISPATCH % (typex.name, obj.name),
                 *node.type_pos))
         return ErrorType()
     meth = self.get_method(typex, node.id, node.pos)
     if not isinstance(meth, MethodError):
         self._check_args(meth, scope, node.args, node.pos)
     return get_type(meth.return_type, typex)
Example #14
0
 def visit(self, node:FuncDeclarationNode):
     args_names = []
     args_types = []
     for name, type_ in node.params:
         if name in args_names:
             self.errors.append(SemanticError(PARAMETER_MULTY_DEFINED % name, *type_.pos))
         args_names.append(name)      
         try:
             arg_type = self.context.get_type(type_.value, type_.pos)
         except SemanticError:
             self.errors.append(TypesError(PARAMETER_UNDEFINED % (type_.value, type_.value), *type_.pos))
             arg_type = ErrorType()
         args_types.append(arg_type)      
     try:
         return_type = self.context.get_type(node.type, node.type_pos)
     except SemanticError as error:
         self.errors.append(TypesError(RETURN_TYPE_UNDEFINED % (node.type, node.id), *node.type_pos))
         return_type = ErrorType(node.type_pos) 
     try:
         self.current_type.define_method(node.id, args_names, args_types, return_type, node.pos)
     except SemanticError as error:
         self.errors.append(error)
Example #15
0
 def _check_args(self, meth, scope, args, pos):
     arg_types = [self.visit(arg, scope) for arg in args]
     if len(arg_types) > len(meth.param_types):
         self.errors.append(SemanticError(ARGUMENT_ERROR % meth.name, *pos))
     elif len(arg_types) < len(meth.param_types):
         for arg, arg_info in zip(meth.param_names[len(arg_types):],
                                  args[len(arg_types):]):
             self.errors.append(
                 SemanticError(ARGUMENT_ERROR % (meth.name), *arg_info.pos))
     for atype, ptype, param_name in zip(arg_types, meth.param_types,
                                         meth.param_names):
         if not atype.conforms_to(ptype):
             self.errors.append(
                 TypesError(
                     INCOSISTENT_ARG_TYPE %
                     (meth.name, atype.name, param_name, ptype.name), *pos))
Example #16
0
 def visit(self, node, scope):
     cond = self.visit(node.cond, scope)
     if cond.name != 'Bool':
         self.errors.append(TypesError(LOOP_CONDITION_ERROR, *node.pos))
     self.visit(node.expr, scope)
     return ObjectType()