Пример #1
0
 public static Cons Last(int num,Cons list)
 {
     int len = Length(list);
     if(num > len)
     return null;
     return NthTail(len-num,list);
 }
Пример #2
0
 public static Object MakeList(params Object[] args)
 {
     Cons ret = null;
     for(int i = args.Length-1;i>=0;--i)
     {
     ret = new Cons(args[i],ret);
     }
     return ret;
 }
Пример #3
0
	public static Cons Reverse(Cons list)
		{
		Cons result = null;
		while(list != null)
			{
			result = new Cons(list.first, result);
			list = list.rest;
			}
		return result;
		}
Пример #4
0
 public static int Length(Cons list)
 {
     int len = 0;
     while(list != null)
     {
     len++;
     list = list.rest;
     }
     return len;
 }
Пример #5
0
	internal Closure(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.interpreter = interpreter;
		this.loc = loc;
		ArgSpecs specs = analyzeArgSpec((Cons)args.first,env,loc);
		//create an env expanded by params in which to analyze body
		Env env2 = new Env(specs.parameters, null, env, interpreter);

		this.argSpecs = specs;
		this.body = interpreter.analyze(new Cons(interpreter.BLOCK,args.rest), env2,loc);
		this.env = env;
		}
Пример #6
0
        public static Object concat_d(params Object[] args)
        {
            Cons tail = (Cons)args[args.Length - 1];

            for (int x = args.Length - 2; x >= 0; --x)
            {
                Cons prev = (Cons)args[x];
                if (prev != null)
                {
                    Cons.Last(1, prev).rest = tail;
                    tail = prev;
                }
            }
            return(tail);
        }
Пример #7
0
        public static Object macroexpand_1(params Object[] args)
        {
            Cons   x = (Cons)arg(0, args);
            Symbol s = x.first as Symbol;

            if (s != null && s.isDefined() && s.getGlobalValue() is Macro)
            {
                Macro    m        = (Macro)s.getGlobalValue();
                Object[] argarray = Cons.ToVector(x.rest);
                return(m.Invoke(argarray));
            }
            else
            {
                return(x);
            }
        }
Пример #8
0
        public override String ToString()
        {
            StringBuilder buf = new StringBuilder();

            buf.Append('(');
            buf.Append(first.ToString());
            Cons tail = rest;

            while (tail != null)
            {
                buf.Append(' ');
                buf.Append(tail.first.ToString());
                tail = tail.rest;
            }
            buf.Append(')');
            return(buf.ToString());
        }
Пример #9
0
 internal ApplyExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
 {
     this.loc = loc;
     this.interpreter = interpreter;
     fexpr = interpreter.analyze(args.first,env,loc);
     if(fexpr is IVar)
     {
     fsym = ((IVar)fexpr).getSymbol();
     }
     Int32 len = Cons.Length(args.rest);
     argexprs = new IExpression[len];
     args = args.rest;
     for(Int32 i=0;i<argexprs.Length;i++,args = args.rest)
     {
     argexprs[i] = interpreter.analyze(args.first,env,loc);
     }
 }
Пример #10
0
        internal ApplyExpression(Cons args, Env env, Interpreter interpreter, Loc loc)
        {
            this.loc         = loc;
            this.interpreter = interpreter;
            fexpr            = interpreter.analyze(args.first, env, loc);
            if (fexpr is IVar)
            {
                fsym = ((IVar)fexpr).getSymbol();
            }
            Int32 len = Cons.Length(args.rest);

            argexprs = new IExpression[len];
            args     = args.rest;
            for (Int32 i = 0; i < argexprs.Length; i++, args = args.rest)
            {
                argexprs[i] = interpreter.analyze(args.first, env, loc);
            }
        }
Пример #11
0
        public override String ToString()
        {
            // MEH: Avoid ToString throwing a null reference exception if first is nil.
            StringBuilder buf = new StringBuilder();

            buf.Append('(');
            buf.Append(firstToString());
            Cons tail = rest;

            while (tail != null)
            {
                buf.Append(' ');
                buf.Append(tail.firstToString());
                tail = tail.rest;
            }
            buf.Append(')');
            return(buf.ToString());
        }
Пример #12
0
        public static Object[] ToVector(Cons list)
        {
            int len = Length(list);

            if (len == 0)
            {
                return(Util.EMPTY_VECTOR);
            }
            else
            {
                Object[] result = new Object[len];
                for (int i = 0; list != null; i++, list = list.rest)
                {
                    result[i] = list.first;
                }
                return(result);
            }
        }
