Exemplo n.º 1
0
Arquivo: math.py Projeto: bodil/lolisp
 def func(self, scope, args):
   args = args[0]
   for i in xrange(len(args)):
     n = args[i]
     if not types.is_number(n):
       raise LispException("argument %d of %s must be number, was %s" %
                           (i + 1, func.__name__,
                            types.type_name(n)))
   return types.py_to_type(m.reduce_num(reducer,
                                        *(n.value for n in args)))
Exemplo n.º 2
0
  def parse_sig(self, scope, fn, args, signature):
    if signature == "*":
      return args

    out = []
    rest = False
    sigs = signature.split(" ")
    if sigs[-1] in ["&", "@&"]:
      rest = sigs[-1]
      sigs = sigs[:-1]
    else:
      if len(sigs) != len(args):
        raise LispException("%s takes %d arguments, %d given" %
                            (fn, len(sigs), len(args)))
    for sig in sigs:
      if not len(args):
        raise LispException("%s takes %s%d arguments, %d given" %
                            (fn, "at least " if rest else "",
                             len(sigs) + 1, len(out)))
      if "callable" in sig:
        sig = sig.replace("callable", "function|macro|primitive")
      arg = args[0]
      args = args[1:]
      if sig[0] == "@":
        sig = sig[1:]
        arg = self.rt.eval(scope, arg)

      if sig != "any":
        matched = False
        for t in sig.split("|"):
          if t.islower():
            test = getattr(types, "is_%s" % t)
            if test(arg):
              matched = True
          else:
            if match_class([arg.__class__], t):
              matched = True
        if not matched:
          raise LispException("argument %d of %s must be %s, was %s" %
                              (len(out) + 1, fn, sig,
                               types.type_name(arg)))

      out.append(arg)

    if rest and not len(args):
      raise LispException("%s takes %s%d arguments, %d given" %
                          (fn, "at least " if rest else "",
                           len(sigs) + 1, len(out)))
    if rest == "@&":
      out.append(map(lambda x: self.rt.eval(scope, x), args))
    elif rest == "&":
      out.append(args)

    return out
Exemplo n.º 3
0
Arquivo: rt.py Projeto: bodil/lolisp
  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
Exemplo n.º 4
0
  def cond(self, scope, args):
    for i in xrange(len(args)):
      sexp = args[i]
      if not types.is_list(sexp):
        raise LispException("argument %d of cond must be list, is %s" %
                            (i + 1, types.type_name(sexp)))
      if types.is_nil(sexp) or types.is_nil(sexp.cdr):
        raise LispException("argument %d of cond must have a length of >= 2" % (i + 1))
    for rule in args:
      test = self.rt.eval(scope, rule.car)
      if test != types.true and test != types.false:
        raise LispException("expr %s does not evaluate to a boolean" % repr(rule.car))
      if test == types.true:
        for sexp in rule.cdr:
          rv = self.rt.eval(scope, sexp)
        return rv

    return types.nil
Exemplo n.º 5
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)