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.Primitive;
import com.vectron.fcl.types.Str;
import com.vectron.fcl.types.Symbol;
import com.vectron.fcl.types.Word;
import java.io.IOException;
@ -18,7 +19,9 @@ import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Fcl {
@ -35,6 +38,7 @@ public class Fcl {
private Reader reader;
private Mode mode = Mode.INTERPRET;
private final Object[] heap;
private final Map<String, Symbol> symbols = new HashMap<>();
private int dp = SCRATCH_SIZE;
private int ip = 0;
private boolean trace = false;
@ -567,13 +571,15 @@ public class Fcl {
private Obj recognize(String token) {
Obj str = recognizeStr(token);
if (str != null) return str;
Obj symbol = recognizeSymbol(token);
if (symbol != null) return symbol;
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) {
private Obj recognizeStr(String token) {
if (!token.startsWith("'")) return null;
StringBuilder str = new StringBuilder(token.substring(1));
if (token.endsWith("'") && token.length() > 1) {
str.setLength(str.length() - 1);
} else {
str.append(" ");
@ -586,6 +592,18 @@ public class Fcl {
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) {
ip = address;
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.Range;
import com.vectron.fcl.types.Str;
import com.vectron.fcl.types.Symbol;
import java.util.HashMap;
import java.util.Map;
@ -32,6 +33,7 @@ public class FclTypeAdapter extends TypeAdapter<Object> {
register("bool", Bool.class);
register("str", Str.class);
register("dic", Dic.class);
register("sym", Symbol.class);
register("lst", Lst.class);
register("nil", Nil.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());
}
@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() {
return transcript.content();
}