Exemple #1
0
 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')
Exemple #2
0
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
Exemple #3
0
 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
Exemple #4
0
 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)
Exemple #5
0
 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')
Exemple #6
0
 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))
Exemple #7
0
 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')
Exemple #8
0
    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)
Exemple #9
0
 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)
Exemple #10
0
 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)
Exemple #11
0
 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)
Exemple #12
0
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
Exemple #13
0
 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}')
Exemple #14
0
 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)
Exemple #15
0
 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)
Exemple #16
0
 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)
Exemple #17
0
 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])
Exemple #18
0
 def apply(self, args: List[Value]) -> Optional[Value]:
     if len(args) != 0:
         raise ArgsNotFit('newline: argument mismatch, expected 0')
     print()
Exemple #19
0
 def apply(self, args: List[Value]) -> Optional[Value]:
     if len(args) != 1:
         raise ArgsNotFit('display: argument mismatch, expected 1')
     print(args, end='')