Пример #13
0
        internal Object splitSymbol(String s)
        {
            //turn x[y] into ([y] x) - can we with readvector in place?
            //Int32 bridx = s.LastIndexOf("[");


            Int32 dotidx   = s.LastIndexOf(".");
            Int32 colonidx = s.LastIndexOf(":");

            //dot in the middle and not member(dot at start) or type(dot at end)
            if (dotidx >= 0 && dotidx > colonidx && dotidx < (s.Length - 1) && s[0] != '.')
            {
                //turn x.y into (.y x)

                return(Cons.MakeList(interpreter.intern(s.Substring(dotidx)),
                                     splitSymbol(s.Substring(0, dotidx))));
            }
            return(interpreter.intern(s));
        }
Пример #14
0
        internal Object ReadUnquote(params Object[] args)
        {
            LocTextReader t    = (LocTextReader)args[0];
            Int32         line = t.line;
            Int32         ch   = t.Peek();
            Object        ret  = null;

            if (ch == '@')
            {
                t.Read();
                ret = Cons.MakeList(interpreter.UNQUOTE_SPLICING, doRead(t, false));
            }
            else
            {
                ret = Cons.MakeList(interpreter.UNQUOTE, doRead(t, false));
            }
            //record the location
            locTable[ret] = new Loc(t.file, line);
            return(ret);
        }
Пример #15
0
        internal Object map_to_list(params Object[] args)
        {
            Object f = Primitives.arg(0, args);

            IEnumerator[] enums = new IEnumerator[args.Length - 1];
            for (int i = 0; i < enums.Length; i++)
            {
                enums[i] = (IEnumerator)get_enum_gf.Invoke(Primitives.arg(i + 1, args));
            }
            //n.b. setting up arg array which will be reused
            //mean functions cannot assume ownership of args w/o copying them
            Object[] fargs = new Object[enums.Length];
            Cons     ret   = null;
            Cons     tail  = null;

            while (true)
            {
                for (int i = 0; i < enums.Length; i++)
                {
                    if (enums[i].MoveNext())
                    {
                        fargs[i] = enums[i].Current;
                    }
                    else             //bail on shortest
                    {
                        return(ret);
                    }
                }

                Object x    = Util.InvokeObject(f, fargs);
                Cons   node = new Cons(x, null);
                if (ret == null)
                {
                    ret = tail = node;
                }
                else
                {
                    tail = tail.rest = node;
                }
            }
        }
Пример #16
0
        internal DynamicLet(Cons args, Env env, Interpreter interpreter, Loc loc)
        {
            this.loc         = loc;
            this.interpreter = interpreter;
            Cons  bindlist = (Cons)args.first;
            Int32 blen     = Cons.Length(bindlist);

            if ((blen % 2) != 0)        //odd
            {
                throw new Exception("Odd number of args in dynamic-let binding list");
            }
            binds = new BindPair[blen / 2];
            for (int i = 0; i < binds.Length; i++)
            {
                binds[i].dvar = (DynamicVar)interpreter.analyze(bindlist.first, env, loc);
                bindlist      = bindlist.rest;
                binds[i].expr = interpreter.analyze(bindlist.first, env, loc);
                bindlist      = bindlist.rest;
            }
            this.body = interpreter.analyze(new Cons(interpreter.BLOCK, args.rest), env, loc);
        }
Пример #17
0
        internal IfExpression(Cons args, Env env, Interpreter interpreter, Loc loc)
        {
            this.loc         = loc;
            this.interpreter = interpreter;
            Int32 len = Cons.Length(args);

            if (len < 2 || len > 3)
            {
                throw new Exception("Wrong number of args for if");
            }
            test   = interpreter.analyze(args.first, env, loc);
            brtrue = interpreter.analyze(Cons.Second(args), env, loc);
            if (len == 3)
            {
                brfalse = interpreter.analyze(Cons.Third(args), env, loc);
            }
            else
            {
                brfalse = new QuoteExpr(null);
            }
        }
Пример #18
0
 internal Object findKeyParamValue(Parameter p, Cons args)
 {
     for (; args != null; args = args.rest)
     {
         if (args.first == p.key)
         {
             if (args.rest != null)
             {
                 Object ret = Cons.Second(args);
                 if (ret == Missing.Value)
                 {
                     ret = getDefaultParamValue(p);
                 }
                 return(ret);
             }
             else
             {
                 throw   new Exception("Key args must be provided in pairs of [:key value]");
             }
         }
     }
     return(getDefaultParamValue(p));
 }
Пример #19
0
	public static Object First(Cons list)
		{
		return list.first;
		}
Пример #20
0
	public static Cons Append(Cons x, Cons y)
		{
		return(x != null) ? new Cons(x.first, Append(x.rest, y)) : y;
		}
Пример #21
0
	public static Cons NthTail(int n,Cons list)
		{
		while(n > 0)
			{
			n--; 
			list = list.rest;
			}
		return list;
		}             
Пример #22
0
	public Cons(Object first,Cons rest)
		{
		this.first = first;
		this.rest = rest;
		}
Пример #23
0
 public Cons(Object first, Cons rest)
 {
     this.first = first;
     this.rest  = rest;
 }
Пример #24
0
	internal Object findKeyParamValue(Parameter p,Cons args)
		{
		for(;args!=null;args = args.rest)
			{
			if(args.first == p.key)
				{
				if(args.rest != null)
					{
					Object ret = Cons.Second(args);
					if(ret == Missing.Value)
						{
						ret = getDefaultParamValue(p);
						}
					return ret;
					}
				else
					throw	new Exception("Key args must be provided in pairs of [:key value]");
				}
			}
		return getDefaultParamValue(p);
		}
Пример #25
0
	private Boolean equalsFirst(Cons that)
		{
		return(first == null) ? that.first == null :
		first.Equals(that.first);
		}
Пример #26
0
 internal Object ReadVector(params Object[] args)
 {
     LocTextReader t = (LocTextReader)args[0];
     Int32 line = t.line;
     Cons largs = readDelimitedList(t,']');
     Object ret = new Cons(interpreter.VECTOR,largs);
     //record the location
     locTable[ret] = new Loc(t.file,line);
     return ret;
 }
Пример #27
0
 internal CompositeSymbol(Cons symAsList)
 {
     this.symbolAsList = symAsList;
 }
Пример #28
0
        internal Cons readDelimitedList(LocTextReader t,Int32 delim)
        {
            Cons ret = null;
            Cons tail = null;

            Int32 ch = t.Peek();
            while(Char.IsWhiteSpace((Char)ch))
            {
            t.Read();
            ch = t.Peek();
            }
            while(ch != delim)
            {
            Object o = doRead(t,delim == ')' && ret == null);
            if(eof(o))
                {
                throw new Exception("Read error - eof found before matching: "
                                          + (Char)delim + "\n File: " + t.file + ", line: " + t.line);
                }
            EndDelimiter ed = o as EndDelimiter;
            if(ed != null)
                {
                if(ed.delim == delim)
                    {
                    return ret;
                    }
                else
                    throw	new Exception("Read error - read unmatched: " + ed.delim
                                              + "\n File: " + t.file + ", line: " + t.line);
                }
            Cons link = new Cons(o,null);
            if(delim == ')' && ret == null && o is CompositeSymbol)
                {
                ret = ((CompositeSymbol)o).symbolAsList;
                tail = ret.rest;
                }
            else if(ret == null)
                {
                ret = tail = link;
                }
            else
                {
                tail.rest = link;
                tail = link;
                }
            ch = t.Peek();
            while(Char.IsWhiteSpace((Char)ch))
                {
                t.Read();
                ch = t.Peek();
                }
            }

            //eat delim
            t.Read();
            return ret;
        }
Пример #29
0
 internal Macro(Cons args, Env env, Interpreter interpreter, Loc loc)
     : base(args, env, interpreter, loc)
 {
 }
Пример #30
0
 private Boolean equalsFirst(Cons that)
 {
     return((first == null) ? that.first == null :
            first.Equals(that.first));
 }
Пример #31
0
 private Boolean equalsRest(Cons that)
 {
     return((rest == null) ? that.rest == null :
            rest.Equals(that.rest));
 }
Пример #32
0
	public static Object Second(Cons list)
		{
		return list.rest.first;
		}
Пример #33
0
	public static Object Fourth(Cons list)
		{
		return Third(list.rest);
		}
