parent
91c4070b53
commit
a2f8086b8e
5
pom.xml
5
pom.xml
|
@ -16,9 +16,8 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<!-- TODO - when everything is converted to kotlin -->
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
<!--<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>-->
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
<!--<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>-->
|
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
package table;
|
|
||||||
|
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
import table.ExecutionContext.NullSymbolTable;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import static function.builtin.cons.APPEND.append;
|
|
||||||
import static function.builtin.cons.LIST.makeList;
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
public class SymbolTable {
|
|
||||||
|
|
||||||
private HashMap<String, SExpression> table;
|
|
||||||
private SymbolTable parent;
|
|
||||||
|
|
||||||
public SymbolTable() {
|
|
||||||
this(NullSymbolTable.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SymbolTable(SymbolTable parent) {
|
|
||||||
this.table = new HashMap<String, SExpression>();
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(String symbolName) {
|
|
||||||
return table.containsKey(symbolName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression get(String symbolName) {
|
|
||||||
return table.get(symbolName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(String symbolName, SExpression value) {
|
|
||||||
table.put(symbolName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SymbolTable getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isGlobal() {
|
|
||||||
return parent == NullSymbolTable.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cons toList() {
|
|
||||||
Cons context = NIL;
|
|
||||||
|
|
||||||
for (Entry<String, SExpression> binding : getSortedBindings())
|
|
||||||
context = append(context, makeList(makeSymbolValuePair(binding)));
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Entry<String, SExpression>> getSortedBindings() {
|
|
||||||
return new TreeMap<>(table).entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cons makeSymbolValuePair(Entry<String, SExpression> binding) {
|
|
||||||
return new Cons(new Symbol(binding.getKey()), makeList(binding.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -125,12 +125,12 @@ public class UserDefinedFunction extends LispFunction {
|
||||||
|
|
||||||
for (String parameter : formalParameters) {
|
for (String parameter : formalParameters) {
|
||||||
SExpression currentArg = argumentList.getFirst();
|
SExpression currentArg = argumentList.getFirst();
|
||||||
executionScope.put(parameter, currentArg);
|
executionScope.set(parameter, currentArg);
|
||||||
argumentList = (Cons) argumentList.getRest();
|
argumentList = (Cons) argumentList.getRest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isKeywordRestPresent)
|
if (isKeywordRestPresent)
|
||||||
executionScope.put(keywordRestParameter, argumentList);
|
executionScope.set(keywordRestParameter, argumentList);
|
||||||
|
|
||||||
return executionScope;
|
return executionScope;
|
||||||
}
|
}
|
|
@ -37,7 +37,7 @@ public class SET extends LispFunction {
|
||||||
SExpression value = rest.getFirst();
|
SExpression value = rest.getFirst();
|
||||||
|
|
||||||
SymbolTable table = findScopeOfSymbol(symbol);
|
SymbolTable table = findScopeOfSymbol(symbol);
|
||||||
table.put(symbol.toString(), value);
|
table.set(symbol.toString(), value);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
|
@ -75,7 +75,7 @@ public class LET extends LispSpecialFunction {
|
||||||
SExpression symbol = symbolValuePair.getFirst();
|
SExpression symbol = symbolValuePair.getFirst();
|
||||||
SExpression value = restOfPair.getFirst();
|
SExpression value = restOfPair.getFirst();
|
||||||
|
|
||||||
scope.put(symbol.toString(), eval(value));
|
scope.set(symbol.toString(), eval(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateBody(Cons body) {
|
private SExpression evaluateBody(Cons body) {
|
|
@ -2,11 +2,10 @@ package table
|
||||||
|
|
||||||
import function.LispFunction
|
import function.LispFunction
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.SExpression
|
|
||||||
|
|
||||||
import java.util.Stack
|
|
||||||
|
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil.NIL
|
||||||
|
import sexpression.SExpression
|
||||||
|
import table.SymbolTable.NullSymbolTable
|
||||||
|
import java.util.Stack
|
||||||
|
|
||||||
object ExecutionContext {
|
object ExecutionContext {
|
||||||
|
|
||||||
|
@ -33,17 +32,13 @@ object ExecutionContext {
|
||||||
|
|
||||||
fun restoreGlobalScope() {
|
fun restoreGlobalScope() {
|
||||||
while (!scope.isGlobal)
|
while (!scope.isGlobal)
|
||||||
scope = scope.parent
|
scope = scope.parent ?: NullSymbolTable
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lookupSymbolValue(symbolName: String): SExpression? {
|
fun lookupSymbolValue(symbolName: String): SExpression? {
|
||||||
var t = scope
|
for (table in scope)
|
||||||
while (t !== NullSymbolTable) {
|
if (symbolName in table)
|
||||||
if (t.contains(symbolName))
|
return table[symbolName]
|
||||||
return t.get(symbolName)
|
|
||||||
|
|
||||||
t = t.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -51,11 +46,8 @@ object ExecutionContext {
|
||||||
fun toList(): Cons {
|
fun toList(): Cons {
|
||||||
var symbols: Cons = NIL
|
var symbols: Cons = NIL
|
||||||
|
|
||||||
var t = scope
|
for (table in scope)
|
||||||
while (t !== NullSymbolTable) {
|
symbols = Cons(table.toList(), symbols)
|
||||||
symbols = Cons(t.toList(), symbols)
|
|
||||||
t = t.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
return symbols
|
return symbols
|
||||||
}
|
}
|
||||||
|
@ -96,6 +88,4 @@ object ExecutionContext {
|
||||||
isRecurInitializing = false
|
isRecurInitializing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object NullSymbolTable : SymbolTable()
|
|
||||||
}
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package table
|
||||||
|
|
||||||
|
import function.builtin.cons.APPEND.append
|
||||||
|
import function.builtin.cons.LIST.makeList
|
||||||
|
import sexpression.Cons
|
||||||
|
import sexpression.Nil.NIL
|
||||||
|
import sexpression.SExpression
|
||||||
|
import sexpression.Symbol
|
||||||
|
import java.util.HashMap
|
||||||
|
import java.util.TreeMap
|
||||||
|
import kotlin.collections.Map.Entry
|
||||||
|
|
||||||
|
open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable<SymbolTable> {
|
||||||
|
|
||||||
|
val isGlobal: Boolean
|
||||||
|
get() = parent === NullSymbolTable
|
||||||
|
|
||||||
|
private val table: HashMap<String, SExpression> = HashMap()
|
||||||
|
|
||||||
|
private val sortedBindings: Set<Entry<String, SExpression>>
|
||||||
|
get() = TreeMap(table).entries
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this)
|
||||||
|
|
||||||
|
operator fun contains(symbolName: String) = table.containsKey(symbolName)
|
||||||
|
|
||||||
|
operator fun get(symbolName: String) = table[symbolName]
|
||||||
|
|
||||||
|
operator fun set(symbolName: String, value: SExpression) {
|
||||||
|
table[symbolName] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toList(): Cons {
|
||||||
|
var context: Cons = NIL
|
||||||
|
|
||||||
|
for (binding in sortedBindings)
|
||||||
|
context = append(context, makeList(makeSymbolValuePair(binding)))
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSymbolValuePair(binding: Entry<String, SExpression>) =
|
||||||
|
Cons(Symbol(binding.key), makeList(binding.value))
|
||||||
|
|
||||||
|
object NullSymbolTable : SymbolTable(null) {
|
||||||
|
override val parent: SymbolTable
|
||||||
|
get() = this
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SymbolTableIterator(private var symbolTable: SymbolTable) : AbstractIterator<SymbolTable>() {
|
||||||
|
override fun computeNext() {
|
||||||
|
when (symbolTable) {
|
||||||
|
is NullSymbolTable -> done()
|
||||||
|
else -> {
|
||||||
|
setNext(symbolTable)
|
||||||
|
symbolTable = symbolTable.parent ?: NullSymbolTable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue