// // Primitive.java : プリミティブ操作 (起動時にロードされる基本関数群) // // This is a part of miolisp sourcefile // Copyright (C) 1998,99 Nishiyama, Naoki / Mio software lab. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // import java.util.* ; import java.io.* ; public final class Primitive implements LispFunction { // Cons public static Object Cons(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object a,d ; a = i.getNextObjEval("cons",e) ; d = i.getFinalObjEval("cons",e) ; return new Cons(a,d) ; } // List public static Object List(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; return i.getRestEval("list",e) ; } // Append (Recursive) private static Object _append(Object a,Object d) throws EvalException { if (a == SAtom.nil) return d ; Cons c = Evalutil.mustbecons("append :",a) ; return new Cons(c.car,_append(c.cdr,d)) ; } public static Object Append(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object a,d ; a = i.getNextObjEval("append",e) ; d = i.getFinalObjEval("append",e) ; return _append(a,d) ; } // Quote public static Object Quote(Environment e,Object o) throws EvalException{ return Evalutil.getarg1("quote :",o) ; } // Backquote private static Object _backquote(Environment e,Object o) throws Exception { if (o instanceof Cons) { Object ca = ((Cons)o).car , cd = ((Cons)o).cdr ; if (cd instanceof Cons) { Object ca2 = ((Cons)cd).car ; if (ca2 instanceof Cons) { if (((Cons)ca2).car == SAtom.commaat) { Cons c = Evalutil.mustbecons("backquote-atmark :",((Cons)ca2).cdr) ; return new Cons(_backquote(e,ca),Eval.eval(c.car,e)) ; } } } if (ca == SAtom.comma) { Cons c = Evalutil.mustbecons("backquote-comma :",cd) ; return Eval.eval(c.car,e) ; } return new Cons(_backquote(e,ca),_backquote(e,cd)) ; } return o ; } public static Object Backquote(Environment e,Object o) throws Exception{ return _backquote(e,Evalutil.getarg1("backquote :",o)) ; } // Lambda public static Object Lambda(Environment e,Object o) throws Exception { Cons c = Evalutil.mustbecons("lambda :",o) ; return new Lambda(e,c.car,c.cdr) ; } // Macro public static Object Macro(Environment e,Object o) throws Exception { Cons c = Evalutil.mustbecons("macro :",o) ; return new Macro(e,c.car,c.cdr) ; } // Car public static Object Car(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("car :",o),e) ; if (o == SAtom.nil) return SAtom.nil ; return Evalutil.mustbecons("car :",o).car ; } // Cdr public static Object Cdr(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("cdr :",o),e) ; if (o == SAtom.nil) return SAtom.nil ; return Evalutil.mustbecons("cdr :",o).cdr ; } // Null? public static Object Null(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("null :",o),e) ; return (o == SAtom.nil ? SAtom.t : SAtom.nil ) ; } // Atom? public static Object Atom(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("atom :",o),e) ; return (o instanceof Atom ? SAtom.t : SAtom.nil ) ; } // Setq (Special Form) public static Object Setq(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; SAtom a = i.getNextSAtom("setq") ; Object d = i.getFinalObjEval("setq",e) ; e.bind(a,d) ; return d ; } // Define (Special Form) public static Object Define(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; SAtom a = i.getNextSAtom("define") ; Object d = i.getFinalObjEval("define",e) ; a.setGlobal(d) ; return a ; } // Envaslist (現在の環境の snapshot をリストにして返す) public static Object Envaslist(Environment e,Object o) throws Exception { return new Cons(e.toalist(), new Cons(SAtom.getGlobalDic(),SAtom.nil)) ; } // Env (現在の環境の Environment オブジェクトを返す) public static Object Env(Environment e,Object o) throws Exception { return e ; } // If public static Object If(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object co = i.getNextObjEval("if",e) ; Object th = i.getNextObj("if") ; // 第1引数の評価結果をみる if (co != SAtom.nil) { return Eval.eval(th,e) ; } return Evalutil.evprogn(i.getRest(),e) ; } // Eq public static Object Eq(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object a,d ; a = i.getNextObjEval("eq",e) ; d = i.getFinalObjEval("eq",e) ; return (a == d ? SAtom.t : SAtom.nil) ; } // Load public static Object Load(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("car :",o),e) ; if (!(o instanceof String)) { throw new EvalException("load : filename must be String") ; } return Sloader.load(e,(String)o) ; } // Print public static Object Print(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; i.doeach("print",new ListIter.cb(e) { // Anonymous class (super is ListIter.cb) public boolean repeat(Object r) throws Exception { System.out.print(Sexpr.toStr(Eval.eval(r,env))+" ") ; return true ; } }) ; System.out.println() ; return SAtom.t ; } // Cond public static Object Cond(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; return i.doeach("cond",new ListIter.cb(e) { // Anonymous class (super is ListIter.cb) public boolean repeat(Object r) throws Exception { Cons c = Evalutil.mustbecons("cond :",r) ; Object co = Eval.eval(c.car,env) ; // 条件式 if (co != SAtom.nil) { // 成立時 if (c.cdr != SAtom.nil) { result = Evalutil.evprogn(c.cdr,env) ; } else { // 成立時の実行文のないときは、条件式の値を戻す。 result = co ; } return false ; // 評価を打ち切る } return true ; } }) ; } // Reverse public static Object Reverse(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("reverse :",o),e) ; if (o == SAtom.nil) return o ; // (reverse '()) ListIter i = new ListIter(Evalutil.mustbecons("reverse :",o)) ; return i.doeach("reverse",new ListIter.cb(e) { // Anonymous class (super is ListIter.cb) public boolean repeat(Object r) throws Exception { result = new Cons(r,result) ; return true ; // continue repeat } }) ; } // Equal private static boolean _equal(Object x,Object y) { if (x == y) return true ; if (x instanceof Atom) { if (y instanceof Atom) { return ((Atom)x).eq((Atom)y) ; } } else if (x instanceof Cons) { if (y instanceof Cons) { if (_equal(((Cons)x).car,((Cons)y).car)) { return _equal(((Cons)x).cdr,((Cons)y).cdr) ; } } } else if (x instanceof String) { if (y instanceof String) { return ((String)x).equals((String)y) ; } } return false ; } public static Object Equal(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object a,d ; a = i.getNextObjEval("equal",e) ; d = i.getFinalObjEval("equal",e) ; return (_equal(a,d) ? SAtom.t : SAtom.nil) ; } // Rplaca public static Object Rplaca(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Cons c = i.getNextConsEval("rplaca",e) ; Object d = i.getFinalObjEval("rplaca",e) ; c.car = d ; return c ; } // Rplacd public static Object Rplacd(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Cons c = i.getNextConsEval("rplacd",e) ; Object d = i.getFinalObjEval("rplacd",e) ; c.cdr = d ; return c ; } // Progn public static Object Progn(Environment e,Object o) throws Exception { return Evalutil.evprogn(o,e) ; } // Prog1 public static Object Prog1(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object res = i.getNextObjEval("prog1",e) ; Evalutil.evprogn(i.getRest(),e) ; return res ; } // Mapcar public static Object Mapcar(Environment e,Object o) throws Exception { ListIter i = new ListIter(o) ; Object f = i.getNextObjEval("mapcar",e) ; Object a = i.getFinalObjEval("mapcar",e) ; ListIter j = new ListIter(a) ; // apply,funcall の代わり^^; Cons template = new Cons(f,new Cons( new Cons(SAtom.quote,new Cons()),SAtom.nil)) ; return j.doeach("mapcar",new ListIter.cb(e,template) { // Anonymous class (super is ListIter.cb) Cons last = null,place = null ; public boolean repeat(Object r) throws Exception { if (place == null) { place = (Cons)((Cons)((Cons)((Cons)arg).cdr).car).cdr ; } place.car = r ; Cons n = new Cons(Eval.eval(arg,env),SAtom.nil) ; if (last == null) { // 第 1 要素か? result = n ; } else { last.cdr = n ; } last = n ; return true ; } }) ; } // Quit (System Exit) public static Object Quit(Environment e,Object o) throws Exception { if (o != SAtom.nil) { o = Eval.eval(Evalutil.getarg1("car :",o),e) ; if (o instanceof Number) { System.exit(((Number)o).intValue()) ; } } System.exit(0) ; // not come here return null ; } // FuncBody public static Object funcbody(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("funcdef :",o),e) ; if (!(o instanceof Macro)) { throw new EvalException("funcdef : argument must be Macro or Lambda") ; } return ((Macro)o).body ; } // Eval public static Object Eval(Environment e,Object o) throws Exception { o = Eval.eval(Evalutil.getarg1("(Primitive)eval :",o),e) ; return Eval.eval(o,e) ; } // Spawn - Eval expression under another thread public static Object Spawn(Environment e,Object o) throws Exception { MLThread mlt = new MLThread(e,Evalutil.getarg1("spawn :",o)) ; Thread t = new Thread(mlt) ; t.start() ; return mlt ; } }