Beispiel #1
0
def cond(args: typing.List[wtypes.Expression],
         env: wisp.env.Environment) -> wtypes.Expression:
    """Return the expression associated with the first test to return true."""
    for arg in args:
        if not isinstance(arg, wtypes.List):
            raise exceptions.WispException('invalid cond form: %s' % args)
        elif len(arg.items) != 2:
            raise exceptions.WispException('invalid cond form: %s' % args)

        body, test = arg.items
        if (test == wtypes.Symbol('else') or
                test.eval(env) == wtypes.Bool(True)):
            return body.eval(env)
    else:
        return wtypes.Symbol('unspecified return value')
Beispiel #2
0
 def wrapper(args: typing.List[wtypes.Expression],
             env: wisp.env.Environment) -> wtypes.Expression:
     if len(args) != n:
         raise exceptions.WispException(
             'called with %d arguments, requires %d' % (len(args), n)
         )
     else:
         return func(args, env)
Beispiel #3
0
    def __getitem__(self, key: wtypes.Symbol) -> wtypes.Expression:
        """Search each frame in the environment for the symbol.

        Raises an exception if the symbol can not be found in any frame.
        """
        for frame in (self.local_scope(), self.global_scope()):
            if key.name in frame:
                return frame[key.name]
        else:
            raise exceptions.WispException('No binding for %s' % key)
Beispiel #4
0
    def __setitem__(self, key: wtypes.Symbol, val: wtypes.Expression):
        """Set a symbol's value in whichever frame it is first bound.

        Raises an exception if the symbol is not yet bound.
        """
        for frame in (self.local_scope(), self.global_scope()):
            if key.name in frame:
                frame[key.name] = val
                break
        else:
            raise exceptions.WispException('No binding for %s' % key)
Beispiel #5
0
def w_lambda(args: typing.List[wtypes.Expression],
             env: wisp.env.Environment) -> wtypes.Function:
    """Create a lambda given an argument list and a body."""
    arg_def, body = args
    if isinstance(arg_def, wtypes.List):
        if all(isinstance(arg, wtypes.Symbol) for arg in arg_def.items):
            if isinstance(body, wtypes.List):
                # mypy isn't smart enough to understand the
                # all(isinstance()) call above.
                return make_lamba(arg_def.items, body, env)  # type: ignore
    raise exceptions.WispException('invalid lambda %s %s' % (arg_def, body))
Beispiel #6
0
def __list_op(op: typing.Callable[[wtypes.List], T],
              args: typing.List[wtypes.Expression]) -> T:
    """Ensure args is a non-empty List and return the call of op on it."""
    val = args[0]
    if isinstance(val, wtypes.List):
        if val.items:
            return op(val)
        else:
            raise exceptions.WispException(
                'can not apply cdr to an empty list'
            )
    else:
        raise exceptions.type_error(wtypes.List, val)
Beispiel #7
0
    def __wrap_operator(self,
                        other: Expression,
                        op_name: str,
                        op: typing.Callable[[int, int], int]) -> Expression:
        """Call the given operator between self and other.

        Calls the given operator between the underlying integers boxed by self
        and other. Wraps the resulting value back in the Integer class.
        Raises an exception if other not an Integer.
        """
        if not isinstance(other, self.__class__):
            raise exceptions.WispException('Can not %s %s' % (op_name, other))
        else:
            return self.__class__(op(self.val, other.val))
Beispiel #8
0
    def eval(self, env: wisp.env.Environment) -> Expression:
        """Evaluate a list as a postfix function call.

        Treat the last item in the list as a symbol pointing to a function.
        Treat other members of the list as arguments to the function.
        An empty list evaluates to an empty list.
        """
        if not self.items:
            return self

        fn = self.items[-1].eval(env)
        if not isinstance(fn, (Function, SpecialForm)):
            raise exceptions.WispException(
                '%s is not applicable' % self.items[-1]
            )

        args = list(reversed(self.items[:-1]))
        return fn.call(args, env)
Beispiel #9
0
 def __floordiv__(self, other: 'Expression') -> 'Expression':
     raise exceptions.WispException('Can not divide %s' % self)
Beispiel #10
0
 def __mul__(self, other: 'Expression') -> 'Expression':
     raise exceptions.WispException('Can not multiply %s' % self)
Beispiel #11
0
 def __sub__(self, other: 'Expression') -> 'Expression':
     raise exceptions.WispException('Can not subtract %s' % self)
Beispiel #12
0
 def __add__(self, other: 'Expression') -> 'Expression':
     raise exceptions.WispException('Can not add %s' % self)