From f4ed1ea29bc466e63feb3006d7a1b414c5f1ec05 Mon Sep 17 00:00:00 2001 From: zeroflag Date: Fri, 25 Jun 2021 13:57:11 +0200 Subject: [PATCH] import #1 --- Dictionary.java | 53 --- Fcl.java | 585 --------------------------------- FclStack.java | 108 ------ RamTranscript.java | 19 -- Transcript.java | 17 - exceptions/Aborted.java | 7 - exceptions/FclException.java | 11 - exceptions/InterOpFailed.java | 11 - exceptions/NotUnderstood.java | 7 - exceptions/TypeMismatched.java | 21 -- interop/JvmInterOp.java | 50 --- interop/MethodSpec.java | 123 ------- types/ArithmeticOperand.java | 8 - types/Bool.java | 94 ------ types/Dic.java | 124 ------- types/JvmObj.java | 69 ---- types/LogicOperand.java | 7 - types/Lst.java | 174 ---------- types/Nil.java | 61 ---- types/Num.java | 260 --------------- types/Obj.java | 11 - types/Primitive.java | 84 ----- types/Quot.java | 73 ---- types/Range.java | 97 ------ types/Str.java | 175 ---------- types/Word.java | 8 - 26 files changed, 2257 deletions(-) delete mode 100644 Dictionary.java delete mode 100644 Fcl.java delete mode 100644 FclStack.java delete mode 100644 RamTranscript.java delete mode 100644 Transcript.java delete mode 100644 exceptions/Aborted.java delete mode 100644 exceptions/FclException.java delete mode 100644 exceptions/InterOpFailed.java delete mode 100644 exceptions/NotUnderstood.java delete mode 100644 exceptions/TypeMismatched.java delete mode 100644 interop/JvmInterOp.java delete mode 100644 interop/MethodSpec.java delete mode 100644 types/ArithmeticOperand.java delete mode 100644 types/Bool.java delete mode 100644 types/Dic.java delete mode 100644 types/JvmObj.java delete mode 100644 types/LogicOperand.java delete mode 100644 types/Lst.java delete mode 100644 types/Nil.java delete mode 100644 types/Num.java delete mode 100644 types/Obj.java delete mode 100644 types/Primitive.java delete mode 100644 types/Quot.java delete mode 100644 types/Range.java delete mode 100644 types/Str.java delete mode 100644 types/Word.java diff --git a/Dictionary.java b/Dictionary.java deleted file mode 100644 index 9a14171..0000000 --- a/Dictionary.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.vectron.fcl; - -import com.vectron.fcl.types.Word; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class Dictionary { - private final List dict = new ArrayList<>(); - private final Set immediate = new HashSet<>(); - - public Dictionary() { - immediate.addAll(Arrays.asList(";", "immediate", "override")); - } - - public void add(Word word) { - dict.add(word); - } - - 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())) - return each; - } - return null; - } - - public void remove(String name) { - Word exiting = at(name); - if (exiting != null) - dict.remove(exiting); - } - - public boolean isImmediate(String name) { - return immediate.contains(name); - } - - public void makeImmediate(Word word) { - immediate.add(word.name()); - } - - public Set wordList() { - Set result = new HashSet<>(); - for (Word word : dict) { - result.add(word.name()); - } - return result; - } -} diff --git a/Fcl.java b/Fcl.java deleted file mode 100644 index ef91f1e..0000000 --- a/Fcl.java +++ /dev/null @@ -1,585 +0,0 @@ -package com.vectron.fcl; - -import com.vectron.fcl.exceptions.Aborted; -import com.vectron.fcl.exceptions.TypeMismatched; -import com.vectron.fcl.interop.JvmInterOp; -import com.vectron.fcl.types.ArithmeticOperand; -import com.vectron.fcl.types.Bool; -import com.vectron.fcl.types.LogicOperand; -import com.vectron.fcl.types.Nil; -import com.vectron.fcl.types.Num; -import com.vectron.fcl.types.Obj; -import com.vectron.fcl.types.Primitive; -import com.vectron.fcl.types.Str; -import com.vectron.fcl.types.Word; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.util.Set; - -public class Fcl { - public static final boolean STRICT = true; - 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 FclStack rstack = new FclStack(); - private final JvmInterOp interOp; - private final FclStack stack; - private final Transcript transcript; - private Word lastWord; - private Reader reader; - private Mode mode = Mode.INTERPRET; - private final Object[] heap; - private int dp = SCRATCH_SIZE; - private int ip = 0; - - class ColonDef implements Word { - private final int address; - private final String name; - private boolean visible = true; - - public ColonDef(int address, String name) { - this.address = address; - this.name = name; - } - - @Override - public void enter() { - rstack.push(new Num(ip)); - innerLoop(address); - ip = rstack.pop().intValue(); - } - - @Override - public String name() { - return name; - } - - @Override - public void visible(boolean isVisible) { - this.visible = isVisible; - } - - @Override - public boolean visible() { - return visible; - } - - @Override - public String toString() { - return "xt_" + name + " (" + address + ")"; - } - - @Override - public long longValue() { - return address; - } - - @Override - public int intValue() { - return address; - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return address; - } - - @Override - public int compareTo(Obj other) { - return other instanceof ColonDef - ? name.compareTo(((ColonDef) other).name) - : -1; - } - } - - public class Var implements Word { - private final int address; - private final String name; - private boolean visible = true; - - public Var(int address, String name) { - this.address = address; - this.name = name; - heap[address] = new Num(0); - } - - @Override - public void visible(boolean isVisible) { - this.visible = isVisible; - } - - @Override - public boolean visible() { - return visible; - } - - @Override - public void enter() { - stack.push(new Num(address)); - } - - @Override - public String name() { - return name; - } - - @Override - public String toString() { - return "var_" + name + " (" + address + ")"; - } - - @Override - public long longValue() { - return address; - } - - @Override - public int intValue() { - return address; - } - - @Override - public double doubleValue() { - return address; - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return address; - } - - @Override - public int compareTo(Obj other) { - return other instanceof Var - ? name.compareTo(((Var) other).name) - : -1; - } - } - - public class Val implements Word { - private final String name; - private final Obj value; - private boolean visible = true; - - public Val(String name, Obj value) { - this.name = name; - this.value = value; - } - - @Override - public void visible(boolean isVisible) { - this.visible = isVisible; - } - - @Override - public boolean visible() { - return visible; - } - - @Override - public void enter() { - stack.push(value); - } - - @Override - public String name() { - return name; - } - - @Override - public String toString() { - return "val_" + name + " (" + value + ")"; - } - - @Override - public long longValue() { - return value.longValue(); - } - - @Override - public int intValue() { - return value.intValue(); - } - - @Override - public double doubleValue() { - return value.doubleValue(); - } - - @Override - public boolean boolValue() { - return value.boolValue(); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return value; - } - - @Override - public int compareTo(Obj other) { - return other instanceof Val - ? name.compareTo(((Val) other).name) - : -1; - } - } - - - public Fcl(FclStack stack, int heapSize, Transcript transcript) { - this.stack = stack; - this.heap = new Object[heapSize]; - this.interOp = new JvmInterOp(stack); - this.transcript = transcript; - initPrimitives(); - } - - private void initPrimitives() { - addPrimitive("+", () -> stack.push((aOp(stack.pop())).add(stack.pop()))); - addPrimitive("-", () -> { - Obj top = stack.pop(); - stack.push(aOp(stack.pop()).sub(top)); - }); - addPrimitive("*", () -> stack.push((aOp(stack.pop())).mul(stack.pop()))); - addPrimitive("/", () -> { - Obj top = stack.pop(); - stack.push((aOp(stack.pop())).div(top)); - }); - addPrimitive("/mod", () -> { - Num b = stack.pop().asNum(); - Num a = stack.pop().asNum(); - stack.push(a.mod(b)); - stack.push(a.intDiv(b)); - }); - addPrimitive("pow", () -> { - Num exponent = stack.pop().asNum(); - Num base = stack.pop().asNum(); - stack.push(base.power(exponent)); - }); - addPrimitive("and", () -> stack.push(lOp(stack.pop()).and(stack.pop()))); - addPrimitive("or", () -> stack.push((lOp(stack.pop())).or(stack.pop()))); - addPrimitive("not", () -> stack.push((lOp(stack.pop())).not())); - addPrimitive("drop", stack::pop); - addPrimitive("dup", () -> stack.push(stack.peek())); - addPrimitive("swap", () -> { - Obj a = stack.pop(); - Obj b = stack.pop(); - stack.push(a); - stack.push(b); - }); - addPrimitive("rswap", () -> { - Obj a = rstack.pop(); - Obj b = rstack.pop(); - rstack.push(a); - rstack.push(b); - }); - addPrimitive(EXIT, () -> {}); - addPrimitive("clean", stack::clean); - addPrimitive("depth", () -> stack.push(new Num(stack.size()))); - addPrimitive("=", () -> stack.push(stack.pop().equals(stack.pop()) ? Bool.TRUE : Bool.FALSE)); - addPrimitive("<", () -> stack.push(stack.pop().asNum().greater(stack.pop().asNum()))); - addPrimitive("true", () -> stack.push(Bool.TRUE)); - addPrimitive("false", () -> stack.push(Bool.FALSE)); - addPrimitive("nil", () -> stack.push(Nil.INSTANCE)); - addPrimitive("here", () -> stack.push(new Num(dp))); - addPrimitive("interpret", () -> mode = Mode.INTERPRET); - addPrimitive("lit", () -> stack.push((Obj)heap[ip++])); - addPrimitive(">r", () -> rstack.push(stack.pop())); - addPrimitive("r>", () -> stack.push(rstack.pop())); - addPrimitive("i", () -> stack.push(rstack.peek())); - addPrimitive("j", () -> stack.push(rstack.at(1))); - addPrimitive(",", () -> heap[dp++] = stack.pop()); - addPrimitive("!", () -> heap[stack.pop().intValue()] = stack.pop()); - addPrimitive("@", () -> stack.push((Obj) heap[stack.pop().intValue()])); - addPrimitive("[']", () -> stack.push((Word)heap[ip++])); - addPrimitive("`", () -> { Word word = dict.at(word()); stack.push(word == null ? Nil.INSTANCE : word); }); - addPrimitive("immediate", () -> dict.makeImmediate(lastWord)); - addPrimitive(".", () -> show(stack.pop())); - addPrimitive("jvm-call-static", interOp::jvmCallStatic); - addPrimitive("jvm-call-method", interOp::jvmCallMethod); - addPrimitive("jvm-static-var", interOp::jvmStaticVar); - addPrimitive("jvm-null", () -> stack.push(null)); - addPrimitive("asc*", this::sortAsc); - addPrimitive("dsc*", this::sortDsc); - addPrimitive("rev*", this::reverse); - addPrimitive("key", () -> stack.push(new Num(key()))); - addPrimitive("word", () -> stack.push(new Str(word()))); - addPrimitive("override", () -> lastWord.visible(false)); - addPrimitive("reveal", () -> lastWord.visible(true)); - addPrimitive("delword", () -> dict.remove((String)stack.pop().value())); - addPrimitive("jmp#f", () -> ip += stack.pop().boolValue() ? 1 : ((Num) heap[ip]).longValue()); - addPrimitive("jmp", () -> ip += ((Num) heap[ip]).longValue()); - addPrimitive("allot", () -> { int p = dp; dp += stack.pop().longValue(); stack.push(new Num(p)); }); - addPrimitive("freemem", () -> stack.push(new Num(heap.length - dp))); - addPrimitive("var:", () -> { String name = word(); dict.add(new Var(dp, name)); dp++; }); - addPrimitive("val:", () -> { String name = word(); dict.add(new Val(name, stack.pop())); }); - addPrimitive("abort", () -> { throw new Aborted(stack.pop().asStr().value()); }); - addPrimitive("exec", () -> { - rstack.push(new Num(ip)); - innerLoop(pop().intValue()); - ip = rstack.pop().intValue(); - }); - addPrimitive("create", () -> dict.add(new ColonDef(dp, (String)stack.pop().value()))); - addPrimitive("dasm", this::disassemble); - addPrimitive(":", () -> { - lastWord = new ColonDef(dp, word()); - dict.add(lastWord); - mode = Mode.COMPILE; - }); - addPrimitive(";", () -> { - heap[dp++] = dict.at(EXIT); - heap[dp++] = Nil.INSTANCE; - mode = Mode.INTERPRET; - lastWord.visible(true); - }); - } - - private LogicOperand lOp(Obj obj) { - try { - return (LogicOperand) obj; - } catch (ClassCastException e) { - throw new TypeMismatched(obj + " cannot do logic operators on " + obj); - } - } - - private ArithmeticOperand aOp(Obj obj) { - try { - return (ArithmeticOperand) obj; - } catch (ClassCastException e) { - throw new TypeMismatched(obj + " cannot do arithmetic"); - } - } - - private void show(Obj pop) { - transcript.show(pop.asStr().value()); - transcript.cr(); - } - - private void disassemble() { - String name = (String) stack.pop().value(); - Word word = dict.at(name); - if (word instanceof ColonDef) { - int address = ((ColonDef)word).address; - while (true) { - transcript.show(String.format("[%08X] %s", address, heap[address])); - transcript.cr(); - if (heap[address] instanceof Word && ((Word)heap[address]).name().equals(EXIT) - && heap[address+1] == Nil.INSTANCE) { - break; - } - address++; - } - } else { - System.err.println("Not colon def: " + word); - } - } - - private void sortDsc() { - stack.sortDsc(); - } - - private void sortAsc() { - stack.sortAsc(); - } - - private void reverse() { - stack.reverse(); - } - - private void addPrimitive(String name, Runnable code) { - dict.add(new Primitive(name, code)); - } - - public void eval(String source) { - eval(new StringReader(source)); - } - - public void eval(Reader reader) { - this.reader = reader; - String token = word(); - while (!token.isEmpty()) { - onTokenFound(token); - token = word(); - } - } - - /** - * Compile a temporary word into the scratch area and call it. - * This is useful for evaluating words without interpretation semantics. - * Like: if else then, loops, quotations - */ - public void compileTmpAndEval(String script) { - int savedDp = dp; - Mode savedMode = mode; - try { - dp = heap.length - SCRATCH_SIZE; - mode = Mode.COMPILE; - eval(script); - eval(";"); - mode = Mode.INTERPRET; - innerLoop(heap.length - SCRATCH_SIZE); - } finally { - dp = savedDp; - mode = savedMode; - } - } - - private String word() { - StringBuilder token = new StringBuilder(); - int key = key(); - while (key != -1) { - char chr = (char) key; - if (Character.isWhitespace(chr)) { - if (token.length() > 0) - return token.toString(); - token.setLength(0); - } else { - token.append(chr); - } - key = key(); - } - return token.toString(); - } - - private int key() { - try { - return reader.read(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void onTokenFound(String name) { - Word word = dict.at(name); - switch (mode) { - case INTERPRET: - if (word != null) - word.enter(); - else - stack.push(recognize(name)); - break; - case COMPILE: - if (word != null) { - if (dict.isImmediate(name)) - word.enter(); - else - heap[dp++] = word; - } else { - heap[dp++] = dict.at("lit"); - heap[dp++] = recognize(name); - } - break; - } - } - - private Obj recognize(String token) { - Obj str = recognizeStr(token); - if (str != null) return str; - return Num.parse(token); - } - - private Obj recognizeStr(String firstToken) { - if (!firstToken.startsWith("'")) return null; - StringBuilder str = new StringBuilder(firstToken.substring(1)); - if (firstToken.endsWith("'") && firstToken.length() > 1) { - str.setLength(str.length() - 1); - } else { - str.append(" "); - int k = key(); - while (k != -1 && (char) k != '\'') { - str.append((char) k); - k = key(); - } - } - return new Str(str.toString()); - } - - private void innerLoop(int address) { - ip = address; - Word word = (Word) heap[ip++]; - while (!EXIT.equals(word.name())) { - word.enter(); - word = (Word) heap[ip++]; - } - } - - public Word get(String name) { - return dict.at(name); - } - - public Obj pop() { - return stack.pop(); - } - - public int stackSize() { - return stack.size(); - } - - public int rStackSize() { - return rstack.size(); - } - - public void switchStack(FclStack stack) { - this.stack.switchStack(stack); - } - - public void reset() { - mode = Mode.INTERPRET; - stack.clean(); - rstack.clean(); - } - - public Set wordList() { - return dict.wordList(); - } -} \ No newline at end of file diff --git a/FclStack.java b/FclStack.java deleted file mode 100644 index 9a8b6c0..0000000 --- a/FclStack.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.vectron.fcl; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.vectron.forthcalc.domain.ports.FileStore; -import com.vectron.fcl.types.Obj; -import com.vectron.forthcalc.support.FclTypeAdapter; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Stack; - -public class FclStack { - private static final Gson gson; - private final Stack stack = new Stack<>(); - - static { - FclTypeAdapter typeAdapter = new FclTypeAdapter(); - gson = new GsonBuilder() - .registerTypeAdapter(Obj.class, typeAdapter) - .setLenient() - .serializeSpecialFloatingPointValues() - .create(); - typeAdapter.setGSon(gson); - } - - public void push(Obj obj) { - stack.push(obj); - } - - public Obj pop() { - return stack.pop(); - } - - public Obj peek() { - return stack.peek(); - } - - public boolean empty() { - return stack.empty(); - } - - public void clean() { - stack.clear(); - } - - public int size() { - return stack.size(); - } - - public Obj at(int index) { - return stack.get(stack.size() - index -1); - } - - public void switchStack(FclStack other) { - List copy = new ArrayList<>(other.stack); - other.stack.clear(); - other.stack.addAll(this.stack); - this.stack.clear(); - this.stack.addAll(copy); - } - - public void sortDsc() { - Collections.sort(stack, (o1, o2) -> o1.compareTo(o2)); - } - - public void sortAsc() { - Collections.sort(stack, (o1, o2) -> o2.compareTo(o1)); - } - - public void reverse() { - Collections.reverse(stack); - } - - public void load(FileStore fileStore, String id) { - FileInputStream stream = null; - try { - stream = fileStore.open(fileName(id)); - Obj[] loaded = gson.fromJson(new BufferedReader(new InputStreamReader(stream)), Obj[].class); - stack.clear(); - for (Obj each : loaded) - stack.add(each); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } - - public void save(FileStore fileStore, String id) { - fileStore.save(gson.toJson(stack.toArray(new Obj[0])).getBytes(), fileName(id)); - } - - private String fileName(String id) { - return String.format("stack%s.json", id); - } -} diff --git a/RamTranscript.java b/RamTranscript.java deleted file mode 100644 index 330053e..0000000 --- a/RamTranscript.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.vectron.fcl; - -public class RamTranscript implements Transcript { - private final StringBuilder content = new StringBuilder(); - - @Override - public void show(String str) { - content.append(str); - } - - @Override - public void cr() { - content.append("\n"); - } - - public String content() { - return content.toString(); - } -} diff --git a/Transcript.java b/Transcript.java deleted file mode 100644 index f4d9bda..0000000 --- a/Transcript.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.vectron.fcl; - -public interface Transcript { - void show(String str); - void cr(); - - Transcript STDOUT = new Transcript() { - public void show(String str) { - System.out.print(str); - } - - @Override - public void cr() { - System.out.println(""); - } - }; -} diff --git a/exceptions/Aborted.java b/exceptions/Aborted.java deleted file mode 100644 index e0d9be8..0000000 --- a/exceptions/Aborted.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.vectron.fcl.exceptions; - -public class Aborted extends FclException { - public Aborted(String str) { - super(str); - } -} diff --git a/exceptions/FclException.java b/exceptions/FclException.java deleted file mode 100644 index fac912d..0000000 --- a/exceptions/FclException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.vectron.fcl.exceptions; - -public class FclException extends RuntimeException { - public FclException(String message) { - super(message); - } - - public FclException(Throwable cause) { - super(cause); - } -} diff --git a/exceptions/InterOpFailed.java b/exceptions/InterOpFailed.java deleted file mode 100644 index d7da7f0..0000000 --- a/exceptions/InterOpFailed.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.vectron.fcl.exceptions; - -public class InterOpFailed extends FclException { - public InterOpFailed(Exception e) { - super(e); - } - - public InterOpFailed(String message) { - super(message); - } -} diff --git a/exceptions/NotUnderstood.java b/exceptions/NotUnderstood.java deleted file mode 100644 index 04859aa..0000000 --- a/exceptions/NotUnderstood.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.vectron.fcl.exceptions; - -public class NotUnderstood extends FclException { - public NotUnderstood(String message) { - super(message); - } -} diff --git a/exceptions/TypeMismatched.java b/exceptions/TypeMismatched.java deleted file mode 100644 index d52a144..0000000 --- a/exceptions/TypeMismatched.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.vectron.fcl.exceptions; - -import com.vectron.fcl.types.Obj; - -public class TypeMismatched extends FclException { - public TypeMismatched(String operator, Obj a, Obj b) { - super(String.format("Unsupported types for %s: %s and %s", operator, a, b)); - } - - public TypeMismatched(String operator, Obj a) { - super(String.format("Unsupported types for %s: %s", operator, a)); - } - - public TypeMismatched(Obj obj, String type) { - super(obj + " (" + obj.getClass().getSimpleName() + ") is not convertible to " + type); - } - - public TypeMismatched(String message) { - super(message); - } -} diff --git a/interop/JvmInterOp.java b/interop/JvmInterOp.java deleted file mode 100644 index c9dc318..0000000 --- a/interop/JvmInterOp.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.vectron.fcl.interop; - -import com.vectron.fcl.FclStack; -import com.vectron.fcl.exceptions.InterOpFailed; -import com.vectron.fcl.types.JvmObj; -import com.vectron.fcl.types.Obj; - -import java.util.Random; - -import static com.vectron.fcl.interop.MethodSpec.processResult; - -public class JvmInterOp { - private static final Random RND = new Random(); - private final FclStack stack; - - public JvmInterOp(FclStack stack) { - this.stack = stack; - } - - public void jvmCallStatic() { - MethodSpec spec = MethodSpec.parseStatic(stack.pop().asStr().value()); - spec.invoke(stack); - } - - public void jvmCallMethod() { - String methodName = stack.pop().asStr().value(); - Obj receiver = stack.pop(); - MethodSpec spec = MethodSpec.parseDynamic( - methodName, - receiver instanceof JvmObj ? ((JvmObj) receiver).value() : receiver); - spec.invoke(stack); - } - - public void jvmStaticVar() { - String spec = stack.pop().asStr().value(); - String[] parts = spec.split("/"); - String className = parts[0]; - String varName = parts[1]; - try { - Class clazz = Class.forName(className); - processResult(clazz.getDeclaredField(varName).get(null), stack); - } catch (ReflectiveOperationException e) { - throw new InterOpFailed(e); - } - } - - public static double random() { - return RND.nextDouble(); - } -} diff --git a/interop/MethodSpec.java b/interop/MethodSpec.java deleted file mode 100644 index 00c8295..0000000 --- a/interop/MethodSpec.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.vectron.fcl.interop; - -import com.vectron.fcl.FclStack; -import com.vectron.fcl.exceptions.InterOpFailed; -import com.vectron.fcl.types.Bool; -import com.vectron.fcl.types.JvmObj; -import com.vectron.fcl.types.Nil; -import com.vectron.fcl.types.Num; -import com.vectron.fcl.types.Obj; -import com.vectron.fcl.types.Str; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -class MethodSpec { - private final Class clazz; - private final Object receiver; - private final String methodName; - private final int arity; - private final String typeSpec; - - public static MethodSpec parseStatic(String spec) { - String[] parts = spec.split("/"); - try { - return new MethodSpec(Class.forName(parts[0]), null, parts[1], typeSpec(parts, 2)); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - public static MethodSpec parseDynamic(String spec, Object receiver) { - String[] parts = spec.split("/"); - return new MethodSpec(receiver.getClass(), receiver, parts[0], typeSpec(parts, 1)); - } - - private static String typeSpec(String[] parts, int index) { - String types = ""; - if (parts.length > index) { - types = parts[index]; - } - return types; - } - - private MethodSpec(Class clazz, Object receiver, String methodName, String typeSpec) { - this.clazz = clazz; - this.receiver = receiver; - this.methodName = methodName; - this.arity = typeSpec.length(); - this.typeSpec = typeSpec; - } - - public void invoke(FclStack stack) { - List params = new ArrayList<>(); - List> types = new ArrayList<>(); - for (int i = 0; i < arity; i++) { - Obj value = stack.pop(); - Class clazz = typeOf(typeSpec.charAt(i)); - addParam(params, value, clazz); - types.add(clazz); - } - try { - Method method = clazz.getMethod(methodName, types.toArray(new Class[0])); - method.setAccessible(true); - Object result = method.invoke(receiver, params.toArray(new Object[0])); - if (!method.getReturnType().getSimpleName().equals("void")) - processResult(result, stack); - } catch (ReflectiveOperationException e) { - throw new InterOpFailed(e); - } - } - - public static void processResult(Object result, FclStack stack) { - if (result != null) { - if (result instanceof Number) - stack.push(new Num((Number) result)); - else if (result instanceof String) - stack.push(new Str((String) result)); - else if (result instanceof Boolean) - stack.push((boolean)result ? Bool.TRUE : Bool.FALSE); - else if (result instanceof Obj) - stack.push((Obj)result); - else - stack.push(new JvmObj(result)); - } else { - stack.push(Nil.INSTANCE); - } - } - - private void addParam(List params, Obj value, Class clazz) { - if (clazz == Integer.TYPE) - params.add(value.intValue()); - else if (clazz == Long.TYPE) - params.add(value.longValue()); - else if (clazz == Double.TYPE) - params.add(value.doubleValue()); - else if (clazz == String.class) - params.add((String)value.value()); - else if (clazz == Map.class) - params.add((Map)value.value()); - else if (clazz == List.class) - params.add((List)value.value()); - else if (clazz == Obj.class) - params.add(value); - else - throw new InterOpFailed("Unsupported inter-op type: " + clazz); - } - - private Class typeOf(Character type) { - switch (type) { - case 'i': return Integer.TYPE; - case 'd': return Double.TYPE; - case 'l': return Long.TYPE; - case 's': return String.class; - case 'm': return Map.class; - case 't': return List.class; - case 'O': return Obj.class; - default: - throw new InterOpFailed("Invalid type spec: " + type); - } - } -} diff --git a/types/ArithmeticOperand.java b/types/ArithmeticOperand.java deleted file mode 100644 index 3c01656..0000000 --- a/types/ArithmeticOperand.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.vectron.fcl.types; - -public interface ArithmeticOperand { - Obj add(Obj other); - Obj sub(Obj other); - Obj mul(Obj other); - Obj div(Obj other); -} diff --git a/types/Bool.java b/types/Bool.java deleted file mode 100644 index 83dc4c9..0000000 --- a/types/Bool.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.util.Objects; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Bool implements Obj, LogicOperand { - public static final Bool TRUE = new Bool(true); - public static final Bool FALSE = new Bool(false); - private final boolean value; - - private Bool(boolean value) { - this.value = value; - } - - public Bool and(Obj other) { - return new Bool(value && other.boolValue()); - } - - public Bool or(Obj other) { - return new Bool(value || other.boolValue()); - } - - public Bool not() { - return new Bool(!value); - } - - @Override - public boolean boolValue() { - return value; - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return value ? Num.ONE : Num.ZERO; - } - - @Override - public Object value() { - return value; - } - - @Override - public long longValue() { - if (STRICT) throw new TypeMismatched(this, "long"); - return value ? 1l : 0l; - } - - @Override - public int intValue() { - if (STRICT) throw new TypeMismatched(this, "int"); - return value ? 1 : 0; - } - - @Override - public double doubleValue() { - if (STRICT) throw new TypeMismatched(this, "double"); - return value ? 1.0 : 0.0; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public String toString() { - return value ? "true" : "false"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Bool bool = (Bool) o; - return value == bool.value; - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public int compareTo(Obj o) { - if (o instanceof Bool) - return Boolean.compare(value, o.boolValue()); - else - return -1; - } -} diff --git a/types/Dic.java b/types/Dic.java deleted file mode 100644 index 174cc3b..0000000 --- a/types/Dic.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Dic implements Obj { - private final Map value = new LinkedHashMap<>(); - - public static Dic empty() { - return new Dic(); - } - - @Override - public long longValue() { - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return value; - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - public Iterator iterator() { - return new Iterator() { - private Iterator> it = value.entrySet().iterator(); - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public Lst next() { - Map.Entry next = it.next(); - Lst result = Lst.empty(); - result.append(next.getKey()); - result.append(next.getValue()); - return result; - } - }; - } - - public int size() { - return value.size(); - } - - public void put(Obj key, Obj value) { - this.value.put(key, value); - } - - public Obj at(Obj key) { - return value.get(key); - } - - public void remove(Obj item) { - value.remove(item); - } - - public Lst keys() { - Lst result = Lst.empty(); - for (Obj each : value.keySet()) - result.append(each); - return result; - } - - public Lst values() { - Lst result = Lst.empty(); - for (Obj each : value.values()) - result.append(each); - return result; - } - - public void clear() { - value.clear(); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder("#[ "); - int i = 0; - for (Map.Entry each : value.entrySet()) { - result.append(each.getKey()); - result.append(" "); - result.append(each.getValue()); - if (i < value.size() -1) result.append(" "); i++; - } - result.append(" ]#"); - return result.toString(); - } -} diff --git a/types/JvmObj.java b/types/JvmObj.java deleted file mode 100644 index d0c3d3a..0000000 --- a/types/JvmObj.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import static com.vectron.fcl.Fcl.STRICT; - -public class JvmObj implements Obj { - private final Object object; - - public JvmObj(Object object) { - this.object = object; - } - - @Override - public long longValue() { - if (object instanceof Number) - return ((Number)object).longValue(); - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - if (object instanceof Number) - return ((Number)object).intValue(); - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - if (object instanceof Number) - return ((Number)object).doubleValue(); - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - if (object instanceof Boolean) - return (boolean) object; - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (object instanceof Number) - return new Num((Number)object); - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return object; - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - @Override - public String toString() { - return "JvmObj:" + object; - } -} diff --git a/types/LogicOperand.java b/types/LogicOperand.java deleted file mode 100644 index 1bc0b1e..0000000 --- a/types/LogicOperand.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.vectron.fcl.types; - -public interface LogicOperand { - Obj and(Obj other); - Obj or(Obj other); - Obj not(); -} diff --git a/types/Lst.java b/types/Lst.java deleted file mode 100644 index 3b7d015..0000000 --- a/types/Lst.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Lst implements Obj, ArithmeticOperand { - private final List value = new ArrayList<>(); - - public static Lst empty() { - return new Lst(); - } - - @Override - public long longValue() { - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Object value() { - return value; - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - public int size() { - return value.size(); - } - - public void append(Obj value) { - this.value.add(value); - } - - public void prep(Obj value) { - this.value.add(0, value); - } - - public Obj at(Obj index) { - return value.get(index.intValue()); - } - - public int indexOf(Obj item) { - return value.indexOf(item); - } - - public Lst concat(Obj other) { - Lst result = Lst.empty(); - result.value.addAll(value); - result.value.addAll((List)other.value()); - return result; - } - - public Lst subList(int start, int stop) { - Lst result = Lst.empty(); - result.value.addAll(value.subList(start, stop)); - return result; - } - - public void remove(Obj item) { - value.remove(item); - } - - public void removeAt(int index) { - value.remove(index); - } - - public void clear() { - value.clear(); - } - - public Iterator iterator() { - return value.iterator(); - } - - public Lst reverse() { - Lst result = Lst.empty(); - for (int i = value.size() - 1; i >= 0; i--) - result.append(value.get(i)); - return result; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder("[ "); - for (int i = 0; i < value.size(); i++) { - Obj each = value.get(i); - result.append(each); - if (i < value.size() -1) result.append(" "); - } - result.append(" ]"); - return result.toString(); - } - - @Override - public Lst add(Obj other) { - if (other instanceof Num) { - Lst result = Lst.empty(); - for (Obj each : value) - result.append(each.asNum().add(other)); - return result; - } else { - throw new TypeMismatched("+", this, other); - } - } - - @Override - public Lst sub(Obj other) { - if (other instanceof Num) { - Lst result = Lst.empty(); - for (Obj each : value) - result.append(each.asNum().sub(other)); - return result; - } else { - throw new TypeMismatched("-", this, other); - } - } - - @Override - public Lst mul(Obj other) { - if (other instanceof Num) { - Lst result = Lst.empty(); - for (Obj each : value) - result.append(each.asNum().mul(other)); - return result; - } else { - throw new TypeMismatched("*", this, other); - } - } - - @Override - public Lst div(Obj other) { - if (other instanceof Num) { - Lst result = Lst.empty(); - for (Obj each : value) - result.append(each.asNum().div(other)); - return result; - } else { - throw new TypeMismatched("/", this, other); - } - } -} diff --git a/types/Nil.java b/types/Nil.java deleted file mode 100644 index 373b0db..0000000 --- a/types/Nil.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Nil implements Obj { - public static final Nil INSTANCE = new Nil(); - - private Nil() {} - - @Override - public long longValue() { - if (STRICT) throw new TypeMismatched(this, "long"); - return 0l; - } - - @Override - public int intValue() { - if (STRICT) throw new TypeMismatched(this, "int"); - return 0; - } - - @Override - public double doubleValue() { - if (STRICT) throw new TypeMismatched(this, "double"); - return 0.0; - } - - @Override - public boolean boolValue() { - if (STRICT) throw new TypeMismatched(this, "bool"); - return false; - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.ZERO; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return null; - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - @Override - public String toString() { - return "nil"; - } -} diff --git a/types/Num.java b/types/Num.java deleted file mode 100644 index 89e2c52..0000000 --- a/types/Num.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.NotUnderstood; -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.text.NumberFormat; -import java.util.Objects; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Num implements Obj, LogicOperand, ArithmeticOperand { - public static final Num ZERO = new Num(0); - public static final Num ONE = new Num(1); - public static final Num NAN = new Num(Double.NaN); - private static final NumberFormat format = NumberFormat.getNumberInstance(); - private final Number value; - - static { - format.setMaximumFractionDigits(4); - format.setGroupingUsed(false); - format.setParseIntegerOnly(false); - } - - public Num(Number value) { - if (value instanceof Integer) - this.value = ((Integer)value).longValue(); - else - this.value = value; - } - - public static Num parse(String str) { - try { - return new Num(Long.parseLong(str)); - } catch (NumberFormatException e1) { - try { - return new Num(Double.parseDouble(str)); - } catch (NumberFormatException e2) { - throw new NotUnderstood("Undefined word: " + str); - } - } - } - - @Override - public String toString() { - if (value instanceof Long) { - return Long.toString((Long) value); - } else if (value instanceof Double) { - return format.format(value); - } - return value.toString(); - } - - @Override - public Obj add(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num((Long) value + (Long)other.value()); - else if (value instanceof Long && other.value() instanceof Double) - return new Num((Long) value + (Double)other.value()); - else if (value instanceof Double && other.value() instanceof Long) - return new Num((Double) value + (Long)other.value()); - else if (value instanceof Double && other.value() instanceof Double) - return new Num((Double) value + (Double) other.value()); - else if (other instanceof Lst) - return ((Lst) other).add(this); - else if (STRICT) - throw new TypeMismatched("+", this, other); - return Num.NAN; - } - - @Override - public Obj sub(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num((Long) value - (Long)other.value()); - else if (value instanceof Long && other.value() instanceof Double) - return new Num((Long) value - (Double)other.value()); - else if (value instanceof Double && other.value() instanceof Long) - return new Num((Double) value - (Long)other.value()); - else if (value instanceof Double && other.value() instanceof Double) - return new Num((Double) value - (Double) other.value()); - else if (STRICT) - throw new TypeMismatched("-", this, other); - return Num.NAN; - } - - @Override - public Obj mul(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num((Long) value * (Long)other.value()); - else if (value instanceof Long && other.value() instanceof Double) - return new Num((Long) value * (Double)other.value()); - else if (value instanceof Double && other.value() instanceof Long) - return new Num((Double) value * (Long)other.value()); - else if (value instanceof Double && other.value() instanceof Double) - return new Num((Double) value * (Double) other.value()); - else if (other instanceof Lst) - return ((Lst) other).mul(this); - else if (other instanceof Str) - return ((Str) other).mul(this); - else if (STRICT) - throw new TypeMismatched("*", this, other); - return Num.NAN; - } - - @Override - public Obj div(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num(((Long) value).doubleValue() / (Long) other.value()); - else if (value instanceof Long && other.value() instanceof Double) - return new Num((Long) value / (Double)other.value()); - else if (value instanceof Double && other.value() instanceof Long) - return new Num((Double) value / (Long)other.value()); - else if (value instanceof Double && other.value() instanceof Double) - return new Num((Double) value / (Double) other.value()); - else if (STRICT) - throw new TypeMismatched("/", this, other); - return Num.NAN; - } - - public Num power(Num exponent) { - if (value instanceof Long && exponent.value instanceof Long) - return new Num(Math.pow(((Long) value).doubleValue(), ((Long) exponent.value).doubleValue())); - else if (value instanceof Long && exponent.value instanceof Double) - return new Num(Math.pow(((Long) value).doubleValue(), exponent.doubleValue())); - else if (value instanceof Double && exponent.value instanceof Long) - return new Num(Math.pow((Double)value, ((Long) exponent.value).doubleValue())); - else if (value instanceof Double && exponent.value instanceof Double) - return new Num(Math.pow((Double)value, exponent.doubleValue())); - else if (STRICT) - throw new TypeMismatched("POW", this, exponent); - return Num.NAN; - } - - public Num mod(Num other) { - try { - return new Num(this.longValue() % other.longValue()); - } catch (TypeMismatched e) { - if (STRICT) throw e; - return Num.NAN; - } - } - - public Num intDiv(Num other) { - try { - return new Num(this.longValue() / other.longValue()); - } catch (TypeMismatched e) { - if (STRICT) throw e; - return Num.NAN; - } - } - - public Num round() { - if (value instanceof Long) - return this; - else if (value instanceof Double) - return new Num(Math.round(doubleValue())); - else if (STRICT) - throw new TypeMismatched("ROUND", this); - return Num.NAN; - } - - @Override - public Num and(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num((Long)value & other.longValue()); - else if (STRICT) - throw new TypeMismatched("AND", this, other); - return Num.NAN; - } - - @Override - public Num or(Obj other) { - if (value instanceof Long && other.value() instanceof Long) - return new Num((Long)value | other.longValue()); - else if (STRICT) - throw new TypeMismatched("OR", this, other); - return Num.NAN; - } - - @Override - public Num not() { - if (value instanceof Long) - return new Num(~(Long)value ); - else if (STRICT) - throw new TypeMismatched("Unsupported types for NOT operator: " + value.getClass()); - return Num.NAN; - } - - public Bool greater(Num other) { - if (value instanceof Long && other.value instanceof Long) - return (Long) value > (Long)other.value ? Bool.TRUE : Bool.FALSE; - else if (value instanceof Long && other.value instanceof Double) - return (Long) value > (Double)other.value ? Bool.TRUE : Bool.FALSE; - else if (value instanceof Double && other.value instanceof Long) - return (Double) value > (Long)other.value ? Bool.TRUE : Bool.FALSE; - else if (value instanceof Double && other.value instanceof Double) - return (Double) value > (Double) other.value ? Bool.TRUE : Bool.FALSE; - else - throw new TypeMismatched("<", this, other); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Num num = (Num) o; - return value.equals(num.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public long longValue() { - if (value instanceof Long) - return (Long) value; - else if (value instanceof Double) - return Math.round((Double) value); - else - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - return ((Number)value).intValue(); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - return this; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public double doubleValue() { - return ((Number)value).doubleValue(); - } - - @Override - public Object value() { - return value; - } - - @Override - public int compareTo(Obj other) { - return other instanceof Num - ? Double.compare(doubleValue(), ((Num) other).doubleValue()) - : -1; - } -} diff --git a/types/Obj.java b/types/Obj.java deleted file mode 100644 index a483ef8..0000000 --- a/types/Obj.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.vectron.fcl.types; - -public interface Obj extends Comparable { - long longValue(); - int intValue(); - double doubleValue(); - boolean boolValue(); - Num asNum(); - Str asStr(); - Object value(); -} \ No newline at end of file diff --git a/types/Primitive.java b/types/Primitive.java deleted file mode 100644 index 3fac79d..0000000 --- a/types/Primitive.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Primitive implements Word { - private final Runnable code; - private final String name; - private boolean visible = true; - - public Primitive(String name, Runnable code) { - this.code = code; - this.name = name; - } - - @Override - public void visible(boolean isVisible) { - this.visible = isVisible; - } - - @Override - public boolean visible() { - return visible; - } - - @Override - public void enter() { - code.run(); - } - - @Override - public String name() { - return name; - } - - @Override - public long longValue() { - throw new TypeMismatched(this,"long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this,"int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public Object value() { - return code; - } - - @Override - public String toString() { - return "xt_" + name; - } - - @Override - public int compareTo(Obj other) { - return other instanceof Primitive - ? name.compareTo(((Primitive) other).name) - : -1; - } -} diff --git a/types/Quot.java b/types/Quot.java deleted file mode 100644 index 3b9b5f6..0000000 --- a/types/Quot.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Quot implements Obj { - private final int address; - private final int stackFrame; - - public static Quot create(int stackFrame, int address) { - return new Quot(stackFrame, address); - } - - public Quot(int stackFrame, int address) { - this.address = address; - this.stackFrame = stackFrame; - } - - public Num address() { - return new Num(address); - } - - public Num stackFrame() { - return new Num(stackFrame); - } - - @Override - public long longValue() { - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Object value() { - throw new TypeMismatched(this, "value"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - @Override - public String toString() { - return "Quotation: " + address + ", " + stackFrame; - } -} diff --git a/types/Range.java b/types/Range.java deleted file mode 100644 index 0c888d7..0000000 --- a/types/Range.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.InterOpFailed; -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.util.Iterator; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Range implements Obj { - private RangeIterator iterator; - private final int from; - private final int to; - private final int by; - private int current; - - public static Range create(int by, int to, int from) { - return new Range(from, to, by); - } - - private Range(int from, int to, int by) { - if (by == 0) - throw new InterOpFailed("Invalid increment for range: " + by); - this.from = from; - this.to = to; - this.by = by; - this.current = from; - } - - @Override - public long longValue() { - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.NAN; - } - - @Override - public Str asStr() { - return new Str(toString()); - } - - public Iterator iterator() { - if (iterator == null) - iterator = new RangeIterator(); - return iterator; - } - - @Override - public String toString() { - return by == 1 - ? String.format("%d..%d (%d)", from, to, current) - : String.format("%d...%d (%d) by %d", from, to, current, by); - } - - @Override - public Object value() { - return iterator; - } - - @Override - public int compareTo(Obj o) { - return -1; - } - - public class RangeIterator implements Iterator { - @Override - public boolean hasNext() { - return by > 0 ? current <= to : current >= to; - } - - @Override - public Obj next() { - Num result = new Num(current); - current += by; - return result; - } - } -} diff --git a/types/Str.java b/types/Str.java deleted file mode 100644 index e9bae85..0000000 --- a/types/Str.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.vectron.fcl.types; - -import com.vectron.fcl.exceptions.TypeMismatched; - -import java.util.Iterator; -import java.util.List; -import java.util.Objects; - -import static com.vectron.fcl.Fcl.STRICT; - -public class Str implements Obj, ArithmeticOperand { - private final String value; - - public Str(String value) { - this.value = value; - } - - @Override - public long longValue() { - throw new TypeMismatched(this, "long"); - } - - @Override - public int intValue() { - throw new TypeMismatched(this, "int"); - } - - @Override - public double doubleValue() { - throw new TypeMismatched(this, "double"); - } - - @Override - public boolean boolValue() { - throw new TypeMismatched(this, "bool"); - } - - @Override - public String value() { - return value; - } - - @Override - public Num asNum() { - if (STRICT) throw new TypeMismatched(this, "num"); - return Num.parse(value); - } - - @Override - public Str asStr() { - return this; - } - - @Override - public String toString() { - return "'" + value + "'"; - } - - public Str substr(int from, int to) { - return new Str(value.substring(from, to)); - } - - public int size() { - return value.length(); - } - - public Str at(Obj index) { - return new Str(Character.toString(value.charAt(index.intValue()))); - } - - public Lst split(String delimiter) { - Lst result = Lst.empty(); - for (String each : value.split(delimiter)) - result.append(new Str(each)); - return result; - } - - public Str upper() { - return new Str(value.toUpperCase()); - } - - public Str lower() { - return new Str(value.toLowerCase()); - } - - public Str trim() { - return new Str(value.trim()); - } - - public int indexOf(Obj s) { - return value.indexOf((String)s.value()); - } - - public Str replace(String olds, String news) { - return new Str(value.replaceAll(olds, news)); - } - - public Str concat(Obj str) { - return new Str(value + (String)str.value()); - } - - public Str reverse() { - return new Str(new StringBuilder(value).reverse().toString()); - } - - public Iterator iterator() { - return new Iterator() { - private int index = 0; - @Override - public boolean hasNext() { - return index < value.length(); - } - - @Override - public Str next() { - return new Str(Character.toString(value.charAt(index++))); - } - }; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Str str = (Str) o; - return value.equals(str.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public int compareTo(Obj other) { - return other instanceof Str - ? value.compareTo(((Str) other).value) - : -1; - } - - public Str format(List params) { - Object[] a = new Object[params.size()]; - for (int i = 0; i < params.size(); i++) { - a[i] = params.get(i).value(); - } - return new Str(String.format(value, a)); - } - - @Override - public Obj add(Obj other) { - throw new TypeMismatched("+", this, other); - } - - @Override - public Obj sub(Obj other) { - throw new TypeMismatched("+", this, other); - } - - @Override - public Obj mul(Obj other) { - if (other instanceof Num) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < other.intValue(); i++) { - result.append(value); - } - return new Str(result.toString()); - } - throw new TypeMismatched("*", this, other); - } - - @Override - public Obj div(Obj other) { - throw new TypeMismatched("+", this, other); - } -} diff --git a/types/Word.java b/types/Word.java deleted file mode 100644 index 4c388c1..0000000 --- a/types/Word.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.vectron.fcl.types; - -public interface Word extends Obj { - void enter(); - String name(); - void visible(boolean isVisible); - boolean visible(); -}