package table import function.LispFunction import sexpression.Cons import sexpression.Nil.NIL import sexpression.SExpression import table.SymbolTable.NullSymbolTable import java.util.Stack object ExecutionContext { private val functionCalls: Stack = Stack() var scope: SymbolTable = SymbolTable(NullSymbolTable) var isRecur: Boolean = false private set val isInFunctionCall: Boolean get() = !functionCalls.empty() val currentFunction: LispFunction get() = functionCalls.peek().lispFunction val isRecurInitializing: Boolean get() = functionCalls.peek().isRecurInitializing fun clearContext() { scope = SymbolTable(NullSymbolTable) functionCalls.clear() clearRecur() } fun restoreGlobalScope() { while (!scope.isGlobal) scope = scope.parent ?: NullSymbolTable } fun lookupSymbolValue(symbolName: String): SExpression? { for (table in scope) if (symbolName in table) return table[symbolName] return null } fun toList(): Cons { var symbols: Cons = NIL for (table in scope) symbols = Cons(table.toList(), symbols) return symbols } fun pushFunctionCall(function: LispFunction) { functionCalls.push(LispFunctionRecurInfo(function)) } fun popFunctionCall() { functionCalls.pop() } fun setRecur() { isRecur = true } fun clearRecur() { isRecur = false } fun setRecurInitializing() { functionCalls.peek().setRecurInitializing() } fun clearRecurInitializing() { functionCalls.peek().clearRecurInitializing() } class LispFunctionRecurInfo(val lispFunction: LispFunction) { var isRecurInitializing: Boolean = false private set fun setRecurInitializing() { isRecurInitializing = true } fun clearRecurInitializing() { isRecurInitializing = false } } }