Beispiel #1
0
  def macro(self, scope, args):
    sig = list(args[0])
    body = types.mklist(args[1])

    for arg in sig:
      if not types.is_symbol(arg):
        raise LispException("argument 1 of lambda must be a list of symbols, found %s" % types.type_name(arg))

    return types.mkmacro(sig, body, scope)
Beispiel #2
0
  def invoke(self, scope, func, args, tailrec = False):
    args = list(args)

    if types.is_primitive(func):
      return func.invoke(scope, args)

    try:
      rest = list((i.value for i in func.sig)).index("&")
    except ValueError:
      rest = -1
      if len(args) != len(func.sig):
        raise LispException("%s takes %d arguments, %d given" %
                            (types.type_name(func),
                             len(func.sig), len(args)))
    else:
      if len(args) < rest:
        raise LispException("%s takes at least %d arguments, %d given" %
                            (types.type_name(func), rest, len(args)))

    closure = scope if tailrec else Scope(func, func.scope)
    for i in xrange(len(args)):
      if func.sig[i].value == "&":
        closure.define(func.sig[rest+1].value,
                       types.mklist(args[rest:]))
        rest = -1
        break
      else:
        closure.define(func.sig[i].value, args[i])
    if rest >= 0:
      closure.define(func.sig[rest+1].value, types.nil)

    rv = types.nil
    for sexp in func.value:
      rv = self.execute(closure, sexp)

    return rv