Back to index

wims  3.65+svn20090927
Expression.java
Go to the documentation of this file.
00001 package rene.zirkel.expression;
00002 
00003 import java.util.Enumeration;
00004 
00005 import rene.util.MyVector;
00006 import rene.zirkel.*;
00007 import rene.zirkel.construction.*;
00008 import rene.zirkel.objects.*;
00009 
00010 /*
00011 This file contains classes for computing arithmetic expression. Those
00012 classes might be useful elsewhere. However, variables evaluate to sizes of
00013 construction objects or values of expressions here.
00014 */
00015 
00020 class ExpressionText
00021 {      char A[];
00022        int N;
00023        Construction C;
00024        ConstructionObject O;
00025        DepList DL;
00026        String Var[];
00027        boolean NoCircles;
00028        public ExpressionText (String S, Construction c, ConstructionObject o,
00029               DepList dl, boolean nocircles)
00030        {      A=S.toCharArray();
00031               N=0;
00032               C=c;
00033               O=o;
00034               DL=dl;
00035               NoCircles=nocircles;
00036        }
00037        public void setVar (String t[])
00038        {      Var=t;
00039        }
00040        public boolean isVar (String var)
00041        {      if (Var==null) return false;
00042               for (int i=0; i<Var.length; i++)
00043                      if (Var[i].equals(var)) return true;
00044               return false;
00045        }
00046        public char next (boolean quotes)
00047        {      if (!quotes) skipblanks();
00048               if (N<A.length) return A[N];
00049               else return (char)0;
00050        }
00051        public char next ()
00052        {      return next(false);
00053        }
00054        public char nextnext ()
00055        {      skipblanks();
00056               if (N+1<A.length) return A[N+1];
00057               else return (char)0;
00058        }
00059        public void advance (boolean quotes)
00060        {      if (!quotes) skipblanks();
00061               N++;
00062        }
00063        public void advance ()
00064        {      advance(false);
00065        }
00066        public Construction getConstruction ()
00067        {      return C;
00068        }
00069        public ConstructionObject getObject ()
00070        {      return O;
00071        }
00072        public DepList getDepList ()
00073        {      return DL;
00074        }
00075        public void skipblanks ()
00076        {      while (N<A.length && A[N]==' ') N++;
00077        }
00078        public boolean nocircles ()
00079        {      return NoCircles;
00080        }
00081 }
00082 
00088 class BasicExpression
00089 {      BasicExpression E;
00090 
00091        static final int MINUS=-1,PLUS=1;
00092 
00093        public static BasicExpression scan (ExpressionText t)
00094               throws ConstructionException
00095        {      if (t.next()=='-')
00096               {      t.advance();
00097                      return scan(t,MINUS);
00098               }
00099               if (t.next()=='+')
00100               {      t.advance();
00101                      return scan(t,PLUS);
00102               }
00103               if (t.next()=='(') return new BracketExpression(scanBracket(t));
00104               return ElementaryExpression.scan(t);
00105        }
00106        
00107        public static BasicExpression scan (ExpressionText t,
00108               int sign)
00109               throws ConstructionException
00110        {      if (sign==MINUS)
00111               {      if (t.next()=='(') return new MinusExpression(scanBracket(t));
00112                      return new MinusExpression(ElementaryExpression.scan(t));
00113               }
00114               if (t.next()=='(') return scanBracket(t);
00115               return ElementaryExpression.scan(t);
00116        }
00117        
00118        public static BasicExpression scanBracket (ExpressionText t)
00119               throws ConstructionException
00120        {      t.advance();
00121               BasicExpression E=TopExpression.scan(t);
00122               if (t.next()==')') t.advance();
00123               else
00124                      throw new ConstructionException(Zirkel.name("exception.bracket"));
00125               return E;
00126        }
00127 
00128        public double getValue () throws ConstructionException
00129        {      throw new ConstructionException("");
00130        }
00131        public void translate ()
00132        {
00133        }
00134        
00135        public boolean isNumber ()
00136        {      return false;
00137        }
00138        
00139        public void reset ()
00140        {
00141        }
00142 
00143        public boolean isLogical ()
00144        {      return false;
00145        }
00146 }
00147 
00154 class DoubleExpression extends BasicExpression
00155 {      double X;
00156 
00157        public DoubleExpression (double x)
00158        {      X=x;
00159        }
00160 
00161        public static BasicExpression scan (ExpressionText t)
00162               throws ConstructionException
00163        {      double result=0;
00164               double Faktor=1;
00165               boolean Punkt=false,Digit=false;
00166               boolean Negative=false;
00167               if (t.next()=='+') t.advance();
00168               else if (t.next()=='-')
00169               {      Negative=true;
00170                      t.advance();
00171               }
00172               while (true) 
00173               {      char c=t.next();
00174                      if (c>='0' && c<='9')
00175                      {      result=result*10+(c-'0');
00176                             if (Punkt) Faktor=Faktor/10;
00177                             t.advance();
00178                             Digit=true;
00179                      }
00180                      else if (c=='.')
00181                      {      if (Punkt)
00182                                    throw new ConstructionException(Zirkel.name("exception.dot"));
00183                             Punkt=true;
00184                             t.advance();
00185                      }
00186                      else break;
00187               }
00188               if (!Digit)
00189                      throw new ConstructionException(Zirkel.name("exception.nodigit"));
00190               if (Negative) result=-result;
00191               return new DoubleExpression(Faktor*result);
00192        }
00193        
00194        public double getValue () throws ConstructionException
00195        {      return X;
00196        }
00197 
00198        public String toString ()
00199        {      String s=""+X;
00200               if (s.endsWith(".0")) s=s.substring(0,s.length()-2);
00201               return s;
00202        }
00203        
00204        public void translate ()
00205        {}
00206        
00207        public boolean isNumber ()
00208        {      return true;
00209        }
00210 }
00211 
00217 class FindObjectExpression extends ObjectExpression
00218        implements Translator
00219 {      String Name;
00220        String Var=null;
00221        Construction C;
00222        ConstructionObject O=null; // found object
00223        
00224        public FindObjectExpression (String name, Construction c)
00225        {      super(null);
00226               Name=name;
00227               C=c;
00228        }
00229        
00230        public ConstructionObject getObject ()
00231        {      if (C==null) return null;
00232               if (O!=null && O.getConstruction()==C && O.isInConstruction()
00233                             && O.getName().equals(Name)) return O;
00234               return O=C.find(Name);
00235        }
00236 
00237        public double getValue () throws ConstructionException
00238        {      if (C==null)
00239                      throw new InvalidException("");
00240               if (O!=null && O.getConstruction()==C && O.isInConstruction()
00241                             && O.getName().equals(Name)) return O.getValue();
00242               O=C.find(Name);
00243               if (O==null)
00244                      throw new InvalidException("");
00245               return O.getValue();
00246        }
00247 
00248        public static BasicExpression scan (ExpressionText t, boolean quotes)
00249               throws ConstructionException
00250        {      if (!quotes && t.next()=='\"')
00251               {      t.advance();
00252                      BasicExpression E=scan(t,true);
00253                      if (t.next()!='\"')
00254                             throw new ConstructionException(Zirkel.name("exception.quotes"));
00255                      t.advance();
00256                      return E;
00257               }
00258               StringBuffer b=new StringBuffer();
00259               while (true)
00260               {      char c=t.next(quotes);
00261                      if (!(Character.isLetterOrDigit(c) 
00262                      || c=='\\' 
00263                      || c=='\''
00264                      || (quotes && c!='\"' && c!=0)
00265                      || (quotes && c==' '))) 
00266                             break;
00267                      b.append(c);
00268                      t.advance(quotes);
00269               }
00270               if (!quotes && t.next()=='(')
00271                      return FunctionExpression.scan(t,b.toString());
00272               String s=b.toString();
00273               return new FindObjectExpression(s,t.getConstruction());
00274        }
00275        
00276        public static BasicExpression scan (ExpressionText t)
00277               throws ConstructionException
00278        {      return scan(t,false);
00279        }
00280        
00281        public void translate ()
00282        {      C=C.getTranslation();
00283               C.addTranslator(this);
00284        }
00285        
00286        public String toString ()
00287        {      if (Var!=null) return Var;
00288               return "@"+ObjectExpression.quote(Name);
00289        }
00290        
00294        public void laterTranslate (Construction from)
00295        {      if (C==null) return;
00296               ConstructionObject o=from.find(Name);
00297               if (o==null || o.getTranslation()==null) 
00298               {      from.addError(ConstructionObject.text1(
00299                             Zirkel.name("warning.macrodefinition"),Name));
00300                      return;
00301               }
00302               Name=o.getTranslation().getName();
00303               O=null;
00304        }
00305 }
00306 
00312 class ObjectExpression extends BasicExpression
00313 {      ConstructionObject O;
00314        String Var=null;
00315        public ObjectExpression (ConstructionObject o)
00316        {      O=o;
00317        }
00318 
00319        public double getValue () throws ConstructionException
00320        {      if (!O.valid())
00321                      throw new InvalidException("");
00322               if (Var!=null && 
00323                             (O instanceof FunctionObject)) return ((FunctionObject)O).getValue(Var);
00324               if (Var!=null && 
00325                             (O instanceof UserFunctionObject)) return ((UserFunctionObject)O).getValue(Var);
00326               return O.getValue();
00327        }
00328 
00329        public ConstructionObject getObject ()
00330        {      return O;
00331        }
00332        public static BasicExpression scan (ExpressionText t, boolean quotes)
00333               throws ConstructionException
00334        {      if (!quotes && t.next()=='\"')
00335               {      t.advance();
00336                      BasicExpression E=scan(t,true);
00337                      if (t.next()!='\"')
00338                             throw new ConstructionException(Zirkel.name("exception.quotes"));
00339                      t.advance();
00340                      return E;
00341               }
00342               StringBuffer b=new StringBuffer();
00343               while (true)
00344               {      char c=t.next(quotes);
00345                      if (!(Character.isLetterOrDigit(c) 
00346                      || c=='\\' 
00347                      || c=='\''
00348                      || (quotes && c!='\"' && c!=0)
00349                      || (quotes && c==' '))) 
00350                             break;
00351                      b.append(c);
00352                      t.advance(quotes);
00353               }
00354               if (!quotes && t.next()=='(')
00355                      return FunctionExpression.scan(t,b.toString());
00356               String s=b.toString();
00357               if (s.equals("pi")) return new ConstantExpression("pi",Math.PI);
00358               if (s.equals("valid")) return new ValidExpression(true);
00359               if (s.equals("invalid")) return new ValidExpression(false);
00360               if (s.equals("this"))
00361               {      t.getDepList().add(t.getObject());
00362                      return new ObjectExpression(t.getObject());
00363               }
00364               if (s.equals("windoww")) 
00365                      return new ConstructionExpression(t.getConstruction(),
00366                                    ConstructionExpression.WIDTH);
00367               if (s.equals("windowh")) 
00368                      return new ConstructionExpression(t.getConstruction(),
00369                                    ConstructionExpression.HEIGHT);
00370               if (s.equals("windowcx")) 
00371                      return new ConstructionExpression(t.getConstruction(),
00372                                    ConstructionExpression.CENTERX);
00373               if (s.equals("windowcy")) 
00374                      return new ConstructionExpression(t.getConstruction(),
00375                                    ConstructionExpression.CENTERY);
00376               if (s.equals("pixel")) 
00377                      return new ConstructionExpression(t.getConstruction(),
00378                                    ConstructionExpression.PIXEL);
00379               if (t.isVar(s))
00380               {      ObjectExpression oe=new ObjectExpression(t.getObject());
00381                      oe.Var=s;
00382                      return oe;
00383               }
00384               ConstructionObject o=
00385                      t.getConstruction().findInclusive(s,t.getObject());
00386               if (o==null)
00387               {      o=t.getConstruction().find(s);
00388                      if (o==null)
00389                      {      if (t.getConstruction().loading())
00390                                    return new FindObjectExpression(s,t.getConstruction());
00391                             else
00392                                    throw new ConstructionException(Zirkel.name("exception.notfound")
00393                                                  +" ("+s+")");
00394                      }
00395                      //System.out.println("---");
00396                      //System.out.println(o.getName()+" "+t.getObject().getName());
00397                      //System.out.println(t.getConstruction().dependsOn(o,t.getObject()));
00398                      if (t.getConstruction().dependsOn(o,t.getObject()))
00399                      {      if (t.nocircles())
00400                                    throw new ConstructionException(
00401                                                  ConstructionObject.text1(Zirkel.name("exception.depends"),s));
00402                             return new FindObjectExpression(s,t.getConstruction());
00403                      }
00404                      t.getConstruction().needsOrdering();
00405               }
00406               t.getDepList().add(o);
00407               return new ObjectExpression(o);
00408        }
00409        public static BasicExpression scan (ExpressionText t)
00410               throws ConstructionException
00411        {      if (t.next()=='@')
00412               {      t.advance();
00413                      return FindObjectExpression.scan(t);
00414               }
00415               return scan(t,false);
00416        }
00417        public void translate ()
00418        {      O=O.getTranslation();
00419        }
00420        public String toString ()
00421        {      if (Var!=null) return Var;
00422               return quote(O.getName());
00423        }
00424        static public String quote (String name)
00425        {      boolean quotes=false;
00426               for (int i=0; i<name.length(); i++)
00427               {      if (!Character.isLetterOrDigit(name.charAt(i)))
00428                      {      quotes=true;
00429                             break;
00430                      }
00431               }
00432               if (quotes) return "\""+name+"\"";
00433               else return name;
00434        }
00435 }
00436 
00444 class UserFunctionExpression extends BasicExpression
00445 {      ConstructionObject F;
00446        BasicExpression E[];
00447        double X[];
00448        
00449        public UserFunctionExpression (ConstructionObject f, BasicExpression e[])
00450        {      F=f; 
00451               E=e; 
00452               X=new double[E.length];
00453        }
00454        
00455        public double getValue () throws ConstructionException
00456        {      for (int i=0; i<E.length; i++) X[i]=E[i].getValue();
00457               if (F instanceof FunctionObject) return ((FunctionObject)F).evaluateF(X);
00458               return ((UserFunctionObject)F).evaluateF(X);
00459        }
00460        
00461        public void translate ()
00462        {      for (int i=0; i<E.length; i++) E[i].translate();
00463               if (F instanceof FunctionObject) F=(FunctionObject)F.getTranslation();
00464               else F=(UserFunctionObject)F.getTranslation();
00465        }
00466        
00467        public void reset ()
00468        {      for (int i=0; i<E.length; i++) E[i].reset();
00469        }
00470 
00471        public String toString ()
00472        {      String ex=E[0].toString();
00473               for (int i=1; i<E.length; i++) ex=ex+","+E[i].toString();
00474               return F.getName()+"("+ex+")";
00475        }
00476 }
00477 
00478 class SimulationExpression extends BasicExpression
00479 {      ConstructionObject SO;
00480        ConstructionObject Container,F;
00481        BasicExpression E;
00482        Construction C;
00483        
00484        public SimulationExpression (ConstructionObject so, ConstructionObject c,
00485               BasicExpression e, ConstructionObject f)
00486        {      SO=so; Container=c; E=e; F=f;
00487               C=c.getConstruction();
00488        }
00489        
00490        public double getValue () throws ConstructionException
00491        {      if (C.BlockSimulation)
00492                      throw new ConstructionException(
00493                             Zirkel.name("exception.simmulation.block")); 
00494               try
00495               {      double aa=E.getValue();
00496                      C.BlockSimulation=true;
00497                      ((SimulationObject)SO).setSimulationValue(aa);
00498                      F.getConstruction().validate(F,SO);
00499                      double res=F.getValue();
00500                      ((SimulationObject)SO).resetSimulationValue();
00501                      F.getConstruction().validate(F,SO);
00502                      C.BlockSimulation=false;
00503                      return res;
00504               }
00505               catch (Exception e)
00506               {      C.BlockSimulation=false;
00507                      throw new ConstructionException("");
00508               }
00509        }
00510        
00511        public void translate ()
00512        {      E.translate();
00513               SO=SO.getTranslation(); 
00514               Container=Container.getTranslation();
00515               F=F.getTranslation();
00516        }
00517        
00518        public void reset ()
00519        {      E.reset();
00520        }
00521        
00522        public String toString ()
00523        {      return "simulate("+SO.getName()+","+E.toString()+","+F.getName()+")";
00524        }
00525 }
00526 
00534 class FunctionExpression extends BasicExpression
00535 {      int F;
00536        BasicExpression E[];
00537        int NParams;
00538        
00539        public FunctionExpression (int f, BasicExpression e)
00540        {      F=f; 
00541               E=new BasicExpression[1]; 
00542               E[0]=e; NParams=1;
00543        }
00544        
00545        public FunctionExpression (int f, BasicExpression e, BasicExpression ee)
00546        {      F=f; 
00547               E=new BasicExpression[2]; 
00548               E[0]=e; E[1]=ee; 
00549               NParams=2;
00550        }
00551        
00552        public FunctionExpression (int f, BasicExpression e, BasicExpression ee,
00553               BasicExpression eee)
00554        {      F=f; 
00555               E=new BasicExpression[3]; 
00556               E[0]=e; E[1]=ee; E[2]=eee; 
00557               NParams=3;
00558        }
00559        
00560        final static String Functions[]=
00561               {      "sin","cos","tan","arcsin","arccos","arctan",
00562                      "sqrt","exp","log","round","x","y","floor","ceil",
00563                      "d","a","angle180","angle360","abs","scale","sign","d","sum",
00564                      "if","deg","rad","integrate","zero","diff","min","max","length",
00565                      "rsin","rcos","rtan","rarcsin","rarccos","rarctan",
00566                      "sinhyp","coshyp","z","simulate","inside"
00567               };
00568        final static int NX=10,NY=11,ND=14,NA=15,NS=19,
00569               NSUM=22,NIF=23,NINT=26,NZERO=27,NDIFF=28,NMIN=29,NMAX=30,NLENGTH=31,
00570               NZ=40,NSIM=41,NINSIDE=42;
00571               
00572        public static BasicExpression scan (ExpressionText t, String name)
00573               throws ConstructionException
00574        {      int f=-1;
00575               for (int i=0; i<Functions.length; i++)
00576               {      if (name.equals(Functions[i])) { f=i; break; }
00577               }
00578               if (f<0)
00579               {      boolean forward=false;
00580                      ConstructionObject o=t.getConstruction().find(name,t.getObject());
00581                      if (o==null)
00582                      {      o=t.getConstruction().find(name);
00583                             forward=true;
00584                      }
00585                      if (o!=null && (o instanceof FunctionObject || o instanceof UserFunctionObject) && !(o==t.getObject())
00586                                    && !t.getConstruction().dependsOn(o,t.getObject()))
00587                      {      if (t.next()!='(')
00588                                    throw new ConstructionException(Zirkel.name("exception.parameter"));
00589                             t.advance();
00590                             MyVector ex=new MyVector();
00591                             while (true)
00592                             {      BasicExpression e=TopExpression.scan(t);
00593                                    ex.addElement(e);
00594                                    if (t.next()==')') break;
00595                                    if (t.next()!=',')
00596                                           throw new ConstructionException(Zirkel.name("exception.parameter"));
00597                                    t.advance();
00598                             }
00599                             t.advance();
00600                             t.getDepList().add(o);
00601                             if (forward) t.getConstruction().needsOrdering();
00602                             BasicExpression exp[]=new BasicExpression[ex.size()];
00603                             ex.copyInto(exp);
00604                             return new UserFunctionExpression(o,exp);
00605                      }
00606                      throw new ConstructionException(Zirkel.name("exception.function")
00607                             +" ("+name+")");
00608               }
00609               if (t.next()!='(')
00610                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00611               t.advance();
00612               BasicExpression e=TopExpression.scan(t);
00613               if (f==NX || f==NY || f==NZ)
00614               {      if (e instanceof FindObjectExpression)
00615                             e=new FunctionExpression(f,e);
00616                      else if (e instanceof ObjectExpression &&
00617                             ((ObjectExpression)e).getObject() instanceof PointObject)
00618                             e=new FunctionExpression(f,e);
00619                      else
00620                             throw new ConstructionException(Zirkel.name("exception.parameter")
00621                                    +" ("+Functions[f]+")");           
00622               }
00623               else if (f==ND)
00624               {      if (t.next()!=',')
00625                      {      e=new DExpression(e);
00626                      }
00627                      else
00628                      {      t.advance();
00629                             BasicExpression ee=TopExpression.scan(t);
00630                             if (
00631                                    ((e instanceof ObjectExpression &&
00632                                           ((ObjectExpression)e).getObject() instanceof PointObject)
00633                                    || e instanceof FindObjectExpression)
00634                                     && 
00635                                     ((ee instanceof ObjectExpression &&
00636                                           ((ObjectExpression)ee).getObject() instanceof PointObject)
00637                                    || ee instanceof FindObjectExpression)
00638                                    )
00639                                    e=new FunctionExpression(f,e,ee);
00640                             else
00641                                    throw new ConstructionException(Zirkel.name("exception.parameter")
00642                                           +" ("+Functions[f]+")");
00643                      }
00644               }
00645               else if (f==NA)
00646               {      if (t.next()!=',')
00647                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00648                      t.advance();
00649                      BasicExpression ee=TopExpression.scan(t);
00650                      if (t.next()!=',')
00651                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00652                      t.advance();
00653                      BasicExpression eee=TopExpression.scan(t);
00654                      if (
00655                             ((e instanceof ObjectExpression &&
00656                                    ((ObjectExpression)e).getObject() instanceof PointObject)
00657                             || e instanceof FindObjectExpression)
00658                              && 
00659                              ((ee instanceof ObjectExpression &&
00660                                    ((ObjectExpression)ee).getObject() instanceof PointObject)
00661                             || ee instanceof FindObjectExpression)
00662                              && 
00663                             ((eee instanceof ObjectExpression &&
00664                                    ((ObjectExpression)eee).getObject() instanceof PointObject)
00665                             || eee instanceof FindObjectExpression)
00666                             )
00667                                    e=new FunctionExpression(f,e,ee,eee);
00668                      else
00669                             throw new ConstructionException(Zirkel.name("exception.parameter")
00670                                    +" ("+Functions[f]+")");           
00671                      
00672               }
00673               else if (f==NS)
00674               {      if (t.next()!=',')
00675                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00676                      t.advance();
00677                      BasicExpression ee=TopExpression.scan(t);
00678                      if (t.next()!=',')
00679                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00680                      t.advance();
00681                      BasicExpression eee=TopExpression.scan(t);
00682                      e=new FunctionExpression(f,e,ee,eee);                   
00683               }
00684               else if (f==NSUM)
00685               {      if (t.next()!=',')
00686                      {      e=new CumSumExpression(e);
00687                      }
00688                      else
00689                      {      t.advance();
00690                             BasicExpression ee=TopExpression.scan(t);
00691                             e=new CumSumExpression(e,ee);
00692                      }
00693               }
00694               else if (f==NIF)
00695               {      if (t.next()!=',')
00696                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00697                      t.advance();
00698                      BasicExpression ee=TopExpression.scan(t);
00699                      if (t.next()!=',')
00700                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00701                      t.advance();
00702                      BasicExpression eee=TopExpression.scan(t);
00703                      e=new IfExpression(e,ee,eee);
00704               }
00705               else if (f==NINT || f==NZERO || f==NMIN || f==NMAX || f==NLENGTH)
00706               {      if (!(e instanceof ObjectExpression))
00707                      {      if (f==NMAX || f==NMIN)
00708                             {      if (t.next()!=',')
00709                                           throw new ConstructionException(Zirkel.name("exception.parameter"));
00710                                    t.advance();
00711                                    BasicExpression ee=TopExpression.scan(t);
00712                                    e=new FunctionExpression(f,e,ee);
00713                             }
00714                             else
00715                                    throw new ConstructionException(Zirkel.name("exception.parameter")
00716                                                  +" ("+Functions[f]+")");                         
00717                      }
00718                      else
00719                      {      boolean function=((ObjectExpression)e).getObject() instanceof FunctionObject
00720                                    || ((ObjectExpression)e).getObject() instanceof TrackObject;
00721                             if ((f==NINT || f==NLENGTH) && t.next()==')')
00722                             {      if (!function)
00723                                                  throw new ConstructionException(Zirkel.name("exception.parameter")
00724                                                                +" ("+Functions[f]+")");                         
00725                                    e=new FunctionExpression(f,e);
00726                             }
00727                             else if (f==NLENGTH)
00728                             {      throw new ConstructionException(Zirkel.name("exception.parameter"));
00729                             }
00730                             else
00731                             {      if (t.next()!=',')
00732                                           throw new ConstructionException(Zirkel.name("exception.parameter"));
00733                                    t.advance();
00734                                    BasicExpression ee=TopExpression.scan(t);
00735                                    if (function)
00736                                    {      if (t.next()!=',')
00737                                                  throw new ConstructionException(Zirkel.name("exception.parameter"));
00738                                           t.advance();
00739                                           BasicExpression eee=TopExpression.scan(t);
00740                                           e=new FunctionExpression(f,e,ee,eee);
00741                                    }
00742                                    else if (f==NMIN || f==NMAX)
00743                                    {      e=new FunctionExpression(f,e,ee);
00744                                    }
00745                                    else
00746                                           throw new ConstructionException(Zirkel.name("exception.parameter")
00747                                                         +" ("+Functions[f]+")");                                
00748                             }
00749                      }
00750               }
00751               else if (f==NDIFF)
00752               {      if (!(e instanceof ObjectExpression) ||
00753                             !(((ObjectExpression)e).getObject() instanceof FunctionObject))
00754                                    throw new ConstructionException(Zirkel.name("exception.parameter")
00755                                                  +" ("+Functions[f]+")");
00756                      if (t.next()!=',')
00757                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00758                      t.advance();
00759                      BasicExpression ee=TopExpression.scan(t);
00760                      e=new FunctionExpression(f,e,ee);
00761               }
00762               else if (f==NSIM)
00763               {      if (t.next()!=',')
00764                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00765                      t.advance();
00766                      BasicExpression ee=TopExpression.scan(t);
00767                      if (t.next()!=',')
00768                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00769                      t.advance();
00770                      BasicExpression eee=TopExpression.scan(t);
00771                      if (
00772                             (e instanceof ObjectExpression &&
00773                                    ((ObjectExpression)e).getObject() instanceof SimulationObject)
00774                             ||
00775                             !(eee instanceof ObjectExpression)
00776                             )
00777                      {      ConstructionObject SO=((ObjectExpression)e).getObject();
00778                             if (t.getConstruction().dependsOn(SO,t.getObject()))
00779                                    throw new ConstructionException(Zirkel.name("exception.parameter")
00780                                                  +" ("+Functions[f]+")");           
00781                             e=new SimulationExpression(
00782                                    ((ObjectExpression)e).getObject(),t.getObject(),ee,
00783                                    ((ObjectExpression)eee).getObject());
00784                      }
00785                      else 
00786                             throw new ConstructionException(Zirkel.name("exception.parameter")
00787                                           +" ("+Functions[f]+")");           
00788                      
00789               }
00790               else if (f==NINSIDE)
00791               {      if (t.next()!=',')
00792                             throw new ConstructionException(Zirkel.name("exception.parameter"));
00793                      t.advance();
00794                      BasicExpression ee=TopExpression.scan(t);
00795                      if (
00796                             ((e instanceof ObjectExpression &&
00797                                    ((ObjectExpression)e).getObject() instanceof PointObject)
00798                             || e instanceof FindObjectExpression)
00799                              && 
00800                              ((ee instanceof ObjectExpression &&
00801                                    ((ObjectExpression)ee).getObject() instanceof InsideObject)
00802                             || ee instanceof FindObjectExpression)
00803                             )
00804                             e=new FunctionExpression(f,e,ee);
00805                      else
00806                             throw new ConstructionException(Zirkel.name("exception.parameter")
00807                                    +" ("+Functions[f]+")");
00808               }
00809               else
00810               {      e=new FunctionExpression(f,e);
00811               }
00812               if (t.next()!=')')
00813                      throw new ConstructionException(Zirkel.name("exception.parameter"));
00814               t.advance();
00815               return e;
00816        }
00817 
00818        
00819        public double getValue () throws ConstructionException
00820        {      PointObject P,PP,PPP;
00821               switch (F)
00822               {      case NX : 
00823                             P=getPoint(0);
00824                             if (!P.valid())
00825                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00826                             return ((PointObject)P).getX();
00827                      case NY :
00828                             P=getPoint(0);
00829                             if (!P.valid())
00830                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00831                             return P.getY();
00832                      case NZ :
00833                             P=getPoint(0);
00834                             if (!P.valid())
00835                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00836                             return P.getZ();
00837                      case ND :
00838                             P=getPoint(0); PP=getPoint(1);
00839                             if (!P.valid() || !PP.valid())
00840                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00841                             double dx=P.getX()-PP.getX();
00842                             double dy=P.getY()-PP.getY();
00843                             return Math.sqrt(dx*dx+dy*dy);
00844                      case NA :
00845                             P=getPoint(0); PP=getPoint(1); PPP=getPoint(2);
00846                             if (!P.valid() || !PP.valid() || !PPP.valid())
00847                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00848                             dx=P.getX()-PP.getX();
00849                             dy=P.getY()-PP.getY();
00850                             double dx1=PPP.getX()-PP.getX();
00851                             double dy1=PPP.getY()-PP.getY();
00852                             double a=Math.atan2(dx,dy)-Math.atan2(dx1,dy1);
00853                             a=a/Math.PI*180;
00854                             if (a<0) a+=360;
00855                             if (a>360) a-=360;
00856                             return a;
00857                      case NS :
00858                             double x=E[0].getValue(),xa=E[1].getValue(),xb=E[2].getValue();
00859                             if (x<xa || x>=xb || xb<=xa)
00860                                    throw new InvalidException(Zirkel.name("exception.invalid"));
00861                             return (x-xa)/(xb-xa);
00862                      case NINT :
00863                             if (((ObjectExpression)E[0]).getObject() instanceof FunctionObject)
00864                             {      FunctionObject F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00865                                    if (E.length>1)
00866                                    {      double aa=E[1].getValue(),bb=E[2].getValue();
00867                                           return Romberg.compute(F,aa,bb,10,1e-10,10);
00868                                    }
00869                                    else
00870                                    {      return F.getIntegral();
00871                                    }
00872                             }
00873                             else
00874                             {      TrackObject TO=(TrackObject)(((ObjectExpression)E[0]).getObject());
00875                                    if (E.length>1)
00876                                    {      double aa=E[1].getValue(),bb=E[2].getValue();
00877                                           return TO.getSum(aa,bb);
00878                                    }
00879                                    else return TO.getSum();
00880                             }                                  
00881                      case NLENGTH :
00882                             if (((ObjectExpression)E[0]).getObject() instanceof FunctionObject)
00883                             {      FunctionObject F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00884                                    return F.getLength();
00885                             }
00886                             else
00887                             {      TrackObject TO=(TrackObject)(((ObjectExpression)E[0]).getObject());
00888                                    return TO.getLength();
00889                             }      
00890                      case NZERO :
00891                             FunctionObject F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00892                             double aa=E[1].getValue(),bb=E[2].getValue();
00893                             return Secant.compute(F,aa,bb,1e-10);
00894                      case NDIFF :
00895                             F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00896                             aa=E[1].getValue();
00897                             return 
00898                                    (F.evaluateF(aa+1e-3)-F.evaluateF(aa-1e-3))/2e-3;       
00899                      case NMIN :
00900                             if (NParams==2)
00901                             {      return Math.min(E[0].getValue(),E[1].getValue());
00902                             }
00903                             else
00904                             {      F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00905                                    aa=E[1].getValue(); bb=E[2].getValue();
00906                                    return ConvexMin.computeMin(F,aa,bb,1e-10);
00907                             }
00908                      case NMAX :
00909                             if (NParams==2)
00910                             {      return Math.max(E[0].getValue(),E[1].getValue());
00911                             }
00912                             else
00913                             {      F=(FunctionObject)(((ObjectExpression)E[0]).getObject());
00914                                    aa=E[1].getValue(); bb=E[2].getValue();
00915                                    return ConvexMin.computeMax(F,aa,bb,1e-10);
00916                             }
00917                      case NINSIDE :
00918                             P=getPoint(0);
00919                             InsideObject IO=(InsideObject)(((ObjectExpression)E[1]).getObject());
00920                             return IO.containsInside(P);
00921               }
00922               double x=E[0].getValue();
00923               switch (F)
00924               {      case 0 : return Math.sin(x/180*Math.PI);
00925                      case 1 : return Math.cos(x/180*Math.PI);
00926                      case 2 : return Math.tan(x/180*Math.PI);
00927                      case 3 : return Math.asin(x)/Math.PI*180;
00928                      case 4 : return Math.acos(x)/Math.PI*180;
00929                      case 5 : return Math.atan(x)/Math.PI*180;
00930                      case 6 : return Math.sqrt(x);
00931                      case 7 : return Math.exp(x);
00932                      case 8 : return Math.log(x);
00933                      case 9 : return Math.round(x);
00934                      case 12 : return Math.floor(x);
00935                      case 13 : return Math.ceil(x);
00936                      case 16 :
00937                             x=x/360;
00938                             x-=Math.floor(x);
00939                             x=x*360;
00940                             if (x<180) return x;
00941                             else return (x-360);
00942                      case 17 :
00943                             x/=360;
00944                             x-=Math.floor(x);
00945                             return x*360;
00946                      case 18 :
00947                             return Math.abs(x);
00948                      case 20 :
00949                             if (x>0) return 1;
00950                             else if (x==0) return 0;
00951                             else return -1;
00952                      case 24 : return (x/Math.PI*180);
00953                      case 25 : return (x/180*Math.PI);
00954                      case 32 : return Math.sin(x);
00955                      case 33 : return Math.cos(x);
00956                      case 34 : return Math.tan(x);
00957                      case 35 : return Math.asin(x);
00958                      case 36 : return Math.acos(x);
00959                      case 37 : return Math.atan(x);
00960                      case 38 : return (Math.exp(x)-Math.exp(-x))/2;
00961                      case 39 : return (Math.exp(x)+Math.exp(-x))/2;
00962               }
00963               throw new ConstructionException("");
00964        }
00965        
00966        public PointObject getPoint (int n)
00967               throws ConstructionException
00968        {      PointObject p;
00969               try
00970               {      p=(PointObject)((ObjectExpression)E[n]).getObject();
00971               }
00972               catch (Exception e)
00973               {      throw new ConstructionException("exception.notfound");
00974               }
00975               if (!p.valid()) throw new ConstructionException("exception.invalid");
00976               return p;
00977        }
00978        
00979        public void translate ()
00980        {      for (int i=0; i<NParams; i++)
00981                      E[i].translate();
00982        }
00983        
00984        public void reset ()
00985        {      for (int i=0; i<NParams; i++)
00986                      E[i].reset();
00987        }
00988 
00989        public String toString ()
00990        {      String s=Functions[F]+"(";
00991               for (int i=0; i<NParams; i++)
00992               {      if (i>0) s=s+",";
00993                      s=s+E[i];
00994               }
00995               return s+")";
00996        }
00997 }
00998 
00999 class DExpression extends FunctionExpression
01000 {      double Old=0;
01001        double Old1=0;
01002        boolean start=false;
01003        
01004        public DExpression (BasicExpression e)
01005        {      super(21,e);
01006        }
01007        
01008        public double getValue () throws ConstructionException
01009        {      if (E[0] instanceof ObjectExpression)
01010               {      ConstructionObject o=((ObjectExpression)E[0]).getObject();
01011                      if (o instanceof PointObject)
01012                      {      PointObject p=(PointObject)o;
01013                             if (p.dontUpdate()) return 0;
01014                             double x=p.getX(),y=p.getY();
01015                             if (start)
01016                             {      double res=(x-Old)*(x-Old)+(y-Old1)*(y-Old1);
01017                                    Old=x; Old1=y;
01018                                    return Math.sqrt(res);
01019                             }
01020                             Old=x; Old1=y;
01021                             start=true;
01022                             return 0;
01023                      }
01024                      else if (o instanceof AngleObject)
01025                      {      AngleObject a=(AngleObject)o;
01026                             double x=a.getValue();
01027                             if (start)
01028                             {      double res=x-Old;
01029                                    if (res<-180) res+=180;
01030                                    if (res>180) res-=180;
01031                                    Old=x;
01032                                    return res;
01033                             }
01034                             Old=x;
01035                             start=true;
01036                             return 0;
01037                      }
01038               }
01039               double x=E[0].getValue();
01040               double res;
01041               if (start)
01042               {      res=x-Old;
01043               }
01044               else
01045               {      res=0;
01046                      start=true;
01047               }
01048               Old=x;
01049               return res;
01050        }
01051        
01052        public void reset ()
01053        {      start=false;
01054               super.reset();
01055        }
01056 }
01057 
01058 class CumSumExpression extends FunctionExpression
01059 {      double sum=0;
01060 
01061        public CumSumExpression (BasicExpression e, BasicExpression ee)
01062        {      super(22,e,ee);
01063        }
01064 
01065        public CumSumExpression (BasicExpression e)
01066        {      super(22,e);
01067        }
01068 
01069        public double getValue () throws ConstructionException
01070        {      if (NParams>1) 
01071                      try
01072                      {      double x=E[1].getValue();
01073                             if (x<0)
01074                             {      reset(); return sum;
01075                             }
01076                      }
01077                      catch (Exception e)
01078                      {      sum=0; return sum;
01079                      }
01080               sum+=E[0].getValue();
01081               return sum;
01082        }
01083        
01084        public void reset ()
01085        {      sum=0;
01086               super.reset();
01087        }      
01088 }
01089 
01090 class IfExpression extends FunctionExpression
01091 {      public IfExpression (BasicExpression e, BasicExpression ee,
01092               BasicExpression eee)
01093        {      super(23,e,ee,eee);
01094        }
01095 
01096        public double getValue ()
01097               throws ConstructionException
01098        {      double v=0;
01099               try
01100               {      v=E[0].getValue();
01101               }
01102               catch (NoValueException e)
01103               {      if (e.isValid())
01104                             return E[1].getValue();
01105                      else
01106                             return E[2].getValue();
01107               }
01108               catch (ConstructionException e)
01109               {      return E[2].getValue();
01110               }
01111               if (E[0].isLogical())
01112               {      if (v==0) return E[2].getValue();
01113                      else return E[1].getValue();       
01114               }
01115               return E[1].getValue();
01116        }
01117 }
01118 
01123 class ConstantExpression extends BasicExpression
01124 {      double X;
01125        String S;
01126        public ConstantExpression (String s, double x)
01127        {      X=x; S=s;
01128        }
01129        public double getValue ()
01130               throws ConstructionException
01131        {      return X;
01132        }
01133        public void translate () {}
01134        public String toString ()
01135        {      return S;
01136        }
01137 
01138 }
01139 
01144 class ConstructionExpression extends BasicExpression
01145 {      int Type;
01146        Construction C;
01147        final static int CENTERX=0,CENTERY=1,WIDTH=2,HEIGHT=3,PIXEL=4;
01148        public ConstructionExpression (Construction c, int type)
01149        {      Type=type; C=c;
01150        }
01151        public double getValue ()
01152               throws ConstructionException
01153        {      if (C==null) return 0;
01154               switch (Type)
01155               {      case WIDTH : return C.getW();
01156                      case CENTERX : return C.getX();
01157                      case CENTERY : return C.getY();
01158                      case HEIGHT : return C.getH();
01159                      case PIXEL : return C.getPixel();
01160               }
01161               return 0;
01162        }
01163        public void translate ()
01164        {      C=C.getTranslation();
01165        }
01166        public String toString ()
01167        {      switch (Type)
01168               {      case WIDTH: return "windoww";
01169                      case CENTERX: return "windowcx";
01170                      case CENTERY: return "windowcy";
01171                      case HEIGHT : return "windowh";
01172                      case PIXEL : return "pixel";
01173               }
01174               return "";
01175        }
01176 
01177 }
01178 
01183 class ValidExpression extends BasicExpression
01184 {      boolean V;
01185        public ValidExpression (boolean valid)
01186        {      V=valid;
01187        }
01188        public double getValue ()
01189               throws ConstructionException
01190        {      if (V) return 0;
01191               else throw new ConstructionException("");
01192        }
01193        public void translate () {}
01194        public String toString ()
01195        {      if (V) return "valid";
01196               else return "invalid";
01197        }
01198 
01199 }
01200 
01205 class BracketExpression extends ElementaryExpression
01206 {      BasicExpression E;
01207 
01208        public BracketExpression (BasicExpression e)
01209        {      E=e;
01210        }
01211        
01212        public double getValue ()
01213               throws ConstructionException
01214        {      return E.getValue();
01215        }
01216        
01217        public void translate ()
01218        {      E.translate();
01219        }
01220        
01221        public String toString ()
01222        {      return "("+E.toString()+")";
01223        }
01224        
01225        public boolean isNumber ()
01226        {      return E.isNumber();
01227        }
01228 
01229        public void reset ()
01230        {      E.reset();
01231        }
01232 }
01233 
01234 
01240 abstract class ElementaryExpression extends BasicExpression
01241 {      public static BasicExpression scan (ExpressionText t)
01242               throws ConstructionException
01243        {      try
01244               {      BasicExpression E=DoubleExpression.scan(t);
01245                      return E;
01246               }
01247               catch (Exception e) {}
01248               try
01249               {      BasicExpression E=ObjectExpression.scan(t);
01250                      return E;
01251               }
01252               catch (ConstructionException e) { throw e; }
01253               catch (Exception e) {}
01254               throw new ConstructionException(Zirkel.name("exception.elementary"));
01255        }
01256        abstract public boolean isNumber ();
01257        abstract public double getValue () throws ConstructionException;
01258 }
01259 
01264 class PotenzExpression extends BasicExpression
01265 {      BasicExpression E1,E2;
01266 
01267        public PotenzExpression (BasicExpression e1, BasicExpression e2)
01268        {      E1=e1; E2=e2;
01269        }
01270 
01271        public static BasicExpression scan (ExpressionText t)
01272               throws ConstructionException
01273        {      BasicExpression E1=BasicExpression.scan(t);
01274               if (t.next()=='^' || (t.next()=='*' && t.nextnext()=='*'))
01275               {      if (t.next()=='*') t.advance();
01276                      t.advance();
01277                      return scan(t,E1);
01278               }
01279               return E1;
01280        }
01281        
01282        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01283               throws ConstructionException
01284        {      BasicExpression E1=BasicExpression.scan(t);
01285               if (t.next()=='^' || (t.next()=='*' && t.nextnext()=='*'))
01286               {      if (t.next()=='*') t.advance();
01287                      t.advance();
01288                      return scan(t,new PotenzExpression(E,E1));
01289               }
01290               return new PotenzExpression(E,E1);
01291        }
01292        
01293        public double getValue ()
01294               throws ConstructionException
01295        {      return Math.pow(E1.getValue(),E2.getValue());
01296        }
01297        
01298        public void translate ()
01299        {      E1.translate(); E2.translate();
01300        }
01301        public String toString ()
01302        {      return E1+"^"+E2;
01303        }
01304 
01305        public void reset ()
01306        {      E1.reset();
01307               E2.reset();
01308        }
01309 }
01310 
01315 class MinusExpression extends ElementaryExpression
01316 {      BasicExpression E;
01317 
01318        public MinusExpression (BasicExpression e)
01319        {      E=e;
01320        }
01321        
01322        public double getValue ()
01323               throws ConstructionException
01324        {      return -E.getValue();
01325        }
01326        
01327        public static BasicExpression scan (ExpressionText t)
01328               throws ConstructionException
01329        {      if (t.next()!='-') return PotenzExpression.scan(t);
01330               t.advance();
01331               BasicExpression E1=PotenzExpression.scan(t);
01332               return new MinusExpression(E1);
01333        }
01334        
01335        public void translate ()
01336        {      E.translate();
01337        }
01338        
01339        public String toString ()
01340        {      return "-"+E.toString();
01341        }
01342        
01343        public boolean isNumber ()
01344        {      return E.isNumber();
01345        }
01346 
01347        public void reset ()
01348        {      E.reset();
01349        }
01350 }
01351 
01352 
01357 class QuotientExpression extends BasicExpression
01358 {      BasicExpression E1,E2;
01359 
01360        public QuotientExpression (BasicExpression e1, BasicExpression e2)
01361        {      E1=e1; E2=e2;
01362        }
01363 
01364        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01365               throws ConstructionException
01366        {      BasicExpression E1=MinusExpression.scan(t);
01367               if (t.next()=='/')
01368               {      t.advance();
01369                      return scan(t,new QuotientExpression(E,E1));
01370               }
01371               else if (t.next()=='*' && t.nextnext()!='*')
01372               {      t.advance();
01373                      return ProductExpression.scan(t,new QuotientExpression(E,E1));
01374               }
01375               return new QuotientExpression(E,E1);
01376        }
01377        
01378        public double getValue ()
01379               throws ConstructionException
01380        {      return E1.getValue()/E2.getValue();
01381        }
01382 
01383        public void translate ()
01384        {      E1.translate(); E2.translate();
01385        }
01386        public String toString ()
01387        {      return E1+"/"+E2;
01388        }
01389        public void reset ()
01390        {      E1.reset();
01391               E2.reset();
01392        }
01393 }
01394 
01398 class ProductExpression extends BasicExpression
01399 {      BasicExpression E1,E2;
01400 
01401        public ProductExpression (BasicExpression e1, BasicExpression e2)
01402        {      E1=e1; E2=e2;
01403        }
01404 
01405        public static BasicExpression scan (ExpressionText t)
01406               throws ConstructionException
01407        {      BasicExpression E1=MinusExpression.scan(t);
01408               if (t.next()=='*')
01409               {      t.advance();
01410                      return scan(t,E1);
01411               }
01412               else if (t.next()=='/')
01413               {      t.advance();
01414                      return QuotientExpression.scan(t,E1);
01415               }
01416               return E1;
01417        }
01418        
01419        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01420               throws ConstructionException
01421        {      BasicExpression E1=MinusExpression.scan(t);
01422               if (t.next()=='*' && t.nextnext()!='*')
01423               {      t.advance();
01424                      return scan(t,new ProductExpression(E,E1));
01425               }
01426               else if (t.next()=='/')
01427               {      t.advance();
01428                      return QuotientExpression.scan(t,new ProductExpression(E,E1));
01429               }
01430               return new ProductExpression(E,E1);
01431        }
01432        
01433        public double getValue ()
01434               throws ConstructionException
01435        {      return E1.getValue()*E2.getValue();
01436        }
01437        
01438        public void translate ()
01439        {      E1.translate(); E2.translate();
01440        }
01441        
01442        public String toString ()
01443        {      return E1+"*"+E2;
01444        }
01445        public void reset ()
01446        {      E1.reset();
01447               E2.reset();
01448        }
01449 }
01450 
01455 class DifferenceExpression extends BasicExpression
01456 {      BasicExpression E1,E2;
01457 
01458        public DifferenceExpression (BasicExpression e1, BasicExpression e2)
01459        {      E1=e1; E2=e2;
01460        }
01461 
01462        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01463               throws ConstructionException
01464        {      BasicExpression E1=ProductExpression.scan(t);
01465               if (t.next()=='+')
01466               {      t.advance();
01467                      return SumExpression.scan(t,new DifferenceExpression(E,E1));
01468               }
01469               else if (t.next()=='-')
01470               {      t.advance();
01471                      return scan(t,new DifferenceExpression(E,E1));
01472               }
01473               return new DifferenceExpression(E,E1);
01474        }
01475        
01476        public double getValue ()
01477               throws ConstructionException
01478        {      return E1.getValue()-E2.getValue();
01479        }
01480 
01481        public void translate ()
01482        {      E1.translate(); E2.translate();
01483        }
01484 
01485        public String toString ()
01486        {      return E1+"-"+E2;
01487        }
01488 
01489        public void reset ()
01490        {      E1.reset();
01491               E2.reset();
01492        }
01493 }
01494 
01499 class SumExpression extends BasicExpression
01500 {      BasicExpression E1,E2;
01501 
01502        public SumExpression (BasicExpression e1, BasicExpression e2)
01503        {      E1=e1; E2=e2;
01504        }
01505 
01506        public static BasicExpression scan (ExpressionText t)
01507               throws ConstructionException
01508        {      BasicExpression E1=ProductExpression.scan(t);
01509               if (t.next()=='+')
01510               {      t.advance();
01511                      return scan(t,E1);
01512               }
01513               else if (t.next()=='-')
01514               {      t.advance();
01515                      return DifferenceExpression.scan(t,E1);
01516               }
01517               return E1;
01518        }
01519        
01520        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01521               throws ConstructionException
01522        {      BasicExpression E1=ProductExpression.scan(t);
01523               if (t.next()=='+')
01524               {      t.advance();
01525                      return scan(t,new SumExpression(E,E1));
01526               }
01527               else if (t.next()=='-')
01528               {      t.advance();
01529                      return DifferenceExpression.scan(t,new SumExpression(E,E1));
01530               }
01531               return new SumExpression(E,E1);
01532        }
01533 
01534        public double getValue ()
01535               throws ConstructionException
01536        {      return E1.getValue()+E2.getValue();
01537        }
01538 
01539        public void translate ()
01540        {      E1.translate(); E2.translate();
01541        }
01542 
01543        public String toString ()
01544        {      return E1+"+"+E2;
01545        }
01546 
01547        public void reset ()
01548        {      E1.reset();
01549               E2.reset();
01550        }
01551 }
01552        
01557 class CompareExpression extends BasicExpression
01558 {      BasicExpression E1,E2;
01559        int Operator;
01560        final static int LESS=1,LESSEQUAL=2,GREATER=3,GREATEREQUAL=4,
01561               EQUAL=5,ABOUTEQUAL=6;
01562 
01563        public CompareExpression (BasicExpression e1, BasicExpression e2, int op)
01564        {      E1=e1; E2=e2; Operator=op;
01565        }
01566 
01567        public static BasicExpression scan (ExpressionText t)
01568               throws ConstructionException
01569        {      BasicExpression E1=SumExpression.scan(t);
01570               char c=t.next();
01571               int op=0;
01572               if (c=='<')
01573               {      t.advance();
01574                      if (t.next(true)=='=')
01575                      {      op=LESSEQUAL;
01576                             t.advance();
01577                      }
01578                      else op=LESS;
01579               }
01580               else if (c=='>')
01581               {      t.advance();
01582                      if (t.next(true)=='=')
01583                      {      op=GREATEREQUAL;
01584                             t.advance();
01585                      }
01586                      else op=GREATER;
01587               }
01588               else if (c=='=')
01589               {      t.advance();
01590                      if (t.next(true)=='=') t.advance();
01591                      op=EQUAL;
01592               }
01593               else if (c=='~')
01594               {      t.advance();
01595                      if (t.next(true)=='=') t.advance();
01596                      op=ABOUTEQUAL;
01597               }
01598               else return E1;
01599               BasicExpression E2=SumExpression.scan(t);
01600               return new CompareExpression(E1,E2,op);
01601        }
01602        
01603        public double getValue ()
01604               throws ConstructionException
01605        {      switch (Operator)
01606               {      case LESS :
01607                             return logical(E1.getValue()<E2.getValue());
01608                      case LESSEQUAL :
01609                             return logical(E1.getValue()<=E2.getValue());
01610                      case GREATER :
01611                             return logical(E1.getValue()>E2.getValue());
01612                      case GREATEREQUAL :
01613                             return logical(E1.getValue()>=E2.getValue());
01614                      case EQUAL :
01615                             return logical(E1.getValue()==E2.getValue());
01616                      case ABOUTEQUAL :
01617                             return logical(
01618                                    Math.abs(E1.getValue()-E2.getValue())<1e-10);
01619               }
01620               return 0.0;
01621        }
01622        
01623        public double logical (boolean flag)
01624        {      if (flag) return 1.0;
01625               else return 0.0;
01626        }
01627 
01628        public void translate ()
01629        {      E1.translate(); E2.translate();
01630        }
01631 
01632        public String toString ()
01633        {      switch (Operator)
01634               {      case LESS : return E1+"<"+E2;
01635                      case LESSEQUAL : return E1+"<="+E2;
01636                      case GREATER : return E1+">"+E2;
01637                      case GREATEREQUAL : return E1+">="+E2;
01638                      case EQUAL : return E1+"=="+E2;
01639                      case ABOUTEQUAL : return E1+"~="+E2;
01640               }
01641               return "";
01642        }
01643 
01644        public void reset ()
01645        {      E1.reset(); E2.reset();
01646        }
01647        
01648        public boolean isLogical ()
01649        {      return true;
01650        }
01651 }
01652 
01657 class NotExpression extends BasicExpression
01658 {      BasicExpression E1;
01659 
01660        public NotExpression (BasicExpression e1)
01661        {      E1=e1;
01662        }
01663 
01664        public static BasicExpression scan (ExpressionText t)
01665               throws ConstructionException
01666        {      if (t.next()!='!') return CompareExpression.scan(t);
01667               t.advance();
01668               BasicExpression E1=CompareExpression.scan(t);
01669               return new NotExpression(E1);
01670        }
01671        
01672        public double getValue ()
01673               throws ConstructionException
01674        {      if (E1.getValue()==0.0)
01675                      return 1.0;
01676               else
01677                      return 0.0;
01678        }
01679 
01680        public void translate ()
01681        {      E1.translate();
01682        }
01683 
01684        public String toString ()
01685        {      return "!"+E1;
01686        }
01687 
01688        public void reset ()
01689        {      E1.reset();
01690        }
01691 
01692        public boolean isLogical ()
01693        {      return true;
01694        }
01695 }
01696 
01701 class AndExpression extends BasicExpression
01702 {      BasicExpression E1,E2;
01703 
01704        public AndExpression (BasicExpression e1, BasicExpression e2)
01705        {      E1=e1; E2=e2;
01706        }
01707 
01708        public static BasicExpression scan (ExpressionText t)
01709               throws ConstructionException
01710        {      BasicExpression E1=NotExpression.scan(t);
01711               if (t.next()=='&')
01712               {      t.advance();
01713                      if (t.next(true)=='&') t.advance();
01714                      return scan(t,E1);
01715               }
01716               return E1;
01717        }
01718        
01719        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01720               throws ConstructionException
01721        {      BasicExpression E1=NotExpression.scan(t);
01722               if (t.next()=='&')
01723               {      t.advance();
01724                      return scan(t,new AndExpression(E,E1));
01725               }
01726               return new AndExpression(E,E1);
01727        }
01728        
01729        public double getValue ()
01730               throws ConstructionException
01731        {      if (E1.getValue()!=0.0 && E2.getValue()!=0.0)
01732                      return 1.0;
01733               else
01734                      return 0.0;
01735        }
01736 
01737        public void translate ()
01738        {      E1.translate(); E2.translate();
01739        }
01740 
01741        public String toString ()
01742        {      return E1+"&&"+E2;
01743        }
01744 
01745        public void reset ()
01746        {      E1.reset();
01747               E2.reset();
01748        }
01749 
01750        public boolean isLogical ()
01751        {      return true;
01752        }
01753 }
01754 
01759 class OrExpression extends BasicExpression
01760 {      BasicExpression E1,E2;
01761 
01762        public OrExpression (BasicExpression e1, BasicExpression e2)
01763        {      E1=e1; E2=e2;
01764        }
01765 
01766        public static BasicExpression scan (ExpressionText t)
01767               throws ConstructionException
01768        {      BasicExpression E1=AndExpression.scan(t);
01769               if (t.next()=='|')
01770               {      t.advance();
01771                      if (t.next(true)=='|') t.advance();
01772                      return scan(t,E1);
01773               }
01774               return E1;
01775        }
01776        
01777        public static BasicExpression scan (ExpressionText t, BasicExpression E)
01778               throws ConstructionException
01779        {      BasicExpression E1=AndExpression.scan(t);
01780               if (t.next()=='|')
01781               {      t.advance();
01782                      if (t.next(true)=='|') t.advance();
01783                      return scan(t,new OrExpression(E,E1));
01784               }
01785               return new OrExpression(E,E1);
01786        }
01787        
01788        public double getValue ()
01789               throws ConstructionException
01790        {      if (E1.getValue()!=0.0 || E2.getValue()!=0.0)
01791                      return 1.0;
01792               else
01793                      return 0.0;
01794        }
01795 
01796        public void translate ()
01797        {      E1.translate(); E2.translate();
01798        }
01799 
01800        public String toString ()
01801        {      return E1+"||"+E2;
01802        }
01803 
01804        public void reset ()
01805        {      E1.reset();
01806               E2.reset();
01807        }
01808 
01809        public boolean isLogical ()
01810        {      return true;
01811        }
01812 }
01813 
01814 class TopExpression extends BasicExpression
01815 {      
01816        public static BasicExpression scan (ExpressionText t)
01817               throws ConstructionException
01818        {      return OrExpression.scan(t);
01819        }      
01820 }
01821 
01822 public class Expression
01823 {      String S;
01824        BasicExpression E;
01825        boolean Valid;
01826        String ErrorText;
01827        DepList DL;
01828        double Value;
01829        boolean HasDoubleValue=false;
01830        boolean ForcePlus=false;
01831        
01840        public Expression (String s, Construction c, ConstructionObject o, String var[], 
01841                      boolean nocircles)
01842        {      if (s.startsWith("+"))
01843               {      ForcePlus=true;
01844                      s=s.substring(1);
01845               }
01846               S=s;
01847               DL=new DepList();
01848               try
01849               {      ExpressionText t=new ExpressionText(s,c,o,DL,nocircles);
01850                      t.setVar(var);
01851                      E=TopExpression.scan(t);
01852                      if (t.next()!=0)
01853                             throw new ConstructionException(
01854                                    Zirkel.name("exception.superfluous"));
01855                      Valid=true;
01856               }
01857               catch (Exception e)
01858               {      Valid=false; 
01859                      ErrorText=(e.toString());
01860                      //e.printStackTrace();
01861               }
01862        }
01863        
01864        public Expression (String s, Construction c, ConstructionObject o, String var[])
01865        {      this(s,c,o,var,false);
01866        }
01867        
01868        public Expression (String s, Construction c, ConstructionObject o)
01869        {      this(s,c,o,null,false);
01870        }
01871        
01872        public boolean isValid ()
01873        {      return Valid;
01874        }
01875        public String getErrorText ()
01876        {      return ErrorText;
01877        }
01878        public double getValue () throws ConstructionException
01879        {      if (HasDoubleValue) return Value;
01880               if (!Valid)
01881                      throw new ConstructionException(Zirkel.name("exception.expression"));
01882               double x=E.getValue();
01883               if (Double.isNaN(x) || Double.isInfinite(x))
01884                      throw new ConstructionException(Zirkel.name("exception.value"));
01885               return x;
01886        }
01887 
01888        public void setValue (double x)
01889        {      HasDoubleValue=true;
01890               ForcePlus=false;
01891               DL=new DepList();
01892               Value=x;
01893        }
01894        
01895        public String toString ()
01896        {      if (HasDoubleValue) return ""+Value;
01897               if (Valid) return E.toString();
01898               else return S;
01899        }
01900        
01901        public DepList getDepList ()
01902        {      return DL;
01903        }
01904        
01905        public void translate ()
01906        {      E.translate();
01907               DL.translate();
01908        }
01909        
01910        public boolean isNumber ()
01911        {      return HasDoubleValue || E.isNumber();
01912        }
01913        
01914        public void reset ()
01915        {      if (E!=null && Valid) E.reset();
01916        }
01917 
01918        public boolean isForcePlus () { return ForcePlus; }
01919        public void setForcePlus (boolean flag) { ForcePlus=flag; }
01920 
01921        public ConstructionObject getObject ()
01922        {      if (E instanceof ObjectExpression) return ((ObjectExpression)E).getObject();
01923               else return null;
01924        }
01925 
01930        public void addDep (ConstructionObject o)
01931        {      Enumeration e=getDepList().elements();
01932               while (e.hasMoreElements())
01933               {      ConstructionObject.DL.add((ConstructionObject)e.nextElement());
01934               }
01935        }
01936 }