created mirror

This commit is contained in:
whatever
2026-09-14 20:19:29 -04:00
commit 6764738d92
600 changed files with 87187 additions and 0 deletions

View File

@@ -0,0 +1,256 @@
/*
Actions.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
/** Primitive actions for the Zaubertrank applitude.
*/
public class Actions {
public static final String rcsid = "$Id: Actions.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
static ZZCell getDim(ZZCell any, String id) {
return getDim(any.getSpace(), id);
}
static ZZCell getDim(ZZSpace sp, String id) {
ZZCell c = ZZDefaultSpace.findOnSystemlist(sp, "DimLists", false);
c = c.s("d.1");
if(c.t().equals(id)) return c;
ZZCell res = c.findText("d.2", 1, id);
if(res == null) { res = c.N("d.2", -1); res.setText(id); }
return res;
}
static void setDims(ZZCell win, String[] id) {
ZZSpace sp = win.getSpace();
ZZCell[] cells = new ZZCell[id.length];
for(int i=0; i<id.length; i++)
cells[i] = getDim(sp, id[i]);
ZZDefaultSpace.setDims(win, cells);
}
static ZZCell grammarCurs(ZZSpace sp) {
ZZCell c = ZZDefaultSpace.findOnSystemlist(sp, "Zaubertrank", true);
c = c.getOrNewCell("d.1");
return c;
}
static void setGrammarNode(ZZCell win) {
ZZCell curs = grammarCurs(win.getSpace());
ZZCursorReal.set(curs, ZZCursorReal.get(win));
}
static void gotoGrammarNode(ZZCell win) {
ZZCell c = grammarCurs(win.getSpace());
c = ZZCursorReal.get(c);
if(c == null) {
pa("org.zaubertrank.Actions.gotoGrammarNode failed: ");
pa("--- no grammar node set");
} else {
ZZCursorReal.set(win, c);
}
}
static ZZCell typeCurs(ZZSpace sp) {
ZZCell c = ZZDefaultSpace.findOnSystemlist(sp, "Zaubertrank", true);
c = c.getOrNewCell("d.1");
c = c.getOrNewCell("d.2");
return c;
}
static void setTypeNode(ZZCell win) {
ZZCell curs = typeCurs(win.getSpace());
ZZCursorReal.set(curs, ZZCursorReal.get(win));
}
static void gotoTypeNode(ZZCell win) {
ZZCell c = typeCurs(win.getSpace());
c = ZZCursorReal.get(c);
if(c == null) {
pa("org.zaubertrank.Actions.gotoTypeNode failed: ");
pa("--- no type node set");
} else {
ZZCursorReal.set(win, c);
}
}
static public void viewGrammarNodes(ZZCell win) {
gotoGrammarNode(win);
setDims(win, new String[] {
Parser.grammardim,
Parser.textgrammardim,
Parser.textrankdim
});
}
static public void viewTexts(ZZCell win) {
setDims(win, new String[] {
Parser.textdim,
Parser.textrankdim,
Parser.textgrammardim
});
}
static public void viewTypeNode(ZZCell win) {
setDims(win, new String[] {
Parser.textdim,
Parser.decdim,
Parser.paramdim
});
}
static public void viewDecNode(ZZCell win) {
setDims(win, new String[] {
Parser.valuedim,
Parser.paramdim,
Parser.decdim
});
}
static public void viewExpNode(ZZCell win) {
setDims(win, new String[] {
Parser.valuedim,
Parser.paramdim,
Parser.sequencedim
});
}
static public void viewSequence(ZZCell win) {
setDims(win, new String[] {
Parser.paramdim,
Parser.sequencedim,
Parser.valuedim
});
}
static public void stdView(ZZCell win) {
ZZCell home = win.getSpace().getHomeCell();
ZZCell defDims = ZZDefaultSpace.findDefaultDimlist(home);
ZZDefaultSpace.setDimsFromList(win, defDims, true);
}
static public void mkGrammarNode(ZZCell win) {
Parser.GrammarNode gn = new Parser.GrammarNode(win.getSpace());
ZZCursorReal.set(grammarCurs(win.getSpace()), gn.c);
viewGrammarNodes(win);
}
static public void mkText(ZZCell win) {
ZZCell c = ZZCursorReal.get(win);
ZZCell res = ZZCursorReal.get(grammarCurs(win.getSpace())).zzclone();
ZZCursorReal.get(win).insert(Parser.textdim, 1, res);
ZZCursorReal.set(win, res);
}
static public void mkTypeNode(ZZCell win) {
ZZCell c = ZZCursorReal.get(win).N("d.2");
ZZCursorReal.set(win, c);
ZZCursorReal.set(typeCurs(win.getSpace()), c);
}
static public void mkDecNode(ZZCell win) {
ZZCell c = ZZCursorReal.get(typeCurs(win.getSpace()));
Parser.TypeNode tn = new Parser.TypeNode(c);
Parser.DecNode dn = new Parser.DecNode(tn, "", new Parser.TypeNode[0]);
ZZCursorReal.get(win).insert("d.1", 1, dn.c);
ZZCursorReal.set(win, dn.c);
}
static public void mkExpNode(ZZCell win) {
Parser.DecNode dn = new Parser.DecNode(ZZCursorReal.get(win));
Parser.ExpNode en = new Parser.ExpNode(dn, new Parser.ExpNode[0]);
ZZCursorReal.set(win, en.c);
}
static public void mkDecRef(ZZCell win) {
ZZCell c = ZZCursorReal.get(win);
c = c.N(Parser.textrankdim);
c.setText("0");
c.connect(Parser.textgrammardim, 1,
ZZCursorReal.get(grammarCurs(win.getSpace())).zzclone());
ZZCursorReal.set(win, c);
}
static public void twoWinExp(ZZCell win) {
ZZCell other = win.s("d.ctrlview");
if(other == null) other = win.s("d.ctrlview", -1);
Parser.DecNode dn = new Parser.DecNode(ZZCursorReal.get(other));
Parser.ExpNode en = new Parser.ExpNode(dn, new Parser.ExpNode[0]);
ZZCursorReal.get(win).insert(Parser.valuedim, 1, en.c);
}
static public void remove(ZZCell win) {
ZZCell c = ZZCursorReal.get(win);
c = c.h(Parser.valuedim);
ZZCursorReal.set(win, c);
if(c.s(Parser.valuedim) != null) c.disconnect(Parser.valuedim, 1);
}
static public void move(ZZCell win, int dir) {
ZZCell c = ZZCursorReal.get(win);
if(c.s(Parser.paramdim, -1) == null) return;
c = c.s(Parser.paramdim, dir);
if(c.s(Parser.paramdim, -1) != null) ZZCursorReal.set(win, c);
}
static public void movein(ZZCell win) {
ZZCell c = ZZCursorReal.get(win);
c = c.h(Parser.valuedim, 1);
c = c.s(Parser.paramdim, 1);
if(c != null) ZZCursorReal.set(win, c);
}
static public void moveout(ZZCell win) {
ZZCell c = ZZCursorReal.get(win);
c = c.h(Parser.valuedim);
c = c.h(Parser.paramdim);
c = c.h(Parser.valuedim);
ZZCursorReal.set(win, c);
}
static public void click(ZZCell win, Flob f) {
if( !(f instanceof TokenFlob)) { p("No TkFlob"); return; }
TokenFlob tk = (TokenFlob)f;
if(tk.tkHandle == null) { p("No handle in TkFlob"); return; }
ZZCursorReal.set(win, tk.tkHandle);
}
static public void action(ZZCell win, String id, Flob f) {
if(id.equals("SETGRAMMAR")) setGrammarNode(win);
else if(id.equals("GOTOGRAMMAR")) gotoGrammarNode(win);
else if(id.equals("SETTYPE")) setTypeNode(win);
else if(id.equals("GOTOTYPE")) gotoTypeNode(win);
else if(id.equals("VIEWGRAMMAR")) viewGrammarNodes(win);
else if(id.equals("VIEWTEXTS")) viewTexts(win);
else if(id.equals("VIEWTYPE")) viewTypeNode(win);
else if(id.equals("VIEWDEC")) viewDecNode(win);
else if(id.equals("VIEWEXP")) viewExpNode(win);
else if(id.equals("VIEWSEQ")) viewSequence(win);
else if(id.equals("STDVIEW")) stdView(win);
else if(id.equals("MKGRAMMAR")) mkGrammarNode(win);
else if(id.equals("MKTEXT")) mkText(win);
else if(id.equals("MKTYPE")) mkTypeNode(win);
else if(id.equals("MKDEC")) mkDecNode(win);
else if(id.equals("MKDECREF")) mkDecRef(win);
else if(id.equals("MKEXP")) mkExpNode(win);
else if(id.equals("TWOWINEXP")) twoWinExp(win);
else if(id.equals("REMOVE")) remove(win);
else if(id.equals("MOVELEFT")) move(win, -1);
else if(id.equals("MOVERIGHT")) move(win, 1);
else if(id.equals("MOVEIN")) movein(win);
else if(id.equals("MOVEOUT")) moveout(win);
else if(id.equals("CLICK")) click(win, f);
else throw new ZZError("Unknown Zaubertrank action "+id);
}
}

View File

@@ -0,0 +1,93 @@
/*
Evaluator.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.util.*;
/** An evaluator for zaubertrank expressions.
*/
public class Evaluator {
public static final String rcsid = "$Id: Evaluator.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
// XXX should be able to store the following in the structure for debugging
public Stack data = new Stack();
public Stack returns = new Stack();
public Stack frames = new Stack();
public Data frame;
public ZZCell pos;
public boolean failed = false;
public Evaluator(ZZCell what, Data args) {
pos = what.h("zaubertrank:rpn");
frame = args;
}
public void step() {
ZZCell root = pos.getRootclone();
Primitive p = PrimitiveSet.findPrimitive(root);
if(root == null) { // RETURN STEP -- XXX return cell in ztpart
if(returns.empty()) return;
pos = (ZZCell)returns.pop();
frame = (Data)frames.pop();
} else if(p != null) {
Object[] args = new Object[p.args()];
for(int i=args.length-1; i>=0; i--) args[i] = data.pop();
data.push(p.eval(new Data(args)));
} else if(root.s("d.zt-arg") != null) {
int nr = Data.i(root.s("d.zt-arg"));
data.push(frame.o(nr));
} else { // FUNCTION CALL! (XXX need argument reads)
throw new ZZError("Function calls aren't working yet!");
/*
Parser.DecNode dn = new Parser.DecNode(root);
Object[] args = new Object[dn.params.length];
for(int i=args.length-1; i>=0; i--) args[i] = data.pop();
returns.push(pos);
frames.push(frame);
frame = new Data(args);
pos = dn.c.h("zaubertrank:rpn"); // XXX fix
*/
}
pos = pos.s(Parser.sequencedim);
}
static public Object eval(ZZCell what, Data args) {
Evaluator e = new Evaluator(what, args);
while(e.running()) e.step();
if(e.failed) return null;
return e.data.pop();
}
public boolean running() {
return (!failed && pos != null);
}
public boolean finished() {
return (!failed && pos == null);
}
}

View File

@@ -0,0 +1,209 @@
/*
ParsedView.zob
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
/** A view for the zaubertrank using the Parser class.
*/
public class ParsedView implements FlobView, ZOb {
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
/** The font to use. */
Font font
= new Font("SansSerif", Font.PLAIN, 16);
ZOb ftextlayouter
= new FTextLayouter();
/** Whether to mark the accursed part. */
boolean mark
= false;
int xmargin
= 8;
int ymargin
= 2;
int yspace
= 10;
}
FontMetrics fm;
INITIALIZE {
fm = FONTMETRICS(font);
}
static class TokenPart extends FText.CellPart {
int tkNumber;
ZZCell tkHandle;
public TokenPart(ZZCell c, int offs, int n, Font f, FontMetrics fm,
Color bg, Color fg, int tkNumber, ZZCell tkHandle) {
super(c, offs, n, f, fm, bg, fg);
this.tkNumber = tkNumber;
this.tkHandle = tkHandle;
}
public FText.Part subpart(int first, int last) {
return new TokenPart(c, offs+first, last-first, f, this.fm,
bg, fg, tkNumber, tkHandle);
}
public Renderable rend(int x, int y, int d, Renderable prev0) {
TokenFlob prev = null, parent = null, res;
p("SimpleView.TokenPart.rend prev "+prev0);
if(prev0 instanceof TokenFlob) {
prev = (TokenFlob)prev0;
if(prev.c != this.c) prev = null;
else if(prev.parent != null) parent = (TokenFlob)prev.parent;
else parent = prev;
}
p("SimpleView.TokenPart.rend found prev "+prev+" -- parent "+parent);
res = new TokenFlob(x, y, d, width(), height(),
c, s, f, this.fm, parent, offs, n, bg, tkHandle);
if(prev != null) res.setPrev(prev);
if(parent == null) res.tkNumber = tkNumber;
p("SimpleView.TokenPart nr "+tkNumber+" has nr "+res.tkNumber+" rend: "+res);
return res;
}
}
FText.Part make(ZZCell c, int number, ZZCell tkHandle,
ZZCell view) {
Color bg = null;
if(mark && tkHandle.equals(ZZCursorReal.get(view)))
bg = ZZCursorReal.getColor(view);
Color fg = Color.black;
return new TokenPart(c, 0, -1, font, fm, bg, fg, number, tkHandle);
}
FText.Part make(String s) {
return new FText.StringPart(s, font, fm, null, Color.black);
}
void getParts(Vector v, Parser.TypeRef tr, TokenGrouper g, int parent,
ZZCell tkHandle, ZZCell view) {
int number = g.addToken(parent);
ZZCell[] text = tr.getText();
if(text == null) { v.addElement(make("<type without text>")); return; }
v.addElement(make("["));
for(int i=0; i<text.length; i++)
v.addElement(make(text[i], number, tkHandle, view));
v.addElement(make("?]"));
}
void getParts(Vector v, Parser.ExpRef er, TokenGrouper g, int parent,
ZZCell view) {
int number = g.addToken(parent);
Object[] text = er.getText();
for(int i=0; i<text.length; i++) {
Object o = text[i];
if(o instanceof ZZCell) {
v.addElement(make((ZZCell)o, number, er.e.c, view));
} else if(o instanceof Parser.ExpRef) {
Parser.ExpRef sub_er = (Parser.ExpRef)o;
ZZCell sub_c = sub_er.e.c;
getParts(v, sub_er, g, number, view);
} else if(o instanceof Parser.TypeRef) {
getParts(v, (Parser.TypeRef)o, g, number, er.e.c, view); // XXX tkHandle
} else
throw new ZZError("ARGH! strange type in ExpRef.getText");
}
}
public void place(FlobSet into, Parser.ExpNode en, Rectangle rect,
TokenGrouper grp, Parser.GrammarNode gn, int dir,
ZZCell view, int[] inits) {
int number = grp.addToken(-1);
Vector parts = new Vector();
Parser.ExpRef er = new Parser.ExpRef(en, gn);
getParts(parts, er, grp, -1, view);
parts.addElement(make(". "));
FText ftxt = new FText(parts);
boolean[] beginningSentence = new boolean[2];
beginningSentence[0] = true;
beginningSentence[1] = false;
int starty;
if(dir <= 0) starty = inits[0];
else starty = inits[1];
Rectangle res =
((FTextLayouter)ftextlayouter).place(into, ftxt, rect, 1,
dir, starty,
FText.Part.len(ftxt.parts)/2,
false, beginningSentence);
int xm = xmargin+3, ym = ymargin+3;
into.add(new CellBgFlob(res.x-xm, res.y-ym, 2, res.width+xm+xm,
res.height+ym+ym, en.c));
if(dir <= 0) inits[0] = res.y - 2*ym - yspace - 6;
if(dir >= 0) inits[1] = res.y + res.height + 2*ym + yspace + 6;
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
ZZCell c = accursed;
while(c.h(Parser.paramdim) != c ||
c.h(Parser.valuedim) != c) {
c = c.h(Parser.paramdim);
c = c.h(Parser.valuedim);
}
TokenGrouper grp = new TokenGrouper();
Parser.GrammarNode gn = new Parser.GrammarNode(
view.getSpace().getHomeCell().s(Parser.grammardim));
Parser.ExpNode en = new Parser.ExpNode(c);
Dimension size = into.getSize();
Rectangle rect = new Rectangle(xmargin, ymargin, size.width-2*xmargin,
size.height-2*ymargin);
int[] inits = new int[2];
inits[0] = (inits[1] = rect.y + rect.height/2);
place(into, en, rect, grp, gn, 0, view, inits);
for(Parser.ExpNode en0 = en.step(-1);
en0 != null && inits[0] > rect.y;
en0 = en0.step(-1)) {
place(into, en0, rect, grp, gn, -1, view, inits);
}
for(Parser.ExpNode en1 = en.step(1);
en1 != null && inits[1] < rect.y+rect.height;
en1 = en1.step(1)) {
place(into, en1, rect, grp, gn, 1, view, inits);
}
grp.group(into);
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,275 @@
/*
Parser.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.util.*;
/** A parser for zaubertrank programs.
* Currently micro-level: the biggest structure recognized is one statement.
*/
public class Parser {
public static final String rcsid = "$Id: Parser.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
static Object NULL = new Object();
static public final String paramdim = "d.2"; // parameter list dim
static public final String valuedim = "d.1";
static public final String recorddim = "d.1";
static public final String sequencedim = "d.zaubertrank-list";
static public final String textdim = "d.zaubertrank-txt-alt";
static public final String textrankdim = "d.2";
static public final String textgrammardim = "d.1";
static public final String grammardim = "d.zaubertrank-grammar-list";
static public final String decdim = "d.zaubertrank-declarations";
/** A reference to an ExpNode param in a certain grammatical form. */
static public final class DecRef {
int i;
GrammarNode g;
public DecRef(int i, GrammarNode g) { this.i = i; this.g = g; }
}
/** A reference to a certain ExpNode in a certain grammatical form.
* The difference to DecRef is that DecRef contains only a param number
* and a GrammarNode; additionally, an ExpNode is needed to read the
* actual text.
*/
static public final class ExpRef {
ExpNode e;
GrammarNode g;
public ExpRef(ExpNode e, GrammarNode g) { this.e = e; this.g = g; }
public Object[] getText() { return e.getText(g); }
}
static public final class TypeRef {
TypeNode t;
GrammarNode g;
public TypeRef(TypeNode t, GrammarNode g) { this.t = t; this.g = g; }
public ZZCell[] getText() { return t.getText(g); }
}
static public class Node {
public ZZCell c;
public boolean equals(Node other) { return c.equals(other.c); }
}
/** A node declaring a grammatical way to utter a type.
* Example: English noun ("the person" // "which person?")
* Example: English statement ("the ball is red" // "what is true?")
* Example: English genitive ("the person's" // "whose?")
* etc.
*/
static public class GrammarNode extends Node {
public GrammarNode(ZZCell c) {
this.c = c.getRootclone();
if(!this.c.h(grammardim).equals(this.c.getSpace().getHomeCell()))
throw new ZZError("Attempt to create GrammarNode from " +
"non-grammar cell "+this.c);
}
public GrammarNode(ZZSpace sp) {
this.c = sp.getHomeCell().N(grammardim, 1);
}
}
static ZZCell[] readText(ZZCell c, GrammarNode g) {
ZZCell root = c.intersect(textdim, 1, g.c, "d.clone", 1);
p("Parse intersect "+c+" and "+g.c+" gives "+root);
if(root == null) return null;
return root.readRank(textrankdim, 1, false);
}
static void writeText(ZZCell c, GrammarNode g, ZZCell[] tc) {
ZZCell here = g.c.zzclone();
c.insert(textdim, 1, here);
for(int i=0; i<tc.length; i++) {
here.insert(textrankdim, 1, tc[i]);
here = tc[i];
}
}
/** A node declaring a data type. */
static public class TypeNode extends Node {
public TypeNode(ZZCell c) { this.c = c.getRootclone(); }
public TypeNode(ZZSpace sp) { this.c = sp.getHomeCell().N(); }
public ZZCell[] getText(GrammarNode g) {
return readText(c, g);
}
public void setText(GrammarNode g, ZZCell[] tc) {
writeText(c, g, tc);
}
}
/** A node declaring a variable or a function of a data type. */
static public class DecNode extends Node {
TypeNode type;
TypeNode[] params;
/** Create from structure */
public DecNode(ZZCell c) {
this.c = c;
type = new TypeNode(c.h(decdim));
ZZCell[] pcells = c.readRank(paramdim, 1, false);
params = new TypeNode[pcells.length];
for(int i=0; i<pcells.length; i++)
params[i] = new TypeNode(pcells[i]);
}
/** Create anew, to put into the structure */
public DecNode(TypeNode type, String title, TypeNode params[]) {
this.type = type;
c = type.c.N(decdim);
if(title != null) c.setText(title);
ZZCell here = c;
for(int i=0; i<params.length; i++) {
ZZCell there = params[i].c.zzclone();
here.insert(paramdim, 1, there);
here = there;
}
}
/** Read the text for a given GrammarNode.
* Returns an Object[] array where the Objects are either ZZCells
* (which contain a piece of the text) or DecRef instances containing
* an int and a GrammarNode as reference to a param.
*/
public Object[] getText(GrammarNode g) {
ZZCell[] rank = readText(c, g);
if(rank == null) return null;
Object[] res = new Object[rank.length];
for(int i=0; i<rank.length; i++) {
ZZCell gr = rank[i].s(textgrammardim, 1);
if(gr == null) res[i] = rank[i];
else res[i] = new DecRef(Integer.parseInt(rank[i].t()),
new GrammarNode(gr));
}
return res;
}
/** Write the text for a given GrammarNode.
* Returns an Object[] array where the Objects are either ZZCells
* (which contain a piece of the text) or DecRef instances containing
* an int and a GrammarNode as reference to a param.
*/
public void setText(GrammarNode g, Object[] text) {
ZZCell[] rank = new ZZCell[text.length];
for(int i=0; i<text.length; i++) {
if(text[i] instanceof ZZCell) rank[i] = (ZZCell)text[i];
else if(text[i] instanceof DecRef) {
DecRef ref = (DecRef)text[i];
rank[i] = c.N();
rank[i].setText(""+ref.i);
rank[i].connect(textgrammardim, 1, ref.g.c.zzclone());
} else
throw new ZZError("Strange object: "+text[i]);
}
writeText(c, g, rank);
}
}
/** A node representing an expression.
* An expression consists of a reference to a DecNode (which references
* a data type), and references to ExpNodes as parameters.
*/
static class ExpNode extends Node {
public ExpNode[] params;
public DecNode dec;
/** Create from structure */
public ExpNode(ZZCell c) {
this.c = c;
dec = new DecNode(c.getRootclone());
int i = 0;
for(ZZCell var=c.s(paramdim); var!=null; var=var.s(paramdim)) {
i++;
}
params = new ExpNode[i];
i = 0;
for(ZZCell var=c.s(paramdim); var!=null; var=var.s(paramdim)) {
ZZCell val = var.s(valuedim);
if(val != null) params[i] = new ExpNode(val);
i++;
}
}
/** Create anew, to put into the structure */
public ExpNode(DecNode dec, ExpNode[] params) {
this.dec = dec;
this.params = new ExpNode[dec.params.length];
System.arraycopy(params, 0, this.params, 0, params.length);
c = dec.c.zzclone();
ZZCell here = c;
for(int i=0; i<dec.params.length; i++) {
here = here.N(paramdim);
if(i >= params.length || params[i] == null) continue;
if(params[i].c.s(valuedim, -1) != null)
params[i].c.disconnect(valuedim, -1);
here.connect(valuedim, 1, params[i].c);
}
}
/** Change a param in the structure. */
public void setParam(int nr, ExpNode val) {
ZZCell var = c.getOrNewCell(paramdim, nr+1);
if(var.s(valuedim) != null) var.disconnect(valuedim, 1);
if(val.c.s(valuedim, -1) != null) val.c.disconnect(valuedim, -1);
var.connect(valuedim, 1, val.c);
}
/** Read the text for a given GrammarNode.
* Returns an Object[] array where the Objects are ZZCells
* (which contain a piece of the text) ExpRef objects, or TypeRef
* objects.
* <br>
* NOTE: there is no corresponding setText function because the
* text is deducted from params[] and dec.getText().
*/
public Object[] getText(GrammarNode g) {
Object[] res = dec.getText(g);
if(res == null) return null;
for(int i=0; i<res.length; i++) {
if(res[i] instanceof DecRef) {
DecRef ref = (DecRef)res[i];
if(params[ref.i] != null)
res[i] = new ExpRef(params[ref.i], ref.g);
else
res[i] = new TypeRef(dec.params[ref.i], ref.g);
}
}
return res;
}
/** Step through a sequence (list) of expression nodes. */
public ExpNode step(int steps) {
ZZCell c0 = c.s(sequencedim, steps);
if(c0 == null) return null;
return new ExpNode(c0);
}
}
}

View File

@@ -0,0 +1,43 @@
/*
Primitive.java
*
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
* Copyright (c) 2000-2001, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
/** A primitive for use in the zaubertrank.
*/
public abstract class Primitive {
String rcsid = "$Id: Primitive.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
// In subclasses, override one of the following two:
protected Object eval(Data params) { return null; }
public Object eval(Data params, ZZSpace space) {
return eval(params);
}
public abstract int args();
}

View File

@@ -0,0 +1,78 @@
/*
PrimitiveSet.java
*
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
* Copyright (c) 2001, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Tuomas Lukka (for Heraclitus Clang)
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.util.*;
/** A set of Zaubertrank primitives.
*/
public abstract class PrimitiveSet {
String rcsid = "$Id: PrimitiveSet.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public abstract Primitive get(String id);
static Hashtable pss = new Hashtable();
static PrimitiveSet findPrimitiveSet(String set) {
Object o = pss.get(set);
if(o != null) return (PrimitiveSet)o;
try {
o = Class.forName("org.gzigzag.flowing."+set).newInstance();
} catch(Exception e) {
ZZLogger.exc(e);
return null;
}
if(!(o instanceof PrimitiveSet)) return null;
pss.put(set, o);
return (PrimitiveSet)o;
}
static Hashtable prims = new Hashtable();
static Primitive findPrimitive(String s) {
Object o = prims.get(s);
if(o != null) return (Primitive)o;
int ind = s.indexOf(".");
if(ind < 0) return null;
String set = s.substring(0, ind);
String id = s.substring(ind+1);
PrimitiveSet ps = findPrimitiveSet(set);
Primitive prim = ps.get(id);
if(prim != null)
prims.put(id, prim);
return prim;
}
public static Primitive findPrimitive(ZZCell c0) {
ZZCell c = c0.getRootclone();
c = c.s("d.zaubertrank-primitive-binding");
if(c == null) return null;
if(!c.h("d.zaubertrank-primitives").equals(
c.getSpace().getHomeCell()))
throw new ZZError("Zaubertrank primitive not enumerated on " +
"d.zaubertrank-primitives rank from home cell!");
return findPrimitive(c.t());
}
}

View File

@@ -0,0 +1,137 @@
/*
SimpleView.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
/** A simple view just showing a structure as text.
*/
public class SimpleView implements FlobView, ZOb {
public static boolean dbg = true;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
/** The font to use. */
Font font
= new Font("SansSerif", Font.PLAIN, 16);
ZOb ftextlayouter
= new FTextLayouter();
}
FontMetrics fm;
INITIALIZE {
fm = FONTMETRICS(font);
}
static class TokenPart extends FText.CellPart {
int tkNumber;
public TokenPart(ZZCell c, int offs, int n, Font f, FontMetrics fm,
Color bg, Color fg, int tkNumber) {
super(c, offs, n, f, fm, bg, fg);
this.tkNumber = tkNumber;
}
public FText.Part subpart(int first, int last) {
return new TokenPart(c, offs+first, last-first, f, this.fm,
bg, fg, tkNumber);
}
public Renderable rend(int x, int y, int d, Renderable prev0) {
TokenFlob prev = null, parent = null, res;
p("SimpleView.TokenPart.rend prev "+prev0);
if(prev0 instanceof TokenFlob) {
prev = (TokenFlob)prev0;
if(prev.c != this.c) prev = null;
else if(prev.parent != null) parent = (TokenFlob)prev.parent;
else parent = prev;
}
p("SimpleView.TokenPart.rend found prev "+prev+" -- parent "+parent);
res = new TokenFlob(x, y, d, width(), height(),
c, s, f, this.fm, parent, offs, n, bg, c);
if(prev != null) res.setPrev(prev);
if(parent == null) res.tkNumber = tkNumber;
p("SimpleView.TokenPart nr "+tkNumber+" has nr "+res.tkNumber+" rend: "+res);
return res;
}
}
FText.Part make(ZZCell c, int number) {
return new TokenPart(c, 0, -1, font, fm, null, Color.black, number);
}
FText.Part make(String s) {
return new FText.StringPart(s, font, fm, null, Color.black);
}
Vector getPart(ZZCell c, TokenGrouper g, int parent) {
Vector v = new Vector();
ZZCell tx = c.getRootclone(), var = c.s("d.2");
if(tx.equals(c)) {
v.addElement(make(c, g.addToken(parent)));
return v;
}
int number = g.addToken(parent);
for(tx = tx.s("d.2"); tx != null; tx = tx.s("d.2")) {
ZZCell type = tx.getRootclone();
if(type.equals(tx))
v.addElement(make(tx, number));
else {
ZZCell val;
if(var == null || (val=var.s("d.1")) == null) {
v.addElement(make("["));
v.addElement(make(type.s("d.2"), g.addToken(number)));
v.addElement(make("?]"));
} else {
v.addElement(make("("));
Vector w = getPart(val, g, number);
for(Enumeration e = w.elements();
e.hasMoreElements();) {
v.addElement(e.nextElement());
}
v.addElement(make(")"));
}
if(var != null) var = var.s("d.2");
}
}
return v;
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
TokenGrouper grp = new TokenGrouper();
FText ftxt = new FText(getPart(accursed, grp, -1));
Dimension size = into.getSize();
Rectangle rect = new Rectangle(0, 0, size.width, size.height);
((FTextLayouter)ftextlayouter).place(into, ftxt, rect,
0, rect.y+rect.height/2,
FText.Part.len(ftxt.parts)/2,
false, null); // XXX use firstcap
grp.group(into);
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,78 @@
/*
TokenFlob.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.awt.*;
/** A SplitCellFlob1 showing a Zaubertrank token.
* This is an own class in order to get the XOR highlighting right.
*/
public class TokenFlob extends SplitCellFlob1 {
public static final String rcsid = "$Id: TokenFlob.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
// tk for 'token.'
public TokenFlob tkParent, tkFirstChild, tkNextChild;
public TokenFlob tkNextPart, tkFirstPart;
public int tkNumber = -1;
public ZZCell tkHandle;
public void setTkParent(TokenFlob parent) {
tkParent = parent;
tkNextChild = parent.tkFirstChild;
parent.tkFirstChild = this;
}
public void setTkFirstPart(TokenFlob first) {
tkFirstPart = first;
tkNextPart = first.tkNextPart;
first.tkNextPart = this;
}
TokenFlob(int x, int y, int d, int w, int h, ZZCell c, String txt, Font f,
FontMetrics fm, SplitCellFlob1 parent, int start, int n, Color bg,
ZZCell tkHandle) {
super(x, y, d, w, h, c, txt, f, fm, parent, start, n, bg);
this.bg = bg;
this.tkHandle = tkHandle;
tkFirstPart = this;
}
public void renderChildrenXOR(Graphics g) {
for(TokenFlob tk = tkFirstChild; tk != null; tk = tk.tkNextChild) {
tk.renderXORFrame(g, false, false);
tk.renderChildrenXOR(g);
}
}
public boolean renderXOR(Graphics g, int cx, int cy) {
if(!insideRect(cx, cy)) return false;
tkFirstPart.renderChildrenXOR(g);
for(TokenFlob tk = tkFirstPart; tk != null; tk = tk.tkNextPart)
tk.renderXORSolid(g);
return true;
}
}

View File

@@ -0,0 +1,81 @@
/*
TokenGrouper.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/** A class to group TokenFlobs into their hierarchies.
*/
public class TokenGrouper {
public static final String rcsid = "$Id: TokenGrouper.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
private int ntoks = 0;
private Vector parents = new Vector();
public int addToken(int parent) {
parents.addElement(new Integer(parent));
p("TokenGroup cur "+ntoks+" parent "+parent);
return ntoks++; // i.e., return ntoks and after, increment one
}
public void group(final FlobSet into) {
final TokenFlob[] toks = new TokenFlob[ntoks];
if(dbg) into.dump();
into.iterDepth(new FlobSet.DepthIter() {
public void act(Flob[] flobs, int start, int n) {
for(int f = start; f<start+n; f++) {
Flob cur = flobs[f];
p("TokenGroup found flob "+cur);
if(!(cur instanceof TokenFlob)) continue;
TokenFlob tf = (TokenFlob)cur;
if(tf.tkNumber >= 0) {
if(toks[tf.tkNumber] == null)
toks[tf.tkNumber] = tf;
else
tf.setTkFirstPart(toks[tf.tkNumber]);
}
p("...is TokenFlob "+tf.tkNumber);
}
}}, false);
int child = 0;
for(Enumeration e = parents.elements(); e.hasMoreElements();) {
int parent = ((Integer)e.nextElement()).intValue();
p("TokenGroup connect parent "+parent+" child "+child);
if(parent >= 0 && toks[child] != null && toks[parent] != null)
toks[child].setTkParent(toks[parent]);
child++;
}
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,54 @@
/*
Zaubertrank.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
/** The module for the Zaubertrank applitude.
*/
public class Zaubertrank {
public static final String rcsid = "$Id: Zaubertrank.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static final void pa(String s) { System.out.println(s); }
static public ZZModule module = new ZZModule() {
public void action(String id,
ZZCell code,
ZZCell target,
ZZView view, ZZView cview, String key, Point pt, ZZScene xi) {
Flob[] flob = new Flob[1];
if(pt != null) ((FlobSet)xi).getObjectAt(pt.x, pt.y, flob);
org.zaubertrank.Actions.action(view.getViewcell(), id, flob[0]);
}
public ZOb newZOb(String id) {
if(id.equals("Simple"))
return new org.zaubertrank.SimpleView();
else if(id.equals("Parsed"))
return new org.zaubertrank.ParsedView();
return null;
}
};
}

View File

@@ -0,0 +1,216 @@
/*
ZaubertrankPart.java
*
* Copyright (c) 2000, Benjamin Fallenstein
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Benjamin Fallenstein
*/
package org.zaubertrank;
import org.gzigzag.*;
import java.util.*;
/** A spacepart for the zaubertrank.
* Currently connects tokens in Reverse Polish Notation, and has cells whose
* content is the computed result of a Zaubertrank function.
*/
public class ZaubertrankPart extends ZZROSpacePart {
public static final String rcsid = "$Id: ZaubertrankPart.java,v 1.1 2001/04/02 20:29:05 bfallenstein Exp $";
public static boolean dbg = false;
private static final void p(String s) { if(dbg) System.out.println(s); }
private static final void pa(String s) { System.out.println(s); }
public ZaubertrankPart(ZZSpace space, String id) {
super(space, id);
}
public static class Result {
String codeID;
int nr;
public Result(String c, int nr) { codeID = c; this.nr = nr; }
}
public Object parseIDPart(String idPart) {
if(idPart.substring(0, 7).equals("result-")) {
String rest = idPart.substring(7);
int idx = rest.indexOf("-");
if(idx < 0 || idx+1 == rest.length()) return null;
String nr = rest.substring(0, idx);
String codeID = rest.substring(idx+1);
try {
return new Result(codeID, Integer.parseInt(nr));
} catch(NumberFormatException e) {
return null;
}
} else
return null;
}
public String generateIDPart(Object parsed) {
if(parsed instanceof Result) {
Result r = (Result)parsed;
return "result-" + r.nr + "-" + r.codeID;
} else
throw new ZZError("Not a ZaubertrankPart parsed ID object!");
}
public String getText(ZZCellHandle c) {
if(c.parsedID instanceof Result) {
Result r = (Result)c.parsedID;
ZZCell code = space.getCellByID(r.codeID);
pa("code "+code);
Object res;
try {
res = Evaluator.eval(code, new Data(c));
} catch(Throwable t) {
// ZZLogger.exc(t);
return t.getMessage();
}
return Data.s(res);
} else
return "";
}
public ZZDimension getDim(String name) {
if(name.equals("result")) return new ResultDimension();
else if(name.equals("rpn")) return new ReversePolishNotation();
return null;
}
public class ResultDimension extends ZZRODimension {
public ZZCellHandle s(ZZCellHandle c, int steps, ZZObs o) {
Result r = null;
if(c.parsedID instanceof Result) r = (Result)c.parsedID;
if(r == null) {
if(steps <= 0) return null;
r = new Result(c.getID(), steps);
return (ZZCellHandle)space.getCellByID(ZaubertrankPart.this,
generateID(r), r);
} else {
r = new Result(r.codeID, r.nr + steps);
if(r.nr < 0) return null;
else if(r.nr == 0)
return (ZZCellHandle)space.getCellByID(r.codeID);
else
return (ZZCellHandle)space.getCellByID(ZaubertrankPart.this,
generateID(r), r);
}
}
}
public static ZZCell parent(ZZCell c, ZZObs o) throws SyntaxError {
c = c.s(Parser.valuedim, -1, o);
if(c == null) return null;
c = c.h(Parser.paramdim, -1, true, o);
if(c == null) throw new SyntaxError("Not connected to parent!");
return c;
}
private static ZZCell sibling(ZZCell c, int dir, ZZObs o)
throws SyntaxError {
c = c.s(Parser.valuedim, -1, o);
if(c == null) return null; // XXX syntax error? has no siblings at all!
c = c.s(Parser.paramdim, dir, o);
if(dir < 0 && c == null) throw new SyntaxError("was parent already");
else if(dir > 0 && c == null) return null;
// i.e., this was the last sibling
else if(dir < 0 && c.s(Parser.paramdim, -1, o) == null) return null;
// i.e., this was the first sibling
c = c.s(Parser.valuedim, 1, o);
if(c == null) throw new MissingTermError("Term's missing");
return c;
}
public static ZZCell prevSibling(ZZCell c, ZZObs o) throws SyntaxError {
return sibling(c, -1, o);
}
public static ZZCell nextSibling(ZZCell c, ZZObs o) throws SyntaxError {
return sibling(c, 1, o);
}
public static ZZCell firstChild(ZZCell c, ZZObs o) throws SyntaxError {
c = c.s(Parser.paramdim, 1, o);
if(c == null) return null;
c = c.s(Parser.valuedim, 1, o);
if(c == null) throw new MissingTermError("Term's missing");
return c;
}
public static ZZCell lastChild(ZZCell c, ZZObs o) throws SyntaxError {
c = c.h(Parser.paramdim, 1, true, o);
if(c == null) return null;
c = c.s(Parser.valuedim, 1, o);
if(c == null) throw new MissingTermError("Term's missing");
return c;
}
public static ZZCell firstDescendant(ZZCell c, ZZObs o) throws SyntaxError {
LoopDetector l = new LoopDetector();
ZZCell d = c;
while(true) {
d = firstChild(c, o);
if(d == null) return c;
c = d;
l.detect(c);
}
}
public static ZZCell rpnPrev(ZZCell c, ZZObs o) throws SyntaxError {
ZZCell d = lastChild(c, o);
if(d != null) return d;
LoopDetector l = new LoopDetector();
while(true) {
d = prevSibling(c, o);
if(d != null) return d;
l.detect(c);
c = parent(c, o);
if(c == null) return null;
}
}
public static ZZCell rpnNext(ZZCell c, ZZObs o) throws SyntaxError {
ZZCell d = nextSibling(c, o);
if(d == null) return parent(c, o);
else return firstDescendant(d, o);
}
public class ReversePolishNotation extends ZZRODimension {
public ZZCellHandle s(ZZCellHandle c, int steps, ZZObs o) {
// Sanity check: can this be a tree node?
if(c.s(Parser.valuedim, 1, o) != null) return null;
if(c.s(Parser.paramdim, -1, o) != null) return null;
// Until we have syntax error cells, let the errors be throws.
// try {
if(steps > 0)
for(int i=0; i<steps; i++)
c = (ZZCellHandle)rpnNext(c, o);
else
for(int i=0; i>steps; i--)
c = (ZZCellHandle)rpnPrev(c, o);
// Another sanity check
if(c != null && (c.s(Parser.valuedim, 1, o) != null ||
c.s(Parser.paramdim, -1, o) != null))
throw new SyntaxError("Target not a tree node!");
return c;
// } catch(SyntaxError e) {
// ZZLogger.exc(e);
// return null;
// }
}
}
}