def type_check_constructor(attr_types, constructor): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, void, attr_types, True, dict(constructor.parameters) ) type_check_code_block.type_check_code_block(context, constructor.body)
def type_check_coroutine(coroutine): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, coroutine.receive_type, coroutine.yield_type, void, {}, False, dict(coroutine.parameters) ) type_check_code_block.type_check_code_block(context, coroutine.body)
def type_check_method(self_type, attr_types, method, store_attributes=False): types = {} types.update(primitives) types.update(module.types) scope = dict(method.parameters) scope['self'] = self_type context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, method.return_type, attr_types, store_attributes, scope ) type_check_code_block.type_check_code_block(context, method.body)
def type_check_function(function): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, function.return_type, {}, False, dict(function.parameters) ) try: type_check_code_block.type_check_code_block(context, function.body) except: print function.name raise
def type_check_module(module_interfaces, module_name, module_decl): module = module_interface.ModuleInterface(module_name, module_decl.imports) module_interfaces[module_name] = module def type_check_function(function): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, function.return_type, {}, False, dict(function.parameters) ) try: type_check_code_block.type_check_code_block(context, function.body) except: print function.name raise def type_check_coroutine(coroutine): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, coroutine.receive_type, coroutine.yield_type, void, {}, False, dict(coroutine.parameters) ) type_check_code_block.type_check_code_block(context, coroutine.body) def type_check_constructor(attr_types, constructor): types = {} types.update(primitives) types.update(module.types) context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, void, attr_types, True, dict(constructor.parameters) ) type_check_code_block.type_check_code_block(context, constructor.body) def type_check_method(self_type, attr_types, method, store_attributes=False): types = {} types.update(primitives) types.update(module.types) scope = dict(method.parameters) scope['self'] = self_type context = type_check_code_block.TypeCheckingContext( module_interfaces, module, types, None, None, method.return_type, attr_types, store_attributes, scope ) type_check_code_block.type_check_code_block(context, method.body) function_decls = [] coroutine_decls = [] enum_decls = [] interface_decls = [] service_decls = [] entry = None for decl in module_decl.decls: decl.module_interface = module if isinstance(decl, program.Function): function_decls.append(decl) elif isinstance(decl, program.Coroutine): coroutine_decls.append(decl) elif isinstance(decl, program.Enum): enum_decls.append(decl) elif isinstance(decl, program.Interface): interface_decls.append(decl) elif isinstance(decl, program.Service): service_decls.append(decl) elif isinstance(decl, program.Entry): assert not entry entry = decl for enum in enum_decls: enum.type_constructor = program_types.Enum(enum.name, {}) enum.type = program_types.Instantiation(enum.type_constructor, []) module.types[enum.name] = enum.type for enum in enum_decls: types = {} types.update(primitives) types.update(module.types) for constructor in enum.constructors: constructor.resolve_types(module_interfaces, types) assert not constructor.name in enum.type_constructor.constructors enum.type_constructor.constructors[constructor.name] = constructor.types signature = type_check_code_block.FunctionSignature(constructor.types, enum.type) module.signatures[constructor.name] = signature for interface in interface_decls: types = {} types.update(primitives) types.update(module.types) methods = {} for decl in interface.decls: decl.resolve_types(module_interfaces, types) methods[decl.name] = (decl.parameters, decl.return_type) interface.type_constructor = program_types.Interface(interface.name, interface.parameters, methods) assert not interface.name in primitives assert not interface.name in module.types module.types[interface.name] = interface.type_constructor for service in service_decls: types = {} types.update(primitives) types.update(module.types) attrs = {} dependency_names = [name for name, interface_name in service.dependencies] dependencies = [] constructor_signatures = {} interfaces = list() private_methods = {} for name, interface in service.dependencies: interface = interface.resolve_type(module_interfaces, types) if isinstance(interface, program_types.Interface): interface = program_types.Instantiation(interface, []) assert isinstance(interface, program_types.Instantiation) assert isinstance(interface.constructor, program_types.Interface) dependencies.append((name, interface)) for service_decl in service.decls: if isinstance(service_decl, program.Attr): service_decl.type = service_decl.type.resolve_type(module_interfaces, types) assert not service_decl.name in attrs assert not service_decl.name in dependency_names attrs[service_decl.name] = service_decl.type elif isinstance(service_decl, program.Implements): interface = service_decl.interface_type.resolve_type(module_interfaces, types) if isinstance(interface, program_types.Interface): interface = program_types.Instantiation(interface, []) assert isinstance(interface, program_types.Instantiation) assert isinstance(interface.constructor, program_types.Interface) assert len(interface.types) == len(interface.constructor.parameters) methods = {} for method_decl in service_decl.decls: method_decl.resolve_types(module_interfaces, types) methods[method_decl.name] = method_decl.signature assert methods == interface.methods interfaces.append(interface) elif isinstance(service_decl, program.Private): for private_decl in service_decl.decls: private_decl.resolve_types(module_interfaces, types) private_methods[private_decl.name] = private_decl.signature elif isinstance(service_decl, program.Constructor): service_decl.resolve_types(module_interfaces, types) constructor_signatures[service_decl.name] = service_decl.parameter_types service.type = program_types.Service(service.name, dependencies, attrs, constructor_signatures, interfaces) service.private_type = program_types.PrivateService(service.name, private_methods) module.services[service.name] = service.type for function in function_decls: types = {} types.update(primitives) types.update(module.types) assert not function.name in module.signatures function.resolve_types(module_interfaces, types) signature = type_check_code_block.FunctionSignature( function.parameter_types, function.return_type ) module.signatures[function.name] = signature for coroutine in coroutine_decls: types = {} types.update(primitives) types.update(module.types) assert not coroutine.name in module.signatures coroutine.resolve_types(module_interfaces, types) arg_types = coroutine.parameter_types signature = type_check_code_block.CoroutineSignature( coroutine.parameter_types, coroutine.receive_type, coroutine.yield_type ) module.signatures[coroutine.name] = signature for service in service_decls: all_attrs = service.type.all_attrs for service_decl in service.decls: if isinstance(service_decl, program.Implements): for method_decl in service_decl.decls: type_check_method(service.private_type, all_attrs, method_decl, True) elif isinstance(service_decl, program.Private): for private_decl in service_decl.decls: type_check_method(service.private_type, all_attrs, private_decl, True) elif isinstance(service_decl, program.Constructor): type_check_constructor(attrs, service_decl) for function in function_decls: type_check_function(function) for coroutine in coroutine_decls: type_check_coroutine(coroutine) if entry: types = {} types.update(primitives) types.update(module.types) entry_point_type = program_types.Instantiation(entry_point, []) context = type_check_code_block.TypeCheckingContext(module_interfaces, module, types, None, None, entry_point_type, {}, False, {}) type_check_code_block.type_check_code_block(context, entry.body)