// // Evalutil.java : S 式評価ルーチン作成補助 クラス // // 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.io.* ; import java.util.* ; import java.lang.reflect.* ; public class Evalutil { // (native ...) メソッド検索のため、クラス名を Object[] に展開 // (native ...) メソッドを呼び出すために引数を Object[] に展開 するのに使用 public static Vector listtovector(Object o) throws EvalException { Vector v = new Vector() ; Object mark = o ; while (o != SAtom.nil){ if (o instanceof Cons) { Cons c = (Cons)o ; v.addElement(c.car) ; o = c.cdr ; if (mark == o) break ; // 循環リスト? } else { throw new EvalException("Arg is not a valid list") ; } } return v ; } public static Object[] listtoarg(Object o) throws EvalException { Vector v = listtovector(o) ; Object[] res = new Object[v.size()] ; v.copyInto(res) ; return res ; } // 引数が 1 つの場合のチェックと引数の切り出し public static Object getarg1(String msg,Object o) throws EvalException{ if (!(o instanceof Cons)) { throw new EvalException(msg+" Argument must be supplied") ; } if (((Cons)o).cdr != SAtom.nil) { throw new EvalException(msg+" needs just one argument ") ; } return ((Cons)o).car ; } // Cons かどうかのチェックとキャスト public static Cons mustbecons(String msg,Object o) throws EvalException{ if (!(o instanceof Cons)) { throw new EvalException(msg+" Argument must be Cons") ; } return (Cons)o ; } // SAtom かどうかのチェックとキャスト public static SAtom mustbesatom(String msg,Object o) throws EvalException{ if (!(o instanceof SAtom)) { throw new EvalException(msg+" Argument must be SymbolAtom") ; } return (SAtom)o ; } // リストに現れる要素を順に評価したリストを作成して返す public static Object evalall(int minargs,int maxargs,Object a,Environment e) throws Exception { int argcount = 0 ; Object result = SAtom.nil ; Vector v = new Vector() ; // 引数を数えつつ、一旦ベクタにコピー while(a != SAtom.nil) { Cons c = mustbecons("evalall :",a) ; ++argcount ; if ((maxargs != -1) && (argcount > maxargs)) { throw new EvalException("evalall : Too much argument (At most "+maxargs+")") ; } v.addElement(c.car) ; a = c.cdr ; } if ((minargs != -1) && (argcount < minargs)) { throw new EvalException("evalall : Too few argument (At least "+minargs+" needs)") ; } // 評価を行いつつ、戻り値になるリストを接続する if (argcount > 0) { Enumeration en = v.elements() ; Cons last,next ; last = new Cons(Eval.eval(en.nextElement(),e),SAtom.nil) ; result = last ; while(en.hasMoreElements()) { next = new Cons(Eval.eval(en.nextElement(),e),SAtom.nil) ; last.cdr = next ; last = next ; } } else { result = SAtom.nil ; // とりあえずごまかし^^; } return result ; } // リストに現れる要素を順に評価し、最後の評価値を返す public static Object evprogn(Object ol,Environment env) throws Exception { Object res = SAtom.nil ,mark = ol ; while (ol != SAtom.nil){ if (ol instanceof Cons) { Cons c = (Cons)ol ; res = Eval.eval(c.car,env) ; // 評価 ol = c.cdr ; if (mark == ol) break ; // 循環リスト? } else { throw new EvalException("Eval : Arg is not a valid list") ; } } return res ; } // リストの引数が minargs 以上、maxargs 以下であるかどうかチェックする。 public static void argchk(int minargs,int maxargs,Object a) throws Exception { int argcount = 0 ; // 引数をカウントするのみ while(a != SAtom.nil) { Cons c = mustbecons("argchk :",a) ; ++argcount ; if ((maxargs != -1) && (argcount > maxargs)) { throw new EvalException("evalall : Too much argument (At most "+maxargs+")") ; } a = c.cdr ; } if ((minargs != -1) && (argcount < minargs)) { throw new EvalException("argchk : Too few argument (At least "+minargs+" needs)") ; } } // 文字列を S 式として読み込み、評価する public static Object Evalstring(String s,Environment e) throws Exception { Sreader sr = new Sreader(new StringReader(s)) ; return Eval.eval(sr.read(),e) ; } }