00001 package gov.nasa.arc.ase.jpf.expr;
00002
00003 import gov.nasa.arc.ase.jpf.Engine;
00004 import gov.nasa.arc.ase.jpf.JPFErrorException;
00005 import gov.nasa.arc.ase.jpf.jvm.Reference;
00006 import gov.nasa.arc.ase.jpf.jvm.ReferenceWrapper;
00007 import gov.nasa.arc.ase.jpf.jvm.State;
00008 import gov.nasa.arc.ase.util.Debug;
00009 import gov.nasa.arc.ase.util.Lexer;
00010 import gov.nasa.arc.ase.util.FileClassLoader;
00011 import gov.nasa.arc.ase.util.LexerException;
00012 import java.lang.reflect.InvocationTargetException;
00013 import java.lang.reflect.Method;
00014 import java.util.Vector;
00015
00016
00017 class Evaluate implements SubExpr {
00018 private Method method;
00019 private Object[] args = null;
00020
00021 Evaluate(String expr) {
00022 try {
00023 Lexer l = new Lexer(expr);
00024
00025 if(l.lex() != Lexer.ID)
00026 throw new JPFErrorException("Identified expected: " + expr);
00027
00028 StringBuffer sb = new StringBuffer();
00029 sb.append(l.getStringValue());
00030
00031 char token;
00032
00033 while((token = l.lex()) == '.') {
00034 sb.append(token);
00035 if(l.lex() != Lexer.ID)
00036 throw new JPFErrorException("Identified expected: " + expr);
00037 sb.append(l.getStringValue());
00038 }
00039
00040 String name = sb.toString();
00041
00042 Class[] types;
00043
00044
00045 switch(token) {
00046 case Lexer.END:
00047
00048 types = new Class[1];
00049 types[0] = State.class;
00050 break;
00051
00052 case '(':
00053 Vector t = new Vector();
00054 Vector v = new Vector();
00055 t.add(State.class);
00056
00057 token = l.lex();
00058
00059 if(token != ')')
00060 while(true) {
00061 switch(token) {
00062 case Lexer.ID:
00063 sb = new StringBuffer(l.getStringValue());
00064 for(token = l.lex(); token == '.'; token = l.lex()) {
00065 sb.append('.');
00066 if(l.lex() != Lexer.ID)
00067 throw new JPFErrorException("Identified expected: " + expr);
00068
00069 sb.append(l.getStringValue());
00070 }
00071 t.add(Reference.class);
00072 v.add(new ReferenceWrapper(sb.toString()));
00073 break;
00074
00075 case Lexer.INTEGER:
00076 t.add(Integer.TYPE);
00077 v.add(new Integer(l.getIntValue()));
00078 token = l.lex();
00079 break;
00080
00081 case Lexer.STRING:
00082 t.add(String.class);
00083 v.add(l.getStringValue());
00084 token = l.lex();
00085 break;
00086
00087 default:
00088 throw new JPFErrorException("Expression expected: " + expr);
00089 }
00090
00091 if(token == ')')
00092 break;
00093
00094 if(token != ',')
00095 throw new JPFErrorException("',' expected: " + expr);
00096
00097 token = l.lex();
00098 }
00099
00100 if(l.lex() != Lexer.END)
00101 throw new JPFErrorException("Unexpected token: " + expr);
00102
00103 types = new Class[t.size()];
00104 for(int i = 0; i < t.size(); i++)
00105 types[i] = (Class)t.get(i);
00106
00107 args = new Object[v.size()];
00108 for(int i = 0; i < v.size(); i++)
00109 args[i] = v.get(i);
00110
00111 break;
00112
00113 default:
00114 throw new JPFErrorException("'(' expected: " + expr);
00115 }
00116
00117 Class cls;
00118
00119 try {
00120
00121 cls = FileClassLoader.load(name);
00122
00123
00124
00125 } catch(ClassNotFoundException e) {
00126 throw new JPFErrorException("Expression not defined: " + name);
00127 }
00128
00129 try {
00130 method = cls.getDeclaredMethod("evaluate", types);
00131 } catch(NoSuchMethodException e) {
00132 throw new JPFErrorException("No evaluate defined for expression: " + expr);
00133 }
00134
00135 int n = 0;
00136
00137 for(int i = 1; i < types.length; i++)
00138 if(types[i] != Reference.class)
00139 n++;
00140
00141 Class[] otypes = new Class[n];
00142 Object[] oargs = new Object[n];
00143
00144 n = 0;
00145 for(int i = 1; i < types.length; i++)
00146 if(types[i] != Reference.class) {
00147 otypes[n] = types[i];
00148 oargs[n] = args[i-1];
00149 n++;
00150 }
00151
00152 try {
00153 try {
00154 Method o = cls.getDeclaredMethod("observable", otypes);
00155 String os = (String)o.invoke(null, oargs);
00156
00157 Debug.println(Debug.WARNING, "Observable added: " + os);
00158 Engine.getJPF().vm.BuchiObservable(os);
00159 } catch(NoSuchMethodException e) {
00160 try {
00161 otypes = new Class[0];
00162 oargs = new Object[0];
00163
00164 Method o = cls.getDeclaredMethod("observable", otypes);
00165 String os = (String)o.invoke(null, oargs);
00166
00167 Debug.println(Debug.WARNING, "Observable added: " + os);
00168 Engine.getJPF().vm.BuchiObservable(os);
00169 } catch(NoSuchMethodException ee) {
00170 }
00171 }
00172 } catch(IllegalAccessException e) {
00173 throw new JPFErrorException("Observable is not accessible for expression: " + expr);
00174 } catch(InvocationTargetException e) {
00175 throw new JPFErrorException("Observable cannot be evaluate for expression: " + expr);
00176 }
00177 } catch(LexerException e) {
00178 throw new JPFErrorException(e.getMessage());
00179 }
00180 }
00181 public void backtrack() {
00182 throw new RuntimeException("Expression is not executable");
00183 }
00184 public boolean evaluate() {
00185 if(args == null)
00186 return Engine.getJPF().vm.BuchiEvaluate(method);
00187 else
00188 return Engine.getJPF().vm.BuchiEvaluate(method, args);
00189 }
00190 public void execute() {
00191 throw new RuntimeException("Expression is not executable");
00192 }
00193 public String toString() {
00194 if(args == null)
00195 return method.getDeclaringClass().getName();
00196 else {
00197 StringBuffer sb = new StringBuffer();
00198 sb.append(method.getDeclaringClass().getName());
00199 sb.append('(');
00200 for(int i = 0; i < args.length; i++) {
00201 if(i != 0) sb.append(',');
00202 sb.append(args[i]);
00203 }
00204 sb.append(')');
00205
00206 return sb.toString();
00207 }
00208 }
00209 }