// // Eval.java : Lisp 式の評価 // // This is a part of miolisp sourcefile // Copyright (C) 1998 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.lang.reflect.* ; public class Eval { // 評価 public static Object eval(Object s,Environment e) throws Exception { // Atom か? if (s instanceof Atom) return ((Atom)s).eval(e) ; // コンスか? if (s instanceof Cons) return evalcons(s,e) ; // 文字列か? if (s instanceof String) return s ; // 数値か? if (s instanceof Number) return s ; throw new EvalException("eval : <"+s+"> Unknown Object") ; } public static Object evalcons(Object s,Environment e) throws Exception { Object ca = ((Cons)s).car , cd = ((Cons)s).cdr ; if (ca instanceof SAtom) { ca = ((SAtom)ca).eval(e) ; } else if (ca instanceof Cons) { // ((lambda () ... on 1st arg etc.... ca = eval(ca,e) ; } // ---- この段階で ca には Method か Macro しかないはず // Lisp 関数(lambda()) 、マクロ(macro())オブジェクトの処理 if (ca instanceof Macro) { return ((Macro)ca).eval(cd,e) ; } // 新 Java メソッドオブジェクトの処理 if (ca instanceof NativeFunction) { // LispFunction インタフェイス (static method only) // ((native ...) arg1 arg2 ....) with environment // --> Object lispfunc(Environment,(arg1 arg2)) ; Method m = ((NativeFunction)ca).m ; Object[] o = new Object[2] ; o[0] = e ; o[1] = cd ; try { return m.invoke(null,o) ; } catch(InvocationTargetException ex) { throw (Exception)ex.getTargetException() ; } } // Java メソッドオブジェクトの処理 if (ca instanceof Method) { Method m = (Method)ca ; Cons c = Evalutil.mustbecons("JavaMethod :",cd) ; // Java 標準 class (static and instance method) // ((native ...) *dummy* arg1 arg2 ....) static method call // ((native ...) obj arg1 arg2 ....) instance method call // --> ???? obj.javafunc(arg1,arg2) try { Object args = Evalutil.evalall(-1,-1,c.cdr,e) ; return m.invoke(Eval.eval(c.car,e),Evalutil.listtoarg(args)) ; } catch(InvocationTargetException ex) { throw (Exception)ex.getTargetException() ; } } // Java コンストラクタオブジェクトの処理 if (ca instanceof Constructor) { try { Object args = Evalutil.evalall(-1,-1,cd,e) ; return ((Constructor)ca).newInstance(Evalutil.listtoarg(args)) ; } catch(InvocationTargetException ex) { throw (Exception)ex.getTargetException() ; } } // JavaMethod オブジェクトの処理 if (ca instanceof JavaMethod) { Cons c = Evalutil.mustbecons("JavaMethod :",cd) ; return ((JavaMethod)ca).eval(new Cons(Eval.eval(c.car,e),c.cdr),e) ; } // (obj "Method" args.... かどうかをチェック if (cd instanceof Cons) { Cons c = (Cons)cd ; if (c.car instanceof String) { String ss = ca.getClass().getName()+"."+((String)c.car) ; Object o = SAtom.getSAtom(ss).eval(e) ; if (o instanceof JavaMethod) { Cons cc = new Cons(ca,c.cdr) ; return ((JavaMethod)o).eval(cc,e) ; } } } // エラー throw new EvalException("evalcons : <"+ca+"> Unknown Object") ; } }