Skip to content

Instantly share code, notes, and snippets.

@XGFan
Created December 14, 2021 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XGFan/74a7a4bdac80ebf0952be7ba070d8531 to your computer and use it in GitHub Desktop.
Save XGFan/74a7a4bdac80ebf0952be7ba070d8531 to your computer and use it in GitHub Desktop.
import java.util.*
import kotlin.collections.ArrayList
fun main(args: Array<String>) {
val tokens = string2Tokens(testArg)
println(tokens)
val structure = tokens2Structure(tokens)
println(structure)
}
val testArg = """
(define apply
(lambda (fun vals)
(cond
((primitive? fun) (apply-primitive (second fun) vals))
((non-primitive? fun) (apply-closure (second fun) vals)))))
""".trimIndent()
typealias Token = String
const val START_TOKEN: Token = "("
const val END_TOKEN: Token = ")"
const val DELIMITER_TOKEN: Token = " "
const val START = '('
const val END = ')'
fun string2Tokens(s: String): List<Token> {
val tokens = ArrayList<Token>()
var buf = ""
s.forEach { c ->
when (c) {
START -> {
tokens.add(START_TOKEN)
}
END -> {
if (!buf.isBlank()) {
tokens.add(buf)
buf = ""
}
tokens.add(END_TOKEN)
}
' ', '\t', '\n', '\r' -> {
if (!buf.isBlank()) {
tokens.add(buf)
buf = ""
}
if (tokens.last() != DELIMITER_TOKEN) {
tokens.add(DELIMITER_TOKEN)
}
}
else -> {
// println("$c,${c.code}")
buf += c
}
}
}
return tokens.filter { it != DELIMITER_TOKEN }
}
fun tokens2Structure(tokens: List<Token>): List<Any> {
var stack = emptyList<Any>()
tokens.forEach { token ->
when (token) {
START_TOKEN -> {
stack = stack + token
}
END_TOKEN -> {
val startIndex = stack.lastIndexOf(START_TOKEN)
if (startIndex == -1) {
throw RuntimeException("")
} else {
val tail = stack.subList(startIndex, stack.size).drop(1)
stack = stack.dropLast(stack.size - startIndex)
stack = stack + (tail as Any)
}
}
else -> {
stack = stack + token
}
}
}
return stack;
}
fun atom2action(expr: String): Any {
val int = expr.toIntOrNull()
if (int != null) {
return _const
}
return when (expr) {
"#t", "#f", "cons", "cdr", "null?", "eq?", "atom", "zero?", "add1", "sub1", "number?" -> _const
else -> _identifier
}
}
fun meaning(expr: Any, table: List<Map<String, Any>>): Any {
val action = expression2action(expr) as (Any, List<Map<String, Any>>) -> Any
return action(expr, table)
}
fun list2action(expr: Any): Any {
val anies = expr as List<*>
if (anies.first() is List<*>) {
return _application
} else {
return when ((anies.first() as String)) {
"quote" -> _quote
"lambda" -> _lambda
"cond" -> _cond
else -> _application
}
}
}
fun expression2action(expr: Any): Any {
if (expr is List<*>) {
return atom2action(expr as String)
} else {
return list2action(expr)
}
}
val _const: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
val s = expr as String
s.toIntOrNull() ?: when (s) {
"#t" -> {
true
}
"#f" -> {
false
}
else -> {
listOf("primitive", s)
}
}
}
val _identifier: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
val str = expr as String
var v: Any? = null
for (map in table) {
if (map[str] != null) {
v = map[str]
break
}
}
v
}
val _quote: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
(expr as List<*>)[1]!!
}
val _cond: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
val lines = (expr as List<*>)[1]!! as List<*>
var v: Any? = null
for (line in lines) {
val anies = line as List<*>
val predicate = anies[0]
val branch = anies[1]
if (predicate == "else") {
v = meaning(branch!!, table)
break
} else if (meaning(predicate!!, table) == true) {
v = meaning(branch!!, table)
break
}
}
v!!
}
val _lambda: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
val anies = expr as List<*>
listOf("non-primitive") + (listOf(table) + (anies.drop(1)))
}
val _application: (Any, List<Map<String, Any>>) -> Any = { expr, table ->
val anies = expr as List<*>
val func = anies[0]
val args = anies.drop(1)
args
}
//(non-primitive (() (x) (add1 x)))
fun _apply(f: Any, vals: List<Any>) {
val anies = f as List<*>
val first = anies.first()
if (first == "primitive") {
_applyPrimitive(anies[1]!!, vals)
} else if (first == "non-primitive") {
_applyClosure(anies[1]!!, vals)
} else {
throw RuntimeException()
}
}
fun _applyPrimitive(name: Any, vals: Any): Any {
}
fun _applyClosure(name: Any, vals: Any): Any {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment