def apply(self, args: List[Value]) -> Value: if len(args) != 2: raise ArgsNotFit(f'argument mismatch for \'<=\', expected 2, given: {len(args)}') x, y = args[0], args[1] if (isinstance(x, Int) or isinstance(x, Float)) and (isinstance(y, Int) or isinstance(y, Float)): return Bool(x.val <= y.val) raise ArgsNotFit('incorrect argument type for \'<=\', expected number')
def expand_apply_args(args: List[Value]) -> Value: prev, curr = PairValue(None, None), PairValue(None, None) front = prev expect_list: bool = False for i, arg in enumerate(args): if isinstance(arg, PairValue): prev.second = arg while True: if isinstance(arg, PairValue): arg = arg.second elif arg is NULL_PAIR_VALUE: break else: raise ArgsNotFit(f'apply: expected list, got {arg}') expect_list = False if i != len(args) - 1: raise ArgsNotFit(f'apply: expected list, got {arg}') elif arg is NULL_PAIR_VALUE: expect_list = False if i != len(args) - 1: raise ArgsNotFit(f'apply: expected list, got {arg}') else: expect_list = True curr.first = arg prev.second = curr prev = curr curr = PairValue(None, None) if expect_list: raise ArgsNotFit(f'apply: expected list, got {args[-1]}') return front.second
def apply(self, args: List[Value]) -> Value: if len(args) != 1: raise ArgsNotFit(f'cdr: arguments mismatch, expected 1, given: {len(args)}') pairs = args[0] if not isinstance(pairs, Pair): raise ArgsNotFit(f'cdr: expected pair, given: {pairs}') return pairs.second
def apply(self, args: List[Value]) -> Value: val: float is_float: bool = False if len(args) <= 1: raise ArgsNotFit('\'-\' argument unmatch: expected at least 2') elif len(args) > 1: x = args[0] if isinstance(x, Int) or isinstance(x, Float): val = x.val if isinstance(x, Float): is_float = True else: raise ArgsNotFit(f'incorrect argument type for \'-\' : {x}') args = args[1:] for x in args: if isinstance(x, Int): val -= x.val if isinstance(x, Float): val -= x.val is_float = True else: raise ArgsNotFit(f'incorrect argument type for \'-\' : {x}') if not is_float: return Int(int(val)) else: return Float(val)
def apply(self, args: List[Value]) -> Optional[Value]: if len(args) != 1: raise ArgsNotFit('sleep : arguments mismatch, expected 1') x = args[0] if isinstance(x, Int): sleep(x.val * 0.001) else: raise ArgsNotFit('incorrect argument type for sleep')
def apply(self, args: List[Value]) -> Value: if len(args) != 1: raise ArgsNotFit('random: argument mismatch, expected 1') random.seed() x = args[0] if not isinstance(x, Int): raise ArgsNotFit(f'random: expected integer, given: {x}') if x <= 0: raise ArgsNotFit(f'random: expected positive integer, given: {x}') return Int(random.randrange(0, x))
def apply(self, args: List[Value]) -> Value: if len(args) != 2: raise ArgsNotFit( f'argument mismatch for \'%\', expected 2, given: {len(args)}') x, y = args[0], args[1] if isinstance(x, Int) and isinstance(y, Int): if y.val == 0: raise ArgsNotFit('remainder: undefined for 0') return Int(x.val % y.val) raise ArgsNotFit('incorrect argument type for \'%\', expected integer')
def apply(self, args: List[Value]) -> Symbol: if len(args) != 1: raise ArgsNotFit(f'argument mismatch for \`type-of\', expected 1, given: {len(args)}') symbol: str = 'unknown' x = args[0] if isinstance(x, Int): symbol = 'integer' elif isinstance(x, Float): symbol = 'float' elif isinstance(x, Bool): symbol = 'bool' elif isinstance(x, String): symbol = 'string' elif isinstance(x, NULL_PAIR_VALUE): symbol = 'nilpair' elif isinstance(x, Pair): symbol = 'pair' elif isinstance(x, Closure): symbol = 'procedure' elif isinstance(x, PrimFunc): symbol = 'procedure' elif isinstance(x, Symbol): symbol = x.val return Symbol(symbol)
def apply(self, args: List[Value]) -> Value: ret: bool = True for x in args: if isinstance(x, Bool): ret = x.val and ret else: raise ArgsNotFit(f'incorrect argument type for \'and\': {x}, expected bool') return Bool(ret)
def apply(self, args: List[Value]) -> Value: ret: bool = False for x in args: if isinstance(x, Bool): ret = ret or x.val else: raise ArgsNotFit( 'incorrect argument type for \`or\', expected bool') return Bool(ret)
def apply(self, args: List[Value]) -> Value: if len(args) <= 1: raise ArgsNotFit('\'+\' argument unmatch: expected at least 2') val1: int val2: float is_float: bool = False for x in args: if isinstance(x, Int): val1 += x.val elif isinstance(x, Float): is_float = True val2 += x.val else: raise ArgsNotFit(f'incorrect argument type for \'+\': {x}') if not is_float: return Int(val1) else: return Float(val1 + val2)
def bind_arguments(env: Scope, params: Node, args: Value) -> None: if isinstance(params, Name) and args is NULL_PAIR_VALUE: env.put(params.identifier, args) return while True: if params is NULL_PAIR and args is NULL_PAIR_VALUE: return elif params is NULL_PAIR and args is not NULL_PAIR_VALUE: raise ArgsNotFit('too many arguments') elif params is not NULL_PAIR and args is NULL_PAIR_VALUE: raise ArgsNotFit('missing arguments') if isinstance(params, Pair): name: Name = params.first if not isinstance(args, PairValue): raise ArgsNotFit('arguments does not match given number') env.put(name.identifier, args.first) params = params.second elif isinstance(params, Name): env.put(params.identifier, args) return
def eval(self, s: Scope) -> Value: proc: Value = self.proc.eval(s) args: Value = expand_apply_args(eval_list(self.args, s)) if isinstance(proc, Closure): if not isinstance(proc.body, Lambda): raise TypeError(f'unexpected type: {proc.body}') bind_arguments(proc.env, proc.body.params, args) return proc.body.body.eval(proc.env) elif isinstance(proc, PrimFunc): return proc.apply(pairs_to_slice(args)) else: raise ArgsNotFit(f'apply: expected a procedure, got {self.proc}')
def apply(self, args: List[Value]) -> Value: val: float = 1 if len(args) < 1: raise ArgsNotFit('\'/\' argument unmatch: expected at least 1') else: x = args[0] if isinstance(x, Int) or isinstance(x, Float): val = x.val else: raise ArgsNotFit(f'incorrect argument type for \'/\' : {x}') args = args[1:] if len(args) == 0 and val == 0: raise ArgsNotFit('\'/\': division by zero') for x in args: if x == 0: raise ArgsNotFit('\'/\': division by zero') if isinstance(x, Int) or isinstance(x, Float): val /= x.val else: raise ArgsNotFit(f'incorrect argument type for \'/\' : {x}') return Float(val)
def apply(self, args: List[Value]) -> Value: if len(args) != 2: raise ArgsNotFit(f'argument mismatch for \'eqv?\', expected 2, given: {len(args)}') type_of = TypeOf() symbol1, symbol2 = type_of.apply(args[0:1]), type_of.apply(args[1:2]) if symbol1.val != symbol2.val: return Bool(False) is_eqv: Bool = False x, y = args[0], args[1] if isinstance(x, NULL_PAIR_VALUE): return Bool(True) if isinstance(x, Bool) or isinstance(x, Float) or isinstance(x, Int) or isinstance(x, String) or isinstance(x, Symbol): # Make PyCharm happy if isinstance(y, Bool) or isinstance(y, Float) or isinstance(y, Int) or isinstance(y, String) or isinstance(y, Symbol): is_eqv = x.val == y.val return Bool(is_eqv)
def apply(self, args: List[Value]) -> Value: val1: int = 1 val2: float = 1 is_float: bool = False for x in args: if isinstance(x, Int): val1 *= x.val elif isinstance(x, Float): is_float = True val2 *= x.val else: raise ArgsNotFit(f'incorrect argument type for \'*\' : {x}') if not is_float: return Int(val1) else: return Float(val1 * val2)
def apply(self, args: List[Value]) -> Value: if len(args) != 2: raise ArgsNotFit( f'cons: arguments mismatch, expected 2, given: {len(args)}') return Pair(args[0], args[1])
def apply(self, args: List[Value]) -> Optional[Value]: if len(args) != 0: raise ArgsNotFit('newline: argument mismatch, expected 0') print()
def apply(self, args: List[Value]) -> Optional[Value]: if len(args) != 1: raise ArgsNotFit('display: argument mismatch, expected 1') print(args, end='')