Пример #34
0
        internal IExpression analyze(Object expr, Env env, Loc enclosingLoc)
        {
            Symbol symbol = expr as Symbol;

            if (symbol != null)
            {
                if (symbol.isDynamic)
                {
                    return(new DynamicVar(symbol));
                }
                Object var = env.lookup(symbol);
                if (var is LocalVariable)
                {
                    return(new LocalVar((LocalVariable)var));
                }
                else
                {
                    return(new GlobalVar((Symbol)var));
                }
            }
            if (!(expr is Cons))         //must be literal
            {
                return(new QuoteExpr(expr));
            }

            Cons exprs = (Cons)expr;

            Loc loc = (Loc)reader.locTable[expr];

            if (loc != null)
            {
                reader.locTable.Remove(expr);
            }
            else
            {
                loc = enclosingLoc;
            }

            Object f    = exprs.first;
            Cons   args = exprs.rest;

            //see if it's a macro
            Symbol s = f as Symbol;

            if (s != null && s.isDefined() && s.getGlobalValue() is Macro)
            {
                Macro    m        = (Macro)s.getGlobalValue();
                Object[] argarray = Cons.ToVector(args);
                Object   mexprs   = null;
                try
                {
                    mexprs = m.Invoke(argarray);
                }
                catch (Exception ex)
                {
                    BacktraceFrame frame = new BacktraceFrame(loc, s, args);
                    throw BacktraceException.push(ex, frame, this);
                }
                try
                {
                    return(analyze(mexprs, env, loc));
                }
                catch (Exception ex)
                {
                    BacktraceFrame frame = new BacktraceFrame(loc, "when expanding ", exprs);
                    throw BacktraceException.push(ex, frame, this);
                }
            }
            Int32 numargs = Cons.Length(args);

            if (f == DLET)
            {
                return(new DynamicLet(args, env, this, loc));
            }
            else if (f == FN)
            {
                return(new Closure(args, env, this, loc));
            }
            else if (f == MACRO)
            {
                return(new Macro(args, env, this, loc));
            }
            else if (f == WHILE)
            {
                return(new WhileExpression(args, env, this, loc));
            }
            else if (f == BLOCK)
            {
                if (numargs == 0)
                {
                    return(new QuoteExpr(null));
                }
                //remove block from block of one
                else if (numargs == 1)
                {
                    return(analyze(args.first, env, loc));
                }
                else
                {
                    return(new BlockExpression(args, env, this, loc));
                }
            }
            else if (f == OR)
            {
                if (numargs == 0)
                {
                    return(new QuoteExpr(null));
                }
                else
                {
                    return(new OrExpression(args, env, this, loc));
                }
            }
            else if (f == IF)
            {
                return(new IfExpression(args, env, this, loc));
            }
            else if (f == QUOTE)
            {
                return(new QuoteExpr(args.first));
            }
            else if (f == SET)
            {
                return(new SetExpression(args, env, this, loc));
            }
            else        //presume funcall
            {
                return(new ApplyExpression(exprs, env, this, loc));
            }
        }
Пример #35
0
 public static Object Nth(int n, Cons list)
 {
     return(NthTail(n, list).first);
 }
Пример #36
0
 public static Object Fourth(Cons list)
 {
     return(Third(list.rest));
 }
Пример #37
0
        public object ObjectToLisp(object prim)
        {
            OSD data = OSD.FromObject(prim);
            if (data.Type!=OSDType.Unknown)
                return SerializeLisp(data);
            Type t = prim.GetType();
            foreach (FieldInfo PI in t.GetFields(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public))
            {
                object value = ToLispValue( PI.FieldType, PI.GetValue(prim));
                object kv = new Cons(PI.Name, new Cons(value, null));

            }
            return prim;
        }
Пример #38
0
 public Boolean MoveNext()
 {
     current = next;
     if(current != null)
     next = current.rest;
     return current != null;
 }
