adding symbols

This commit is contained in:
zeroflag 2021-07-03 21:59:52 +02:00
parent 5ea06380dc
commit 7646436036
4 changed files with 97 additions and 4 deletions

View file

@ -11,6 +11,7 @@ import com.vectron.fcl.types.Num;
import com.vectron.fcl.types.Obj; import com.vectron.fcl.types.Obj;
import com.vectron.fcl.types.Primitive; import com.vectron.fcl.types.Primitive;
import com.vectron.fcl.types.Str; import com.vectron.fcl.types.Str;
import com.vectron.fcl.types.Symbol;
import com.vectron.fcl.types.Word; import com.vectron.fcl.types.Word;
import java.io.IOException; import java.io.IOException;
@ -18,7 +19,9 @@ import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class Fcl { public class Fcl {
@ -35,6 +38,7 @@ public class Fcl {
private Reader reader; private Reader reader;
private Mode mode = Mode.INTERPRET; private Mode mode = Mode.INTERPRET;
private final Object[] heap; private final Object[] heap;
private final Map<String, Symbol> symbols = new HashMap<>();
private int dp = SCRATCH_SIZE; private int dp = SCRATCH_SIZE;
private int ip = 0; private int ip = 0;
private boolean trace = false; private boolean trace = false;
@ -567,13 +571,15 @@ public class Fcl {
private Obj recognize(String token) { private Obj recognize(String token) {
Obj str = recognizeStr(token); Obj str = recognizeStr(token);
if (str != null) return str; if (str != null) return str;
Obj symbol = recognizeSymbol(token);
if (symbol != null) return symbol;
return Num.parse(token); return Num.parse(token);
} }
private Obj recognizeStr(String firstToken) { private Obj recognizeStr(String token) {
if (!firstToken.startsWith("'")) return null; if (!token.startsWith("'")) return null;
StringBuilder str = new StringBuilder(firstToken.substring(1)); StringBuilder str = new StringBuilder(token.substring(1));
if (firstToken.endsWith("'") && firstToken.length() > 1) { if (token.endsWith("'") && token.length() > 1) {
str.setLength(str.length() - 1); str.setLength(str.length() - 1);
} else { } else {
str.append(" "); str.append(" ");
@ -586,6 +592,18 @@ public class Fcl {
return new Str(str.toString()); return new Str(str.toString());
} }
private Obj recognizeSymbol(String token) {
return token.startsWith(":") && token.length() > 1
? symbol(token.substring(1))
: null;
}
private Symbol symbol(String name) {
if (!symbols.containsKey(name))
symbols.put(name, new Symbol(name));
return symbols.get(name);
}
private void innerLoop(int address) { private void innerLoop(int address) {
ip = address; ip = address;
Word word = (Word) heap[ip++]; Word word = (Word) heap[ip++];

View file

@ -17,6 +17,7 @@ import com.vectron.fcl.types.Obj;
import com.vectron.fcl.types.Quot; import com.vectron.fcl.types.Quot;
import com.vectron.fcl.types.Range; import com.vectron.fcl.types.Range;
import com.vectron.fcl.types.Str; import com.vectron.fcl.types.Str;
import com.vectron.fcl.types.Symbol;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -32,6 +33,7 @@ public class FclTypeAdapter extends TypeAdapter<Object> {
register("bool", Bool.class); register("bool", Bool.class);
register("str", Str.class); register("str", Str.class);
register("dic", Dic.class); register("dic", Dic.class);
register("sym", Symbol.class);
register("lst", Lst.class); register("lst", Lst.class);
register("nil", Nil.class); register("nil", Nil.class);
register("quot", Quot.class); register("quot", Quot.class);

View file

@ -0,0 +1,63 @@
package com.vectron.fcl.types;
import com.vectron.fcl.exceptions.TypeMismatched;
public class Symbol implements Obj {
private final String symbol;
public Symbol(String symbol) {
this.symbol = symbol;
}
@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() {
return null;
}
@Override
public Str asStr() {
return new Str(symbol);
}
@Override
public Object value() {
return symbol;
}
@Override
public Object unwrap() {
return symbol;
}
@Override
public String toString() {
return ":" + symbol;
}
@Override
public int compareTo(Obj other) {
return other instanceof Symbol
? symbol.compareTo(((Symbol) other).symbol)
: -1;
}
}

View file

@ -1187,6 +1187,16 @@ public class FclTest {
evalPop("#[ 'headers' #[ 'Content-Type' 'text/plain' ]# 'content' #[ 'a' 1 ]# ]# +json-type").toString()); evalPop("#[ 'headers' #[ 'Content-Type' 'text/plain' ]# 'content' #[ 'a' 1 ]# ]# +json-type").toString());
} }
@Test
public void testSymbols() {
assertEquals(":my-symbol", evalPop(":my-symbol").toString());
assertEquals(true, evalPop(":my-symbol :my-symbol =").boolValue());
assertEquals(false, evalPop(":my-symbol :my-symbol !=").boolValue());
assertEquals(false, evalPop(":my-symbol :my-symbol2 =").boolValue());
assertEquals(true, evalPop(":my-symbol :my-symbol2 !=").boolValue());
assertEquals(true, evalPop(": tst :my-symbol :my-symbol = ; tst").boolValue());
}
private String transcript() { private String transcript() {
return transcript.content(); return transcript.content();
} }