Created
December 14, 2021 18:02
-
-
Save XGFan/74a7a4bdac80ebf0952be7ba070d8531 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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