Пример #39
0
        //parse out params from spec (which may contain &optional, &key, &rest, initforms etc

        internal ArgSpecs analyzeArgSpec(Cons arglist, Env env, Loc loc)
        {
            //count the params
            int  nParams = 0;
            Cons a       = arglist;

            while (a != null)
            {
                Object p = a.first;
                if (p != interpreter.AMPOPT && p != interpreter.AMPKEY && p != interpreter.AMPREST)
                {
                    ++nParams;
                }
                a = a.rest;
            }

            ArgSpecs ret = new ArgSpecs(env);

            ret.parameters = new Parameter[nParams];
            Parameter.Spec state = Parameter.Spec.REQ;

            int param = 0;

            a = arglist;
            while (a != null)
            {
                Object p = a.first;
                switch (state)
                {
                case Parameter.Spec.REQ:
                    if (p == interpreter.AMPOPT)
                    {
                        state = Parameter.Spec.OPT;
                    }
                    else if (p == interpreter.AMPKEY)
                    {
                        state = Parameter.Spec.KEY;
                    }
                    else if (p == interpreter.AMPREST)
                    {
                        state = Parameter.Spec.REST;
                    }
                    else
                    {
                        if (p is Symbol)
                        {
                            ret.parameters[param++] =
                                new Parameter((Symbol)p, Parameter.Spec.REQ, null);
                            ++ret.numReq;
                        }
                        else if (p is Cons)
                        {
                            ret.parameters[param] =
                                new Parameter((Symbol)((Cons)p).first, Parameter.Spec.REQ, null);
                            ret.parameters[param].typeSpec = interpreter.eval(Cons.Second((Cons)p), env);
                            ++param;
                            ++ret.numReq;
                        }
                    }
                    break;

                case Parameter.Spec.OPT:
                    if (p == interpreter.AMPOPT)
                    {
                        throw new Exception("&optional can appear only once in arg list");
                    }
                    else if (p == interpreter.AMPKEY)
                    {
                        state = Parameter.Spec.KEY;
                    }
                    else if (p == interpreter.AMPREST)
                    {
                        state = Parameter.Spec.REST;
                    }
                    else
                    {
                        if (p is Symbol)
                        {
                            ret.parameters[param++] =
                                new Parameter((Symbol)p, Parameter.Spec.OPT, null);
                            ++ret.numOpt;
                        }
                        else if (p is Cons)
                        {
                            ret.parameters[param++] =
                                new Parameter((Symbol)((Cons)p).first, Parameter.Spec.OPT,
                                              interpreter.analyze(Cons.Second((Cons)p), env, loc));
                            ++ret.numOpt;
                        }
                        else
                        {
                            throw   new Exception("&optional parameters must be symbols or (symbol init-form)");
                        }
                    }
                    break;

                case Parameter.Spec.KEY:
                    if (p == interpreter.AMPOPT)
                    {
                        throw new Exception("&optional must appear before &key in arg list");
                    }
                    else if (p == interpreter.AMPKEY)
                    {
                        throw new Exception("&key can appear only once in arg list");
                    }
                    else if (p == interpreter.AMPREST)
                    {
                        state = Parameter.Spec.REST;
                    }
                    else
                    {
                        if (p is Symbol)
                        {
                            ret.parameters[param] =
                                new Parameter((Symbol)p, Parameter.Spec.KEY, null);
                            ret.parameters[param].key = interpreter.intern(":" + ((Symbol)p).name);
                            ++param;
                            ++ret.numKey;
                        }
                        else if (p is Cons)
                        {
                            ret.parameters[param] =
                                new Parameter((Symbol)((Cons)p).first, Parameter.Spec.KEY,
                                              interpreter.analyze(Cons.Second((Cons)p), env, loc));
                            ret.parameters[param].key =
                                interpreter.intern(":" + ((Symbol)((Cons)p).first).name);
                            ++param;
                            ++ret.numKey;
                        }
                        else
                        {
                            throw   new Exception("&key parameters must be symbols or (symbol init-form)");
                        }
                    }
                    break;

                case Parameter.Spec.REST:
                    if (p == interpreter.AMPOPT)
                    {
                        throw new Exception("&optional must appear before &rest in arg list");
                    }
                    else if (p == interpreter.AMPKEY)
                    {
                        throw new Exception("&key must appear before &rest in arg list");
                    }
                    else if (p == interpreter.AMPREST)
                    {
                        throw new Exception("&rest can appear only once in arg list");
                    }
                    else
                    {
                        if (!(p is Symbol))
                        {
                            throw new Exception("&rest parameter must be a symbol");
                        }
                        else
                        {
                            if (ret.numRest > 0)                            //already got a rest param
                            {
                                throw new Exception("Only one &rest arg can be specified");
                            }
                            ret.parameters[param++] =
                                new Parameter((Symbol)p, Parameter.Spec.REST, null);
                            ++ret.numRest;
                        }
                    }
                    break;
                }

                a = a.rest;
            }

            return(ret);
        }
Пример #40
0
 public void Reset()
 {
     this.current = null;
     this.next = start;
 }
Пример #41
0
	public static Object Nth(int n,Cons list)
		{
		return NthTail(n,list).first;
		}
Пример #42
0
 public static Object Third(Cons list)
 {
     return(Second(list.rest));
 }
Пример #43
0
	public static Object[] ToVector(Cons list)
		{
		int len = Length(list);
		if(len == 0)
			return Util.EMPTY_VECTOR;
		else
			{
			Object[] result = new Object[len];
			for(int i = 0; list!=null; i++, list = list.rest)
				{
				result[i] = list.first;
				}
			return result;
			}
		}
Пример #44
0
 public static Object Second(Cons list)
 {
     return(list.rest.first);
 }
Пример #45
0
	public ConsEnumerator(Cons start)
		{
		this.start = start;
		this.current = null;
		this.next = start;
		}
Пример #46
0
 public static Object Rest(Cons list)
 {
     return(list.rest);
 }
Пример #47
0
	public static Object Rest(Cons list)
		{
		return list.rest;
		}
Пример #48
0
 public static Object First(Cons list)
 {
     return(list.first);
 }
Пример #49
0
	public static Object Third(Cons list)
		{
		return Second(list.rest);
		}
Пример #50
0
        internal Cons readDelimitedList(LocTextReader t, Int32 delim)
        {
            Cons ret  = null;
            Cons tail = null;

            Int32 ch = t.Peek();

            //MEH: Check for EOF too.
            while (ch != -1 && Char.IsWhiteSpace((Char)ch))
            {
                t.Read();
                ch = t.Peek();
            }
            while (ch != delim)
            {
                Object o = doRead(t, delim == ')' && ret == null);
                if (eof(o))
                {
                    throw new Exception("Read error - eof found before matching: "
                                        + (Char)delim + "\n File: " + t.file + ", line: " + t.line);
                }
                EndDelimiter ed = o as EndDelimiter;
                if (ed != null)
                {
                    if (ed.delim == delim)
                    {
                        return(ret);
                    }
                    else
                    {
                        throw   new Exception("Read error - read unmatched: " + ed.delim
                                              + "\n File: " + t.file + ", line: " + t.line);
                    }
                }
                Cons link = new Cons(o, null);
                if (delim == ')' && ret == null && o is CompositeSymbol)
                {
                    ret  = ((CompositeSymbol)o).symbolAsList;
                    tail = ret.rest;
                }
                else if (ret == null)
                {
                    ret = tail = link;
                }
                else
                {
                    tail.rest = link;
                    tail      = link;
                }
                ch = t.Peek();
                //MEH: Check for EOF too.
                while (ch != -1 && Char.IsWhiteSpace((Char)ch))
                {
                    t.Read();
                    ch = t.Peek();
                }
            }

            //eat delim
            t.Read();
            return(ret);
        }
Пример #51
0
 public static Cons Append(Cons x, Cons y)
 {
     return((x != null) ? new Cons(x.first, Append(x.rest, y)) : y);
 }
Пример #52
0
 public ConsEnumerator(Cons start)
 {
     this.start   = start;
     this.current = null;
     this.next    = start;
 }
Пример #53
0
	private Boolean equalsRest(Cons that)
		{
		return(rest == null) ? that.rest == null :
		rest.Equals(that.rest);
		}
Пример #54
0
 internal CompositeSymbol(Cons symAsList)
 {
     this.symbolAsList = symAsList;
 }
Пример #55
0
	//returns an array of evaluated args corresponding to params of argspec,
	//including substitution of default values where none provided, construction of
	//rest list etc
	//suitable for extending the environment prior to evaluating body of closure
	internal Object[] buildParamArray(Object[] code, Int32 offset,
												 Env env//, Boolean evalArgs
												)
		{
		//do nothing if fixed params and matching number
		if(argSpecs.nParams() == argSpecs.numReq  && argSpecs.numReq == code.Length)
			return code;

		Object[] argArray = new Object[nParms()];
		int nargs = code.Length-offset;
		if(nargs < argSpecs.numReq)
			throw new Exception("Too few arguments to procedure, expected at least " + argSpecs.numReq
									  +", but found "+ nargs  +" arguments");

		int i;
		// Fill in the required parameters
		for(i = 0; i < argSpecs.numReq; i++)
			{
			argArray[i] = //evalArgs?Interpreter.execute(code[i+offset], env):
							  code[i+offset];
			}

		//now grab args to satisfy optionals
		if(argSpecs.numOpt > 0)
			{
			for(i = argSpecs.numReq; i < argSpecs.numReq + argSpecs.numOpt; i++)
				{
				if(i<nargs)
					{
					argArray[i] = //evalArgs?Interpreter.execute(code[i+offset], env):
									  code[i+offset];
					//if missing passed to optional, get default
					if(argArray[i] == Missing.Value)
						{
						argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
						}
					}
				else //ran out of args, default the rest
					{
					argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
					}
				}
			}

		//build a rest list
		Cons rest = null;
		for(int x = code.Length-1;x-offset >= i; --x)
			{
			Object val = //evalArgs?Interpreter.execute(code[x], env):
							 code[x];
			rest = new Cons(val, rest);
			}

		//search for key args in rest
		if(argSpecs.numKey > 0)
			{
			for(i = argSpecs.numReq + argSpecs.numOpt; 
				i < argSpecs.numReq + argSpecs.numOpt + argSpecs.numKey; i++)
				{
				argArray[i] = findKeyParamValue(argSpecs.parameters[i],rest);
				}
			}

		// Add the rest parameter (if there is one)
		if(argSpecs.numRest == 1)
			{
			argArray[i] = rest;
			}

		return argArray;
		}
Пример #56
0
        internal Object map_to_list(params Object[] args)
        {
            Object f = Primitives.arg(0,args);
            IEnumerator[] enums = new IEnumerator[args.Length - 1];
            for(int i=0;i<enums.Length;i++)
            {
            enums[i] = (IEnumerator)get_enum_gf.Invoke(Primitives.arg(i+1,args));
            }
            //n.b. setting up arg array which will be reused
            //mean functions cannot assume ownership of args w/o copying them
            Object[] fargs = new Object[enums.Length];
            Cons ret = null;
            Cons tail = null;
            while(true)
            {
            for(int i=0;i<enums.Length;i++)
                {
                if(enums[i].MoveNext())
                    fargs[i] = enums[i].Current;
                else //bail on shortest
                    return ret;
                }

            Object x = Util.InvokeObject(f,fargs);
            Cons node = new Cons(x,null);
            if(ret == null)
                ret = tail = node;
            else
                tail = tail.rest = node;
            }
        }
Пример #57
0
	//parse out params from spec (which may contain &optional, &key, &rest, initforms etc

	internal ArgSpecs analyzeArgSpec(Cons arglist, Env env,Loc loc)
		{
		//count the params
		int nParams = 0;
		Cons a = arglist;
		while(a!=null)
			{
			Object p = a.first;
			if(p!=interpreter.AMPOPT && p!=interpreter.AMPKEY && p!=interpreter.AMPREST)
				++nParams;
			a = a.rest;
			}

		ArgSpecs ret = new ArgSpecs(env);
		ret.parameters = new Parameter[nParams];
		Parameter.Spec state = Parameter.Spec.REQ;

		int param = 0;
		a = arglist;
		while(a!=null)
			{
			Object p = a.first;
			switch(state)
				{
				case Parameter.Spec.REQ:
					if(p==interpreter.AMPOPT)
						state = Parameter.Spec.OPT;
					else if(p==interpreter.AMPKEY)
						state = Parameter.Spec.KEY;
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.REQ,null);
							++ret.numReq;
							}
						else if(p is Cons)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.REQ,null);
							ret.parameters[param].typeSpec = interpreter.eval(Cons.Second((Cons)p),env);
							++param;
							++ret.numReq;
							}
						}
					break;
				case Parameter.Spec.OPT:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional can appear only once in arg list");
					else if(p==interpreter.AMPKEY)
						state = Parameter.Spec.KEY;
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.OPT,null);
							++ret.numOpt;
							}
						else if(p is Cons)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.OPT,
											  interpreter.analyze(Cons.Second((Cons)p),env,loc));
							++ret.numOpt;
							}
						else
							throw	new Exception("&optional parameters must be symbols or (symbol init-form)");
						}
					break;
				case Parameter.Spec.KEY:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional must appear before &key in arg list");
					else if(p==interpreter.AMPKEY)
						throw new Exception("&key can appear only once in arg list");
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)p,Parameter.Spec.KEY,null);
							ret.parameters[param].key = interpreter.intern(":" + ((Symbol)p).name);
							++param;
							++ret.numKey;
							}
						else if(p is Cons)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.KEY,
											  interpreter.analyze(Cons.Second((Cons)p),env,loc));
							ret.parameters[param].key = 
							interpreter.intern(":" + ((Symbol)((Cons)p).first).name);
							++param;
							++ret.numKey;
							}
						else
							throw	new Exception("&key parameters must be symbols or (symbol init-form)");
						}
					break;
				case Parameter.Spec.REST:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional must appear before &rest in arg list");
					else if(p==interpreter.AMPKEY)
						throw new Exception("&key must appear before &rest in arg list");
					else if(p==interpreter.AMPREST)
						throw new Exception("&rest can appear only once in arg list");
					else
						{
						if(!(p is Symbol))
							throw new Exception("&rest parameter must be a symbol");
						else
							{
							if(ret.numRest > 0) //already got a rest param
								throw new Exception("Only one &rest arg can be specified");
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.REST,null);
							++ret.numRest;
							}
						}
					break;
				}

			a = a.rest;
			}

		return ret;
		}
