-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils-repl-eval.stanza
More file actions
76 lines (60 loc) · 2.4 KB
/
utils-repl-eval.stanza
File metadata and controls
76 lines (60 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
defpackage repl-eval :
import core
import collections
import reader
import stz/core-macros
import stz/repl
public val incoming = Queue<String>()
extern defn rcv_data (raw-data:ptr<byte>, length:long) -> int :
add(incoming, String(length, raw-data))
return 0
defn parse (form) -> ? :
match-syntax[core](form) :
(?es:#exp ... ?rest ...) :
es
defn to-repl-exp (s:String) :
Eval(parse(read-all(s)))
var *inside-pkg*:False|Symbol = false
defn do-inside (repl:REPL, pkg:Symbol) :
;; println("DO-INSIDE %_" % [pkg])
if *inside-pkg* is False or (*inside-pkg* as Symbol) != pkg :
eval-exp(repl, Inside(pkg))
*inside-pkg* = pkg
defn do-queue-eval (repl:REPL, pkg:Symbol, s:String) -> String :
do-inside(repl, pkg)
;; println("DO-EVAL PKG %_ S %_" % [pkg, s])
eval-exp(repl, to-repl-exp(s))
val res = pop(incoming)
;; println("EVAL %_ RES %_" % [s, res])
res
;; TODO: SHOULD BE KEYED TO REPL
public defstruct Package :
name : Symbol
listeners : HashTable<Symbol, (() -> ?)> with: ( init => HashTable<Symbol, (() -> ?)>() )
public var *packages* = HashTable<Symbol, Package>()
public defn install-package-listener (pkg:Symbol, name:Symbol, callback:() -> ?) :
listeners(*packages*[pkg])[name] = callback
public defn remove-package-listener (pkg:Symbol, name:Symbol) :
remove(listeners(*packages*[pkg]), name)
defn maybe-update-listeners (pkg:Symbol) :
if key?(*packages*, pkg) :
for callback in values(listeners(*packages*[pkg])) do :
callback()
public defn load (repl:REPL, pkg:Symbol, filenames:Tuple<String>) -> False :
println("LOAD %_ %_" % [pkg, filenames])
eval-exp(repl, Load(filenames))
if not key?(*packages*, pkg) :
*packages*[pkg] = Package(pkg)
maybe-update-listeners(pkg)
public defn load (repl:REPL, pkg:Symbol, s:String) -> False :
eval-exp(repl, to-repl-exp(s))
maybe-update-listeners(pkg)
public defn eval (repl:REPL, pkg:Symbol, e:String) -> String :
do-queue-eval(repl, pkg, string-join(["snd(" e ")"]))
public defn evals (repl:REPL, pkg:Symbol, e:String) -> Seq<String> :
val id-res = do-queue-eval(repl, pkg, string-join(["stream-register(" e ")"]))
val sid = to-int(id-res)
generate<String> :
while do-queue-eval(repl, pkg, string-join $ ["stream-empty?(" sid ")"]) == "false" :
yield(do-queue-eval(repl, pkg, string-join $ ["stream-next(" sid ")"]))
do-queue-eval(repl, pkg, string-join $ ["stream-free(" sid ")"])