def generate_code(self, arg_types: List[uni.InferenceType], code_builder: OpCodeBuilder): empty_label = code_builder.fresh_label() assert len( arg_types ) == 1, f'len function needs 1 argument, {len(arg_types)} where given' t = arg_types[0] assert isinstance(t, uni.InferenceList), f'Error during code generation of {self.name}: ' \ f'expects argument of type list, but type {t} was given' arg = gen_utils.Local(-1) code_builder.add(codes.LdLoc(arg)) code_builder.add(codes.BrFalse(empty_label)) if isinstance(t.t, uni.InferenceTypeVar): code_builder.add_print_str('Error: type var list has contents') code_builder.add(codes.Halt()) code_builder.add(codes.LdLoc(arg)) code_builder.add(codes.LdFld(FieldType.Tl)) code_builder.add_call(self.name, [t]) code_builder.add(codes.PushConst(1)) code_builder.add(codes.Add()) code_builder.add(codes.Ret()) code_builder.mark(empty_label) code_builder.add(codes.PushConst(0)) code_builder.add(codes.Ret())
def generate_code(self, arg_types: List[uni.InferenceType], code_builder: OpCodeBuilder): assert len(arg_types) == 2, \ f'Error during code generation of \'{self.name}\': ' \ f'expected {self.num_args} arguments but found {len(arg_types)}' t1, t2 = arg_types[0], arg_types[1] assert t1.is_equal(t2) or \ (isinstance(t1, uni.InferenceList) and isinstance(t1.t, uni.InferenceTypeVar) and isinstance(t2, uni.InferenceList) and isinstance(t2.t, uni.InferenceTypeVar)), \ f'Error during code generation: {self.name} expects both arguments to be of the same type' assert not isinstance(t1, uni.InferenceVoid), \ f'Error during code generation: could not generate {self.name} code for type {t1}' arg1 = gen_utils.Local(-2) arg2 = gen_utils.Local(-1) if isinstance(t1, uni.InferenceInt) or isinstance( t1, uni.InferenceChar): code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.Add()) code_builder.add(codes.Ret()) elif isinstance(t1, uni.InferenceList): null_label_1 = code_builder.fresh_label() null_label_2 = code_builder.fresh_label() code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.BrFalse(null_label_1)) code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Hd)) code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Tl)) code_builder.add(codes.LdLoc(arg2)) code_builder.add_call(self.name, [t1, t1], hide=True) code_builder.add(codes.CreateListCons()) code_builder.add(codes.Ret()) code_builder.mark(null_label_1) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.BrFalse(null_label_2)) if isinstance(t2.t, uni.InferenceTypeVar): code_builder.add_print_str('Error: type var list has contents') code_builder.add(codes.Halt()) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Hd)) code_builder.add(codes.PushConst(0)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Tl)) code_builder.add_call(self.name, [t1, t1], hide=True) code_builder.add(codes.CreateListCons()) code_builder.add(codes.Ret()) code_builder.mark(null_label_2) code_builder.add(codes.CreateListNil()) code_builder.add(codes.Ret()) elif isinstance(t1, uni.InferenceBool) or isinstance( t1, uni.InferenceTuple): raise NoFunctionInstanceError(self.name, arg_types)
def generate_code(self, arg_types: List[uni.InferenceType], code_builder: OpCodeBuilder): assert len( arg_types ) == 1, f'len function needs 1 argument, {len(arg_types)} where given' t = arg_types[0] assert isinstance(t, uni.InferenceList), f'Error during code generation of {self.name}: ' \ f'expects argument of type list, but type {t} was given' arg = gen_utils.Local(-1) code_builder.add(codes.LdLoc(arg)) code_builder.add(codes.PushConst(0)) code_builder.add(codes.Eq()) code_builder.add(codes.Ret())
def generate_code(self, code_builder: OpCodeBuilder): if self.expression is None: code_builder.add(codes.RetNoValue()) else: self.expression.generate_code(code_builder) code_builder.add(codes.Ret())
def generate_code(self, arg_types: List[uni.InferenceType], code_builder: OpCodeBuilder): code_builder.add(codes.LdLoc(gen_utils.Local(-1))) code_builder.add(codes.LdLoc(gen_utils.Local(-2))) code_builder.add(codes.Eq()) code_builder.add(codes.Ret())
def generate_code(self, arg_types: List[uni.InferenceType], code_builder: OpCodeBuilder): assert len(arg_types) == 2, \ f'Error during code generation of \'{self.name}\': ' \ f'expected {self.num_args} arguments but found {len(arg_types)}' t1 = arg_types[0] t2 = arg_types[1] assert t1.is_equal(t2) or \ (isinstance(t1, uni.InferenceList) and isinstance(t1.t, uni.InferenceTypeVar) and isinstance(t2, uni.InferenceList) and isinstance(t2.t, uni.InferenceTypeVar)), \ f'Error during code generation: {self.name} expects both arguments to be of the same type' assert not isinstance(t1, uni.InferenceVoid), \ f'Error during code generation: could not generate {self.name} code for type {t1}' arg1 = gen_utils.Local(-1) arg2 = gen_utils.Local(-2) if isinstance(t1, uni.InferenceInt) or isinstance(t1, uni.InferenceBool) or isinstance(t1, uni.InferenceChar): code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.Eq()) code_builder.add(codes.Ret()) elif isinstance(t1, uni.InferenceList): null_label = code_builder.fresh_label() false_label = code_builder.fresh_label() code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.BrFalse(null_label)) if isinstance(t1.t, uni.InferenceTypeVar): code_builder.add_print_str('Error: type var list has contents') code_builder.add(codes.Halt()) else: code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Hd)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Hd)) code_builder.add_call(self.name, [t1.t, t1.t]) code_builder.add(codes.BrFalse(false_label)) code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Tl)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Tl)) tail = uni.InferenceList(t1.t) code_builder.add_call(self.name, [tail, tail]) code_builder.add(codes.Ret()) code_builder.mark(null_label) code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.Eq()) code_builder.add(codes.Ret()) code_builder.mark(false_label) code_builder.add(codes.PushConst(0)) code_builder.add(codes.Ret()) elif isinstance(t1, uni.InferenceTuple): false_label = code_builder.fresh_label() code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Fst)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Fst)) code_builder.add_call(self.name, [t1.t1, t1.t1]) code_builder.add(codes.BrFalse(false_label)) code_builder.add(codes.LdLoc(arg1)) code_builder.add(codes.LdFld(FieldType.Snd)) code_builder.add(codes.LdLoc(arg2)) code_builder.add(codes.LdFld(FieldType.Snd)) code_builder.add_call(self.name, [t1.t2, t1.t2]) code_builder.add(codes.Ret()) code_builder.mark(false_label) code_builder.add(codes.PushConst(0)) code_builder.add(codes.Ret())