def visit(self, ddispatch, scope, errs): if not self.visit(ddispatch.instance, scope, errs): return False for arg in ddispatch.arguments: if not self.visit(arg, scope, errs): return False m = scope.is_define_method(ddispatch.instance.static_type, ddispatch.method) if not m: errs.append('Method {} not found at line {}'.format( ddispatch.method, ddispatch.lineno)) return False if len(ddispatch.arguments) != len(m) - 1: errs.append( 'Missing arguments for method dispatch at line {}'.format( ddispatch.lineno)) return False for i in range(len(ddispatch.arguments)): if not scope.inherit(ddispatch.arguments[i].static_type, m[i]): errs.append( 'Type of argument {} does not conform declared type in function call at line {}' .format(i + 1, ddispatch.lineno)) return False ddispatch.static_type = ddispatch.instance.static_type if m[ -1] == 'SELF_TYPE' else m[-1] return True
def visit(self, method, scope, errs): for p in method.formal_params: if not self.visit(p, scope, errs): return False child = scope.createChildScope() for p in method.formal_params: child.O(p.name, p.param_type) if not self.visit(method.body, child, errs): return False t = scope.is_define_obj( 'self' ) if method.return_type == 'SELF_TYPE' else method.return_type if not scope.is_define_type(t): errs.append('Type {} is not defined at line {}'.format( t, method.lineno)) return False if not scope.inherit(method.body.static_type, t): errs.append( 'Method {}\'s body type does not conform declared return type at line {}' .format(method.name, method.lineno)) return False if (scope.inherit(method.class_name, OBJECT_CLASS) and method.name in ['abort', 'copy', 'type_name']) or \ (scope.inherit(method.class_name, IO_CLASS) and method.name in ['in_int', 'in_string', 'out_int', 'out_string']) or \ (scope.inherit(method.class_name, STRING_CLASS) and method.name in ['length', 'concat', 'substr']): errs.append( 'Built-in method {} cannot be redefined at line {}'.format( method.name, method.lineno)) return None method.static_type = t return True # if __name__ == "__main__": # s = CoolParser() # fpath = "/home/luis/Desktop/Cool-Compiler/cool-compiler-hieu-luis-alejandro/examples/mytest.cl" # ast = None # with open(fpath, encoding="utf-8") as file: # cool_program_code = file.read() # ast = s.parse(cool_program_code) # semantic = Semananalyzer() # semantic.analyze(ast)
def visit(self, sdispatch, scope, errs): if not self.visit(sdispatch.instance, scope, errs): return False t = scope.is_define_obj( 'self' ) if sdispatch.dispatch_type == 'SELF_TYPE' else sdispatch.dispatch_type if not scope.is_define_type(t): errs.append('Type {} is not defined at line {}'.format( t, sdispatch.lineno)) return False if not scope.inherit(sdispatch.instance.static_type, t): errs.append( 'Type to the left of @ : {} must conform the type specified to the right of @: {}, at line {}' .format(sdispatch.instance.static_type, t, sdispatch.lineno)) return False for arg in sdispatch.arguments: if not self.visit(arg, scope, errs): return False m = scope.is_define_method(sdispatch.instance.static_type, sdispatch.method) if not m: errs.append('Method {} not found at line {}'.format( sdispatch.method, sdispatch.lineno)) return False if len(sdispatch.arguments) != len(m) - 1: errs.append( 'Missing arguments for method dispatch at line {}'.format( sdispatch.lineno)) return False for i in range(len(sdispatch.arguments)): if not scope.inherit(sdispatch.arguments[i].static_type, m[i]): errs.append( 'Type of argument {} does not conform declared type in function call at line {}' .format(i + 1, sddispatch.lineno)) return False sdispatch.static_type = sdispatch.instance.static_type if m[ -1] == 'SELF_TYPE' else m[-1] return True
def visit(self, Assign, scope, errs): if not self.visit(Assign.instance, scope, errs): return False if not self.visit(Assign.expr, scope, errs): return False if not scope.inherit(Assign.expr.static_type, Assign.instance.static_type): errs.append( 'Invalid assignment of incompatible types: {} <- {} at line {}' .format(Assign.instance.static_type, Assign.expr.static_type, Assign.lineno)) return False Assign.static_type = Assign.expr.static_type return True
def visit(self, attr, scope, errs): t = scope.is_define_obj( 'self') if attr.attr_type == 'SELF_TYPE' else attr.attr_type if not scope.is_define_type(t): errs.append('Type {} is not defined at line {}'.format( t, attr.lineno)) return False if attr.init_expr: if not self.visit(attr.init_expr, scope, errs): return False if not scope.inherit(attr.init_expr.static_type, t): errs.append( 'Attribute initialization type does not conform declared type at line {}' .format(attr.lineno)) return False attr.static_type = t return True
def visit(self, letvar, scope, errs): t = scope.is_define_obj( 'self') if letvar.ttype == 'SELF_TYPE' else letvar.ttype if not scope.is_define_type(t): errs.append('Type {} is not defined at line {}'.format( t, letvar.lineno)) return False if letvar.initialization: if not self.visit(letvar.initialization, scope, errs): return False if not scope.inherit(letvar.initialization.static_type, t): errs.append( "Type {} does not conform type {} at line {}".format( letvar.initialization.static_type, t, letvar.lineno)) return False scope.O(letvar.name, t) letvar.static_type = letvar.initialization.static_type if letvar.initialization else t return True