package nl.bluering;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Collections;
import java.io.*;
/**
* the rootlib is the central part of the interpreter. It contains the
* variables, and it manages all different extension modules.
*/
public class RootLib extends Interpreter
implements Runnable
{
Calc2 console;
public RootLib(Calc2 c2)
{
installin(this);
new MathLib().installin(this);
new BigIntLib().installin(this);
console=c2;
}
/**
* contains values of the variables in root space.
*/
StackSpace uservar=new StackSpace();
/**
* contains functionpointers to library-defined functions.
*/
//one huge hashtable seems best at this point.
/**
* The list of installed libraries. Uninstalling is hardly provided.
*/
Vector libs=new Vector();
/**
* vector with previous answers
*/
Vector ans=new Vector();
Vector query=new Vector();
/**
* load the library with the given name. This calls for a
* heavy dose of reflection, but seems to be doable in java.
* C implementations might want to recompile themselves to do this,
* just like Linux kernels.
*/
/*
void libload(String s)
{ClassLoader loader = getClass().getClassLoader();
try
{
Object main = loader.loadClass(s).newInstance();
if (main instanceof Interpreter)
{Interpreter itp=(Interpreter)main;
itp.root=this;
itp.mountall();
}
}catch(Exception e)
{e.printStackTrace();
}
}
*/
/**
* add the functionpointer to the system.
*/
static String getclassname(Object obj)
{return obj.getClass().getName();
}
/**
* does the function denoted by the expression.
*/
void userdefdump(ExpWriter w)
{for(Enumeration e=libdef.keys();e.hasMoreElements();)
{
String key=(String)e.nextElement();
functionpointer fp1=(functionpointer)libdef.get(key);
if (fp1.userdefined())
{
w.write(fp1.getdef());
w.write("\n");
}
}
}
void makemanual(File f)
{
int size=libdef.size();
try
{
if(f.exists())
f.delete();
RandomAccessFile raf=new RandomAccessFile(f,"rw");
raf.write(FileLib.s2ba("
WhiteSpace list"));
raf.write(FileLib.s2ba("WhiteSpace list of functions
"));
Vector v=new Vector(size);
for(Enumeration en=libdef.keys();en.hasMoreElements();)
v.addElement(en.nextElement());
//Collections.sort(v);
for(int i=0;i"));
//raf.setLength(raf.getFilePointer());
raf.close();
}catch(Exception e)
{e.printStackTrace();
}
}
/**
* executes the expression
* @param result variable to put the result of the action in
* @param def the definition of the main function of e
* @param e the expression to execute
* @return the variable result. useful for shorter notation.
*/
Variable usercall(Variable result,Expression def,Expression e)
throws Exception
{
Expression leftside=def.get(0);
Expression rightside=def.get(1);
Variable[] arg=new Variable[leftside.getc()];
for(int i=0;i"+topresult.conv2exp());
}catch(Exception e3)
{System.out.println("toprun2myMark:");
e3.printStackTrace();
}
return topresult;
}
/***************************************************************
call toprun if you want the expression calculated with a timeout:
the function is guaranteed to return in a certain time.
*/
/*synchronized*/ void toprun(Expression e)
{
topresult=new Variable("_ans");
topexpression=e;
query.addElement(e);
long start=System.currentTimeMillis();
try
{
Thread T=new Thread(this);
buzy=true;
T.start();
/* do {Thread.sleep(100);System.out.println("going...\n");}
while(buzy&&System.currentTimeMillis()-start"+topresult.getexp());
buzy=false;
console.endquery();
}
/**********************************************************/
/**
* executes/calls/does/calculates an expression
* @param result the variable you want the result in
* @param e the expression to calculate
* @return the variable result. useful for smart notation
*/
Variable run(Variable result,Expression e)
throws Exception
{
if(abort)
return result;
Object o=e.getobject();
// new Exception("hi").printStackTrace();
if (o instanceof String)
{if(e.isbasic())
{
String s=(String)o;
if (s.length()>0&&"1234567890.-".indexOf(s.charAt(0))!=-1)
{
result.set(s);
return result;
}
e.setobject(uservar.getvar((String)o,true));
}
else
{
functionpointer fp=getfp((String)o,e.getc());
if(fp!=null)
e.setobject(fp);
}
}
o=e.getobject();
if (o instanceof Vertical)
{Vertical v=(Vertical)o;
if(!v.canget()) throw new Exception("Vertical "+v.name+" holds no value");
result.set((Variable)v.get());
}
else if (o instanceof functionpointer)
runfp(result,(functionpointer)o,e);
else if (o instanceof Variable)
{result.set((Variable)o);
return result;
}
else run(result,e,ECHO);
return result;
}
/**
* executes an expression
* @param result the variable you want the result in
* @param e the expression to calculate
* @param fp a matching functionpointer (need not be working)
* @return the variable result. useful for smart notation
*/
Variable runfp(Variable result,functionpointer fp,Expression e)
throws Exception
{
if (fp.userdefined())
return usercall(result,fp.userdef,e);
if (fp.isnormal())
{run(result,e.get(0));
Class c1=result.getvalueclass();
if(fp.workson(c1))
return fp.domain.run(result,e,fp.index);
fp=getfp(e.getfunctionstring(),e.getc(),c1);
if(fp!=null)
return fp.domain.run(result,e,fp.index);
}
else//special
{return fp.domain.run(result,e,fp.index);
}
result.set(0);
return result;
}
/*****************************************************/
public final static int LET=1,HELP=2,ANS=3,IF=4,WHILE=5,FOR=6,BLOCK=7,QUOTE=8;
public final static int NEW=9,GOODBYE=10,QUERY=11,GETCLASS=12,MAKEMANUAL=13;
public final static int ECHO=14, AGET=15, FORALL=16, ASET=17,ALENGTH=18,EVAL=19,PRINTLN=20,
NEWARRAY=21;
void mountall()
{mspecial("let",2,LET,"define function");
mspecial("help",1,HELP,"get help on command");
mspecial("ans",1,ANS,"get a previous answer");
mspecial("if",3,IF,"if a0 is true do a1 else do a2");
mspecial("if",2,IF,"if a0 is true do a1");
mspecial("while",2,WHILE,"do a1 until a0 becomes false");
mspecial("codeblock",100,BLOCK,"do these commands");
mspecial("quote",1,QUOTE,"return (do not execute) first argument");
mspecial("new",2,NEW,"create local variable");
mspecial("goodbye",1,GOODBYE,"destroy local variable");
mspecial("makemanual",1,MAKEMANUAL,"make manual file");
mnormal("println",1,PRINTLN,"print a line to the console",stringclass);
}
static Object[] getoa(Variable result)
{
Object o=result.getobject();
if(o instanceof Object[])
return (Object[])o;
return null;
}
// functionpointer undefined=null;
public void setrootlib(RootLib r){};
public Variable run(Variable result,Expression e,int index)
throws Exception
{
Vertical v;
int i;
Expression e2;
Object[] oa,oa2;
Variable v1;
String s;
switch(index)
{case LET:
Expression leftside=e.get(0);
Expression rightside=e.get(1);
if (leftside.isbasic())
setvar(result,leftside,rightside);
else
setfunction(result,leftside,rightside,e);
break;
case HELP:
Expression a1=e.get(0);
functionpointer fp;
if(a1.isbasic())
fp=getfp(a1.toString());
else
fp=getfp(a1.getfunctionstring(),e.getc());
if(fp!=null)
result.set(fp.gethelp());
else
result.set("no help available");
break;
case ANS:
i=run(result,e.get(0)).getint();
if(i<0||i>=ans.size())
result.set(false);
else
result.set((Variable)ans.elementAt(i));
break;
case IF:
boolean b=run(result,e.get(0)).getboolean();
if(b)
run(result,e.get(1));
else if(e.getc()==3)
run(result,e.get(2));
break;
case WHILE:
while(!abort&&run(result,e.get(0)).getboolean())
run(result,e.get(1));
break;
case FOR:
run(result,e.get(0));
while (run(result,e.get(1)).getboolean())
{
run(result,e.get(3));
run(result,e.get(2));
}
break;
case QUOTE:
result.set(e.get(0).Eclone());
break;
case NEW:
if (!e.get(0).isbasic())
{
result.set(0);
break;
}
v=uservar.getvertical(e.get(0).getfunctionstring(),true);
v.newlocal(run(new Variable(v.name),e.get(1)));
result.set(1);
break;
case GOODBYE:
v=uservar.getvertical(e.get(0).getfunctionstring(),false);
if (v==null||!v.canget())
result.set(false);
else
result.set(v.goodbye());
break;
case QUERY:
i=run(result,e.get(0)).getint();
if(i<0||i>=query.size())
result.set(false);
else
result.set((Expression)query.elementAt(i));
break;
case GETCLASS:
result.set(run(result,e.get(0)).getobject().getClass().getName());
break;
case MAKEMANUAL:
fmakemanual(result,e);
break;
case ECHO:
e2=new Expression(e.getfunctionstring(),e.getc());
for(i=0;i