Пример #58
0
        //returns an array of evaluated args corresponding to params of argspec,
        //including substitution of default values where none provided, construction of
        //rest list etc
        //suitable for extending the environment prior to evaluating body of closure
        internal Object[] buildParamArray(Object[] code, Int32 offset,
                                          Env env                                                       //, Boolean evalArgs
                                          )
        {
            //do nothing if fixed params and matching number
            if (argSpecs.nParams() == argSpecs.numReq && argSpecs.numReq == code.Length)
            {
                return(code);
            }

            Object[] argArray = new Object[nParms()];
            int      nargs    = code.Length - offset;

            if (nargs < argSpecs.numReq)
            {
                throw new Exception("Too few arguments to procedure, expected at least " + argSpecs.numReq
                                    + ", but found " + nargs + " arguments");
            }

            int i;

            // Fill in the required parameters
            for (i = 0; i < argSpecs.numReq; i++)
            {
                argArray[i] =         //evalArgs?Interpreter.execute(code[i+offset], env):
                              code[i + offset];
            }

            //now grab args to satisfy optionals
            if (argSpecs.numOpt > 0)
            {
                for (i = argSpecs.numReq; i < argSpecs.numReq + argSpecs.numOpt; i++)
                {
                    if (i < nargs)
                    {
                        argArray[i] =                 //evalArgs?Interpreter.execute(code[i+offset], env):
                                      code[i + offset];
                        //if missing passed to optional, get default
                        if (argArray[i] == Missing.Value)
                        {
                            argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
                        }
                    }
                    else             //ran out of args, default the rest
                    {
                        argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
                    }
                }
            }

            //build a rest list
            Cons rest = null;

            for (int x = code.Length - 1; x - offset >= i; --x)
            {
                Object val =         //evalArgs?Interpreter.execute(code[x], env):
                             code[x];
                rest = new Cons(val, rest);
            }

            //search for key args in rest
            if (argSpecs.numKey > 0)
            {
                for (i = argSpecs.numReq + argSpecs.numOpt;
                     i < argSpecs.numReq + argSpecs.numOpt + argSpecs.numKey; i++)
                {
                    argArray[i] = findKeyParamValue(argSpecs.parameters[i], rest);
                }
            }

            // Add the rest parameter (if there is one)
            if (argSpecs.numRest == 1)
            {
                argArray[i] = rest;
            }

            return(argArray);
        }
Пример #59
0
        public static object SerializeLisp(OSD osd)
        {
            switch (osd.Type)
            {
                case OSDType.Unknown:
                    throw new InvalidCastException();
                case OSDType.Boolean:
                    return osd.AsBoolean();
                case OSDType.Integer:
                    return osd.AsInteger();
                case OSDType.Real:
                    return osd.AsReal();
                case OSDType.String:
                    return osd.AsString();
                case OSDType.Date:
                    return osd.AsDate();
                case OSDType.URI:
                    return osd.AsUri();
                case OSDType.UUID:
                    return osd.AsUUID();

                case OSDType.Binary:
                    return osd.AsBinary();
                case OSDType.Array:
                    OSDArray args = (OSDArray) osd;
                    Cons ret = null;
                    for (int i = args.Count - 1; i >= 0; --i)
                    {
                        ret = new Cons(args[i], ret);
                    }
                    return ret;
                case OSDType.Map:
                    Cons list = null;
                    OSDMap map = (OSDMap) osd;
                    foreach (KeyValuePair<string, OSD> kvp in map)
                    {
                        Cons kv = new Cons(kvp.Key, new Cons(SerializeLisp(kvp.Value)));
                        list = new Cons(kv,list);
                    }
                    return Cons.Reverse(list);
                default:
                    return osd;
            }

        }
Пример #60
0
        public static Object listlength(params Object[] args)
        {
            Cons x = (Cons)arg(0, args);

            return(Cons.Length(x));
        }