mirror of
https://github.com/kanaka/mal.git
synced 2024-11-10 12:47:45 +03:00
Finished atoms and readline
This commit is contained in:
parent
8337e32c1c
commit
a779c814b9
@ -163,7 +163,46 @@ val ns = hashMapOf(
|
||||
Pair(MalSymbol("sequential?"), MalFunction({ a: ISeq -> if (a.nth(0) is ISeq) TRUE else FALSE })),
|
||||
|
||||
Pair(MalSymbol("meta"), MalFunction({ a: ISeq -> a.first().metadata })),
|
||||
Pair(MalSymbol("conj"), MalFunction({ a: ISeq -> (a.first() as ISeq).conj(a.rest()) }))
|
||||
Pair(MalSymbol("conj"), MalFunction({ a: ISeq -> (a.first() as ISeq).conj(a.rest()) })),
|
||||
|
||||
Pair(MalSymbol("deref"), MalFunction({ a: ISeq -> (a.first() as MalAtom).value })),
|
||||
Pair(MalSymbol("reset!"), MalFunction({ a: ISeq ->
|
||||
val atom = (a.nth(0) as MalAtom)
|
||||
val value = a.nth(1)
|
||||
atom.value = value
|
||||
value
|
||||
})),
|
||||
Pair(MalSymbol("swap!"), MalFunction({ a: ISeq ->
|
||||
val atom = (a.nth(0) as MalAtom)
|
||||
val function = a.nth(1) as MalFunction
|
||||
|
||||
// TODO reuse code from apply?
|
||||
val params = MalList()
|
||||
params.conj_BANG(atom.value)
|
||||
a.seq().drop(2).forEach({ it ->
|
||||
if (it is ISeq) {
|
||||
it.seq().forEach({ x -> params.conj_BANG(x) })
|
||||
} else {
|
||||
params.conj_BANG(it)
|
||||
}
|
||||
})
|
||||
|
||||
val value = function.apply(params)
|
||||
atom.value = value
|
||||
|
||||
value
|
||||
})),
|
||||
|
||||
Pair(MalSymbol("readline"), MalFunction({ a: ISeq ->
|
||||
val prompt = a.first() as MalString
|
||||
try {
|
||||
MalString(readline(prompt.value))
|
||||
} catch (e: java.io.IOException) {
|
||||
throw MalException(e.message)
|
||||
} catch (e: EofException) {
|
||||
NIL
|
||||
}
|
||||
}))
|
||||
)
|
||||
|
||||
fun pairwiseEquals(s: ISeq): MalConstant =
|
||||
|
@ -25,6 +25,8 @@ fun pr_str(malType: MalType, print_readably: Boolean = false): String =
|
||||
pr_str(malType.elements, "[", "]", print_readably)
|
||||
} else if (malType is MalHashMap) {
|
||||
malType.elements.map({ it -> pr_str(it, print_readably) }).joinToString(" ", "{", "}")
|
||||
} else if (malType is MalAtom) {
|
||||
"(atom " + pr_str(malType.value, print_readably) + ")"
|
||||
} else {
|
||||
throw MalPrinterException("Unrecognized MalType: " + malType)
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ fun read_form(reader: Reader): MalType =
|
||||
"~" -> read_shorthand(reader, "unquote")
|
||||
"~@" -> read_shorthand(reader, "splice-unquote")
|
||||
"^" -> read_with_meta(reader)
|
||||
"@" -> read_shorthand(reader, "deref")
|
||||
else -> read_atom(reader)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package mal
|
||||
|
||||
fun readline(prompt: String): String? {
|
||||
class EofException : Exception("EOF")
|
||||
|
||||
fun readline(prompt: String): String {
|
||||
print(prompt)
|
||||
return readLine()
|
||||
return readLine() ?: throw EofException()
|
||||
}
|
||||
|
@ -72,6 +72,8 @@ fun eval(_ast: MalType, _env: Env): MalType {
|
||||
val obj = eval(ast.nth(1), env)
|
||||
val metadata = eval(ast.nth(2), env)
|
||||
return obj.with_meta(metadata)
|
||||
} else if (first is MalSymbol && first.value == "atom") {
|
||||
return MalAtom(eval(ast.nth(1), env))
|
||||
} else {
|
||||
val evaluated = eval_ast(ast, env) as ISeq
|
||||
val firstEval = evaluated.first()
|
||||
@ -173,10 +175,11 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
val input = readline("user> ") ?: break
|
||||
|
||||
val input = readline("user> ")
|
||||
try {
|
||||
println(rep(input, repl_env))
|
||||
} catch (e: EofException) {
|
||||
break
|
||||
} catch (e: MalContinue) {
|
||||
} catch (e: MalException) {
|
||||
println("Error: " + e.message)
|
||||
|
@ -235,6 +235,13 @@ class MalHashMap() : MalType {
|
||||
}
|
||||
}
|
||||
|
||||
class MalAtom(var value: MalType) : MalType {
|
||||
override var metadata: MalType = NIL
|
||||
override fun with_meta(meta: MalType): MalType = throw UnsupportedOperationException()
|
||||
|
||||
|
||||
}
|
||||
|
||||
// TODO add truthiness checking
|
||||
val NIL = MalConstant("nil")
|
||||
val TRUE = MalConstant("true")
|
||||
|
Loading…
Reference in New Issue
Block a user