mirror of
https://github.com/zeroflag/fcl.git
synced 2025-01-11 20:01:10 +01:00
predicate words experiment
This commit is contained in:
parent
6a9b8530db
commit
7fa71a71a9
7 changed files with 85 additions and 27 deletions
|
@ -9,8 +9,10 @@ import java.util.Set;
|
|||
|
||||
public class Dictionary {
|
||||
private final List<Word> dict = new ArrayList<>();
|
||||
private final Fcl fcl;
|
||||
|
||||
public Dictionary() {
|
||||
public Dictionary(Fcl fcl) {
|
||||
this.fcl = fcl;
|
||||
}
|
||||
|
||||
public void add(Word word) {
|
||||
|
@ -20,7 +22,7 @@ public class Dictionary {
|
|||
public Word at(String name) {
|
||||
for (int i = dict.size() - 1; i >= 0; i--) {
|
||||
Word each = dict.get(i);
|
||||
if (each.visible() && name.equals(each.name()))
|
||||
if (each.match(name, fcl))
|
||||
return each;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -29,7 +29,7 @@ public class Fcl {
|
|||
private static final String EXIT = "exit";
|
||||
private final int SCRATCH_SIZE = 1024;
|
||||
private enum Mode { COMPILE, INTERPRET }
|
||||
private final Dictionary dict = new Dictionary();
|
||||
private final Dictionary dict;
|
||||
private final FclStack rstack = new FclStack();
|
||||
private final JvmInterOp interOp;
|
||||
private final FclStack stack;
|
||||
|
@ -47,6 +47,7 @@ public class Fcl {
|
|||
private final String name;
|
||||
private boolean visible = true;
|
||||
private boolean immediate = false;
|
||||
private Word predicate;
|
||||
|
||||
public ColonDef(int address, String name) {
|
||||
this.address = address;
|
||||
|
@ -70,11 +71,6 @@ public class Fcl {
|
|||
this.visible = isVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean immediate() {
|
||||
return immediate;
|
||||
|
@ -85,6 +81,26 @@ public class Fcl {
|
|||
immediate = isImmediate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void predicate(Word word) {
|
||||
this.predicate = word;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String name, Fcl fcl) {
|
||||
return visible && (this.name.equals(name) || predicateMatch(name, fcl));
|
||||
}
|
||||
|
||||
private boolean predicateMatch(String name, Fcl fcl) {
|
||||
if (predicate == null) return false;
|
||||
fcl.push(new Str(name));
|
||||
predicate.enter();
|
||||
boolean match = fcl.pop().boolValue();
|
||||
if (match)
|
||||
fcl.push(new Str(name));
|
||||
return match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "xt_" + name + " (" + address + ")";
|
||||
|
@ -155,11 +171,6 @@ public class Fcl {
|
|||
this.visible = isVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean immediate() {
|
||||
return false;
|
||||
|
@ -170,6 +181,16 @@ public class Fcl {
|
|||
throw new Aborted("Cannot make immediate val");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void predicate(Word word) {
|
||||
throw new Aborted("var does not support predicate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String name, Fcl fcl) {
|
||||
return visible && this.name.equals(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
stack.push(new Num(address));
|
||||
|
@ -249,11 +270,6 @@ public class Fcl {
|
|||
this.visible = isVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean immediate() {
|
||||
return false;
|
||||
|
@ -264,6 +280,16 @@ public class Fcl {
|
|||
throw new Aborted("Cannot make immediate val");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void predicate(Word word) {
|
||||
throw new Aborted("val does not support predicate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String name, Fcl fcl) {
|
||||
return visible && this.name.equals(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
stack.push(value);
|
||||
|
@ -329,6 +355,7 @@ public class Fcl {
|
|||
}
|
||||
|
||||
public Fcl(FclStack stack, int heapSize, Transcript transcript) {
|
||||
this.dict = new Dictionary(this);
|
||||
this.stack = stack;
|
||||
this.heap = new Object[heapSize];
|
||||
this.interOp = new JvmInterOp(stack);
|
||||
|
@ -386,6 +413,7 @@ public class Fcl {
|
|||
addPrimitive("here", () -> stack.push(new Num(dp)));
|
||||
addPrimitive("dp!", () -> dp = stack.pop().intValue() );
|
||||
addPrimitive("interpret", () -> mode = Mode.INTERPRET);
|
||||
addPrimitive("interpret?", () -> stack.push(mode == Mode.INTERPRET ? Bool.TRUE : Bool.FALSE));
|
||||
addPrimitive("trace", () -> trace = stack.pop().boolValue());
|
||||
addPrimitive("lit", () -> stack.push((Obj)heap[ip++]));
|
||||
addPrimitive(">r", () -> rstack.push(stack.pop()));
|
||||
|
@ -398,6 +426,8 @@ public class Fcl {
|
|||
addPrimitive("[']", () -> stack.push((Word)heap[ip++]));
|
||||
addPrimitive("`", () -> { Word word = dict.at(word()); stack.push(word == null ? Nil.INSTANCE : word); });
|
||||
addPrimitive("immediate", () -> dict.lastWord().immediate(true), true);
|
||||
addPrimitive("lastword", () -> stack.push(dict.lastWord()));
|
||||
addPrimitive("set-predicate", () -> ((Word)stack.pop()).predicate((Word)stack.pop()));
|
||||
addPrimitive(".", () -> show(stack.pop()));
|
||||
addPrimitive("jvm-call-static", interOp::jvmCallStatic);
|
||||
addPrimitive("jvm-call-method", interOp::jvmCallMethod);
|
||||
|
@ -657,6 +687,10 @@ public class Fcl {
|
|||
return stack.pop();
|
||||
}
|
||||
|
||||
public void push(Obj obj) {
|
||||
stack.push(obj);
|
||||
}
|
||||
|
||||
public int stackSize() {
|
||||
return stack.size();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.vectron.fcl.types;
|
||||
|
||||
import com.vectron.fcl.Fcl;
|
||||
import com.vectron.fcl.exceptions.Aborted;
|
||||
import com.vectron.fcl.exceptions.TypeMismatched;
|
||||
|
||||
import static com.vectron.fcl.Fcl.STRICT;
|
||||
|
@ -21,13 +23,18 @@ public class Primitive implements Word {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
public boolean immediate() {
|
||||
return immediate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean immediate() {
|
||||
return immediate;
|
||||
public void predicate(Word word) {
|
||||
throw new Aborted("primitive does not support predicate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String name, Fcl fcl) {
|
||||
return visible && this.name.equals(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package com.vectron.fcl.types;
|
||||
|
||||
import com.vectron.fcl.Fcl;
|
||||
|
||||
public interface Word extends Obj {
|
||||
void enter();
|
||||
String name();
|
||||
void visible(boolean isVisible);
|
||||
boolean visible();
|
||||
boolean immediate();
|
||||
void immediate(boolean isImmediate);
|
||||
void predicate(Word word);
|
||||
boolean match(String name, Fcl fcl);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
} each
|
||||
tbl ;
|
||||
|
||||
: ms ( n -- ) 'java.lang.Thread/sleep/l' jvm-call-static ;
|
||||
|
||||
: ms ( n -- ) :java.lang.Thread/sleep/l jvm-call-static ;
|
||||
: tone ( hz ms -- ) swap :com.vectron.forthcalc.support.Tone/play/di jvm-call-static ;
|
||||
: torch ( n -- ) :com.vectron.forthcalc.support.Torch/toggle/O jvm-call-static ;
|
||||
: torch ( n -- ) :com.vectron.forthcalc.support.Torch/toggle/O jvm-call-static ;
|
||||
|
||||
: match: immediate ` lastword set-predicate ;
|
|
@ -81,9 +81,10 @@ var: oy
|
|||
2 LINE-COLOR paint
|
||||
nil => px nil => py 1 => x
|
||||
ls { -> y
|
||||
x @ y trans 5 draw-circle
|
||||
px @ nil != if
|
||||
px @ py @ trans x @ y trans draw-line
|
||||
x @ y trans 3 draw-circle
|
||||
\ 0 x @ y trans 20 + y >str draw-text
|
||||
then
|
||||
x @ px ! y py !
|
||||
x inc
|
||||
|
|
|
@ -1236,6 +1236,16 @@ public class FclTest {
|
|||
assertEquals(true, evalPop(": tst :my-symbol :my-symbol = ; tst").boolValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPredicateWords() {
|
||||
eval(": octal? ( token -- ) 0 at '&' = ;\n" +
|
||||
": lit-oct ( token -- n ) immediate match: octal?\n" +
|
||||
" 1 over size substr 8 swap :java.lang.Long/parseLong/si jvm-call-static\n" +
|
||||
" interpret? not if ['] lit , , then ;\n");
|
||||
assertEquals(177, evalPop("&261").intValue());
|
||||
assertEquals(169, evalPop(": tst &261 &10 - ; tst ").intValue());
|
||||
}
|
||||
|
||||
private String transcript() {
|
||||
return transcript.content();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue