def xor_(l, r): if l == r == 'Int' or l == r == 'Set': return l else: raise PseudoPythonTypeCheckError( "wrong types for ^: %s and %s" % (serialize_type(l), serialize_type(r)))
def arg_check(expected_type, args, a): if expected_type != args['pseudo_type'] and expected_type != 'Any' and not ( expected_type == 'Number' and (args['pseudo_type'] == 'Int' or args['pseudo_type'] == 'Float')): raise PseudoPythonTypeCheckError('%s expected %s not %s' % (a, serialize_type(expected_type), serialize_type(args['pseudo_type'])))
def or_(l, r): if l == 'Boolean' and r == 'Boolean': return 'Boolean' else: raise PseudoPythonTypeCheckError( "wrong types for or: %s and %s" % (serialize_type(l), serialize_type(r)))
def mod(l, r): if l == 'Int' and r == 'Int': return [l, r, 'Int'] elif l == 'String' and (r == 'String' or r == ['Array', 'String']): return [l, ['Array', 'String'], 'String'] else: raise PseudoPythonTypeCheckError( "wrong types for %: %s and %s" % (serialize_type(l), serialize_type(r)))
def sub(l, r): if l == 'Float' and r in ['Float', 'Int' ] or r == 'Float' and l in ['Float', 'Int']: return [l, r, 'Float'] elif l == 'Int' and r == 'Int': return [l, r, 'Int'] else: raise PseudoPythonTypeCheckError( "wrong types for -: %s and %s" % (serialize_type(l), serialize_type(r)))
def expand(self, args): if len(args) < 2: raise PseudoPythonTypeCheckError('%s expects more args' % self.message) q = builtin_type_check(self.type, self.message, args[1], [args[0]])[-1] return { 'type': 'standard_method_call', 'receiver': args[1], 'args': [args[0]], 'message': self.message, 'pseudo_type': q }
def add(l, r): if l == 'Float' and r in ['Float', 'Int' ] or r == 'Float' and l in ['Float', 'Int']: return [l, r, 'Float'] elif l == 'Int' and r == 'Int': return [l, r, 'Int'] elif l == 'String' and r == 'String': return [l, r, 'String'] elif isinstance(l, list) and l[0] == 'List' and l == r: return [l, r, l] else: raise PseudoPythonTypeCheckError( "wrong types for +: %s and %s" % (serialize_type(l), serialize_type(r)))
def builtin_type_check(namespace, function, receiver, args): fs = TYPED_API[namespace] if fs == 'library': fs = TYPED_API['_%s' % namespace] # print(namespace, function, receiver, args, TYPED_API[namespace]) # input(0) if function not in fs: raise PseudoPythonTypeCheckError('wrong usage of %s' % str(function)) x = fs[function] a = namespace + '#' + function if receiver else namespace + ':' + function if namespace == 'List' or namespace == 'Set' or namespace == 'Array': generics = {'@t': receiver['pseudo_type'][1]} elif namespace == 'Dictionary': generics = { '@k': receiver['pseudo_type'][1], '@v': receiver['pseudo_type'][2] } else: generics = {} s = [] if x[0][0] == '*': e = x[0][1:] for arg in args: s.append(simplify(e, generics)) arg_check(s[-1], arg, a) else: if len(x) - 1 != len(args): raise PseudoPythonTypeCheckError("%s expects %d args not %d" % (a, len(x) - 1, args)) for e, arg in zip(x[:-1], args): s.append(simplify(e, generics)) arg_check(s[-1], arg, a) s.append(simplify(x[-1], generics)) return s
def mul(l, r): if l == 'Float' and r in ['Float', 'Int' ] or r == 'Float' and l in ['Float', 'Int']: return [l, r, 'Float'] elif l == 'Int' and r == 'Int': return [l, r, 'Int'] elif l == 'Int' and (isinstance(r, list) and r[0] == 'List' or r == 'String'): return [l, r, r] elif r == 'Int' and (isinstance(l, list) and l[0] == 'List' or l == 'String'): return [l, r, l] else: raise PseudoPythonTypeCheckError( "wrong types for *: %s and %s" % (serialize_type(l), serialize_type(r)))