git.iko.soy/rowtype-yoga/pose
on main help sign in
Works but is very slow
commite1d8adf8b4b2d2cc4b2e6e2f76ebf62b262aa702 authorMark Eibes <mark.eibes@gmail.com> dateThu 8 Jul 2021, 20:29 (5 years ago) parentd9dd1bd
27 files changed+3561−34
packages/core/Main packages/core/ffi/go.mod+9 packages/core/ffi/go.sum+76 packages/core/ffi/purescript-aff/Aff.go+1763 packages/core/ffi/purescript-debug/Debug.go+84 packages/core/ffi/purescript-go-dhall-golang/DhallGolang.go+273 packages/core/ffi/purescript-go-gin/Gin.go+116 packages/core/ffi/purescript-go-glsp/Go_LanguageServerProtocol.go+110 packages/core/ffi/purescript-go-os/OS.go+320 packages/core/ffi/purescript-now/Now.go+16 packages/core/ffi/purescript-record/RecordBuilder.purs packages/core/ffi/purescript-spec/Test_Spec_Console.go+19 packages/core/ffi/purescript-spec/Test_Spec_Runner.go+19 packages/core/ffi/purescript-strings/Data_String_CodePoints.go+94 packages/core/ffi/purescript-strings/Data_String_CodeUnits.go+238 packages/core/ffi/purescript-strings/Data_String_Common.go+79 packages/core/ffi/purescript-strings/Data_String_Regex.go+180 packages/core/ffi/purescript-strings/Data_String_Unsafe.go+30 packages/core/ffi/purescript-unicode/Data_Char_Unicode.go+16 packages/core/go.mod+6−2 packages/core/go.sum+70 packages/core/purescript-native/ffi_loader.go+18−10 packages/core/purescript-native/go.mod+7 packages/core/src/Format.purs+2−9 packages/core/src/Main.purs+5−13 packages/core/src/OS.js+4 packages/core/src/OS.purs+7
packages/core/Main

Binary file not shown.

packages/core/ffi/go.modnew file+9
@@ -0,0 +1,9 @@
1+module project.localhost/ffi
2+
3+go 1.16
4+
5+require (
6+ github.com/gin-gonic/gin v1.6.3
7+ github.com/philandstuff/dhall-golang/v6 v6.0.1 // indirect
8+ github.com/purescript-native/go-runtime v0.1.0
9+)
packages/core/ffi/go.sumnew file+76
@@ -0,0 +1,76 @@
1+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
3+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
6+github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f h1:lvGFo/tDOSQ4FKu0d2694s8XyOfAL6FLR9DCD5BIUW4=
7+github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
8+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
9+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
10+github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
11+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
12+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
13+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
14+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
15+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
16+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
17+github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
18+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
19+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
20+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
21+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
22+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
23+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
24+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
25+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
26+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
27+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
28+github.com/leanovate/gopter v0.2.5-0.20190402064358-634a59d12406/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8=
29+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
30+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
31+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
32+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
33+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
34+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
35+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
36+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
37+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
38+github.com/philandstuff/dhall-golang/v6 v6.0.1 h1:pbjs7NlmnmIeNMOa9KQYIEXeKk01uK72IxFCsaSozNM=
39+github.com/philandstuff/dhall-golang/v6 v6.0.1/go.mod h1:XRoxjsqZM2y7KPFhjV7CSVdWpV5CwuTzGjAY/v+1SUU=
40+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
41+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
42+github.com/purescript-native/go-runtime v0.1.0 h1:6liwLEqu9oZhXE/ipAoKBgFi4g4SxjmXs7Whps/P7NQ=
43+github.com/purescript-native/go-runtime v0.1.0/go.mod h1:Pl7TR9c9Al8GMlY/R2D7joWjlQuTiB9eBN2a9aXd6GQ=
44+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
45+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
46+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
47+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
48+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
49+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
50+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
51+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
52+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
53+github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
54+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
55+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
56+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
57+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
58+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
59+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
60+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
61+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
62+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
63+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64+golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
65+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
66+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
67+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
68+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
69+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
70+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
71+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
72+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
73+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
74+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
75+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
76+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
packages/core/ffi/purescript-aff/Aff.gonew file+1763
@@ -0,0 +1,1763 @@
1+package purescript_aff
2+
3+import (
4+ "errors"
5+ "fmt"
6+ "os"
7+ "reflect"
8+ "runtime"
9+ "strings"
10+ "sync"
11+ "time"
12+
13+ . "github.com/purescript-native/go-runtime"
14+)
15+
16+// Whether to log errors or not
17+const TRACE = false
18+
19+func Trace(stuff ...Any) {
20+ if TRACE {
21+ fmt.Println(stuff...)
22+ }
23+}
24+
25+func dontRecover() Any {
26+ return nil
27+}
28+func TraceAnyway(stuff ...Any) {
29+ fmt.Println(stuff...)
30+}
31+
32+var (
33+ Info = Teal
34+ Warn = Yellow
35+ Fata = Red
36+)
37+
38+var (
39+ Black = Color("\033[1;30m%s\033[0m")
40+ Red = Color("\033[1;31m%s\033[0m")
41+ Green = Color("\033[1;32m%s\033[0m")
42+ Yellow = Color("\033[1;33m%s\033[0m")
43+ Purple = Color("\033[1;34m%s\033[0m")
44+ Magenta = Color("\033[1;35m%s\033[0m")
45+ Teal = Color("\033[1;36m%s\033[0m")
46+ White = Color("\033[1;37m%s\033[0m")
47+)
48+
49+func Color(colorString string) func(...interface{}) string {
50+ sprint := func(args ...interface{}) string {
51+ return fmt.Sprintf(colorString,
52+ fmt.Sprint(args...))
53+ }
54+ return sprint
55+}
56+
57+type Fiber = Dict
58+
59+// Pure a
60+type Pure struct {
61+ Pure bool
62+ value Any
63+}
64+
65+// type memo interface {
66+// getMemo() Any
67+// setMemo(v Any)
68+// }
69+
70+// func (p Pure) getMemo() Any {
71+// return p.value
72+// }
73+
74+// func (p Pure) setMemo(m Any) {
75+// p.value = m
76+// }
77+
78+// func (p AbstractAff) getMemo() Any {
79+// return p._3
80+// }
81+
82+// func (p AbstractAff) setMemo(m Any) {
83+// p._3 = m
84+// }
85+
86+func (p Pure) String() string {
87+ return fmt.Sprintf("Pure %s", p.value)
88+}
89+
90+// Throw Error
91+type Throw struct {
92+ Throw bool
93+ err error
94+}
95+
96+func (t Throw) String() string {
97+ return fmt.Sprintf("Throw %s", t.err)
98+}
99+
100+// Catch (Aff a) (Error -> Aff a)
101+type Catch struct {
102+ Catch bool
103+ aff Any
104+ errorToAff func(Any) Any
105+}
106+
107+func (c Catch) String() string {
108+ return fmt.Sprintf("Catch %s", c.aff)
109+}
110+
111+// Sync (Effect a)
112+type Sync struct {
113+ Sync bool
114+ eff func() Any
115+}
116+
117+func (s Sync) String() string {
118+ return fmt.Sprintf("Sync")
119+}
120+
121+type K = Any
122+type Unit = Any
123+type EffectUnit = func() Unit
124+type EitherErrorOrAToEffectUnit = func(Any) EffectUnit
125+type EffectCanceler = func() Canceler
126+type Canceler = func(err Any) Any
127+type AsyncFn = func(EitherErrorOrAToEffectUnit) EffectCanceler
128+
129+// Async ((Either Error a -> Effect Unit) -> Effect (Canceler))
130+type Async struct {
131+ Async bool
132+ asyncFn Any
133+}
134+
135+func (a Async) String() string {
136+ return fmt.Sprintf("Async")
137+}
138+
139+// forall b. Bind (Aff b) (b -> Aff a)
140+type Bind struct {
141+ Bind bool
142+ affOfB Any
143+ bToAff func(Any) Any
144+}
145+
146+func (b Bind) String() string {
147+ return fmt.Sprintf("Bind %d", b.affOfB)
148+}
149+
150+// forall b. Bracket (Aff b) (BracketConditions b) (b -> Aff a)
151+type Bracket struct {
152+ Bracket bool
153+ acquire Any
154+ bracketConditions Dict
155+ k func(Any) Any
156+}
157+
158+func (b Bracket) String() string {
159+ return fmt.Sprintf("Bracket acquire:%d conditions:%d",
160+ b.acquire,
161+ b.bracketConditions)
162+}
163+
164+// forall b. Fork Boolean (Aff b) ?(Fiber b -> a)
165+type Fork struct {
166+ Fork bool
167+ immediate bool
168+ affOfB Any
169+}
170+
171+func (f Fork) String() string {
172+ return fmt.Sprintf("Fork %d", f.affOfB)
173+}
174+
175+// Sequential (ParAff a)
176+type Sequential struct {
177+ Sequential bool
178+ parAff Any
179+}
180+
181+type Return struct {
182+ Return bool
183+}
184+
185+func (r Return) String() string {
186+ return fmt.Sprintf("Return")
187+}
188+
189+type Resume struct {
190+ Resume bool
191+ b Cons
192+}
193+
194+func (r Resume) String() string {
195+ return fmt.Sprintf("Resume %d", r.b.head)
196+}
197+
198+type Release struct {
199+ Release bool
200+ bracketConditions Dict
201+ result Any
202+}
203+
204+func (r Release) String() string {
205+ return fmt.Sprintf("Release %d", r.result)
206+}
207+
208+type Finalizer struct {
209+ Finalizer bool
210+ finalizer Any
211+}
212+
213+func (f Finalizer) String() string {
214+ return fmt.Sprintf("Finalizer")
215+}
216+
217+type Finalized struct {
218+ Finalizer bool
219+ step Any
220+ fail Any
221+}
222+
223+func (f Finalized) String() string {
224+ return fmt.Sprintf("Finalized %d %d", f.step, f.fail)
225+}
226+
227+type AbstractAff struct {
228+ tag string
229+ _1 Any
230+ _2 Any
231+ _3 Any
232+}
233+
234+func (aa AbstractAff) String() string {
235+ return fmt.Sprintf("\nAff:\t%s\n\t_1: %d\n\t_2: %d\n\t_3: %d",
236+ aa.tag, aa._1, aa._2, aa._3)
237+}
238+
239+var Empty AbstractAff = AbstractAff{tag: "empty"}
240+
241+// forall b. Map (b -> a) (ParAff b)
242+// forall b. Apply (ParAff (b -> a)) (ParAff b)
243+// Alt (ParAff a) (ParAff a)
244+type ParAlt struct {
245+ parAffFn Any
246+ parAff Any
247+ memo Any
248+}
249+
250+type OnComplete = Dict
251+
252+type Cons struct {
253+ head Any
254+ tail *Cons
255+}
256+
257+func printCons(cons *Cons) {
258+ var goFn func(depth int, currHead Any, currTail *Cons) = nil
259+ goFn = func(depth int, currHead Any, currTail *Cons) {
260+ if currHead != nil {
261+ Trace(Yellow(currHead))
262+ if currTail != nil {
263+ goFn(depth+1, currTail.head, currTail.tail)
264+ }
265+ }
266+ }
267+ goFn(0, cons.head, cons.tail)
268+}
269+
270+type InterruptCons struct {
271+ head Any
272+ interrupt *Fiber
273+ tail *InterruptCons
274+}
275+
276+const SUSPENDED = 0 // Suspended, pending a join.
277+const CONTINUE = 1 // Interpret the next instruction.
278+const STEP_BIND = 2 // Apply the next bind.
279+const STEP_RESULT = 3 // Handle potential failure from a result.
280+const PENDING = 4 // An async effect is running.
281+const RETURN = 5 // The current stack has returned.
282+const COMPLETED = 6 // The entire fiber has completed.
283+
284+func statusName(st int) string {
285+ switch st {
286+ case SUSPENDED:
287+ return "SUSPENDED"
288+ case CONTINUE:
289+ return "CONTINUE"
290+ case STEP_BIND:
291+ return "STEP_BIND"
292+ case STEP_RESULT:
293+ return "STEP_RESULT"
294+ case PENDING:
295+ return "PENDING"
296+ case RETURN:
297+ return "RETURN"
298+ case COMPLETED:
299+ return "COMPLETED"
300+ }
301+ return "!!!!! UNKNOWN !!!!! "
302+}
303+
304+func nonCanceler(err Any) Any {
305+ return Pure{Pure: true, value: nil}
306+}
307+
308+func runEff(eff func() Any) {
309+ Trace(Teal("func: runEff"))
310+ defer func() {
311+ if err := recover(); err != nil {
312+ Trace(Magenta("Caught error in runEff: ", err))
313+ var msg string
314+ switch errTyped := err.(type) {
315+ case error:
316+ msg = errTyped.Error()
317+ case string:
318+ msg = errTyped
319+ default:
320+ Trace(Red("Unexpected error type in runEff ", reflect.TypeOf(err), err))
321+ os.Exit(0)
322+ }
323+ if msg == "runtime error: invalid memory address or nil pointer dereference" {
324+ Trace(Red("invalid mem", msg))
325+ panic(err)
326+ }
327+ if strings.HasPrefix(msg, "interface conversion:") {
328+ Trace(Red("Wrong cast ", msg))
329+ panic(err)
330+ }
331+ if strings.HasPrefix(msg, "Failed pattern match") {
332+ Trace(Red("FPM ", msg))
333+ panic(err)
334+ }
335+ Trace("\tError> ", err)
336+ go func() {
337+ panic(err)
338+ }()
339+ }
340+ }()
341+ eff()
342+}
343+
344+func runSync(left func(Any) Any, right func(Any) Any, eff func() Any) Any {
345+ Trace(Teal("func: runSync with ", reflect.TypeOf(eff)))
346+ var res Any = left(errors.New("Error wasn't set properly"))
347+ defer func() {
348+ if err := recover(); err != nil {
349+ Trace(Magenta("Caught error in runSync: ", err))
350+ var msg string
351+ switch errTyped := err.(type) {
352+ case error:
353+ msg = errTyped.Error()
354+ case string:
355+ msg = errTyped
356+ default:
357+ Trace(Red("Unexpected error type in runSync ", reflect.TypeOf(err), err))
358+ os.Exit(0)
359+ }
360+ if msg == "runtime error: invalid memory address or nil pointer dereference" {
361+ Trace(Red("invalid mem", msg))
362+ panic(err)
363+ }
364+ if strings.HasPrefix(msg, "interface conversion:") {
365+ Trace(Red("Wrong cast ", msg))
366+ panic(err)
367+ }
368+ Trace("\tError> ", err)
369+ res = left(errors.New(msg))
370+ }
371+ }()
372+ res = right(eff())
373+ return res
374+}
375+
376+func runAsync(left func(Any) Any, eff Any, k K) Any {
377+ Trace(Teal("func: runAsync"))
378+ // catch...
379+ var canceler Any = nonCanceler
380+ defer func() {
381+ if err := recover(); err != nil {
382+ Trace(Magenta("Caught error in runAsync: ", err))
383+ var msg string
384+ switch errTyped := err.(type) {
385+ case error:
386+ msg = errTyped.Error()
387+ case string:
388+ msg = errTyped
389+ case func(Any) Any:
390+ Trace(Red("Fn error type in runAsync ", errTyped(nil)))
391+ panic(err)
392+ default:
393+ Trace(Red("Unexpected error type in runAsync ", reflect.TypeOf(err), err))
394+ os.Exit(0)
395+ }
396+ if msg == "runtime error: invalid memory address or nil pointer dereference" {
397+ Trace(Red("invalid mem", msg))
398+ panic(err)
399+ }
400+ if strings.HasPrefix(msg, "interface conversion:") {
401+ Trace(Red("Wrong cast ", msg))
402+ panic(err)
403+ }
404+ Trace("\tError> ", err)
405+ k.(func(Any) Any)(left(err)).(func() Any)()
406+ }
407+ }()
408+ canceler = eff.(func(Any) Any)(k).(func() Any)()
409+ return canceler
410+}
411+
412+func sequential(util Any, supervisor *Supervisor, par Any) Async {
413+ return Async{asyncFn: func(cb Any) Any {
414+ return func() Any {
415+ return runPar(util, supervisor, par, cb)
416+ }
417+ },
418+ }
419+}
420+
421+type Scheduler struct {
422+ isDraining func() bool
423+ enqueue func(cb func())
424+}
425+
426+var scheduler Scheduler = (func() Scheduler {
427+ const limit = 1024
428+ size := 0
429+ ix := 0
430+ var queue [limit](func())
431+ draining := false
432+
433+ drain := func() {
434+ Trace(Teal("func: drain", size))
435+ draining = true
436+ for size != 0 {
437+ size--
438+ thunk := queue[ix]
439+ ix = (ix + 1) % limit
440+ thunk()
441+ }
442+ draining = false
443+ }
444+
445+ isDraining := func() bool { return draining }
446+ enqueue := func(cb func()) {
447+ Trace(Teal("func: enqueue"))
448+ if size == limit {
449+ tmp := draining
450+ drain()
451+ draining = tmp
452+ }
453+ queue[(ix+size)%limit] = cb
454+ size++
455+
456+ if !draining {
457+ drain()
458+ }
459+ }
460+
461+ return Scheduler{isDraining: isDraining, enqueue: enqueue}
462+})()
463+
464+type Supervisor = struct {
465+ register func(fiber Fiber)
466+ isEmpty func() bool
467+ killAll func(killError error, cb func() Any) Any
468+}
469+
470+func mkSupervisor(util_ Any) Supervisor {
471+ // Boilerplate
472+ var util map[string]Any = util_.(map[string]Any)
473+ var isLeft func(Any) Any = util["isLeft"].(func(Any) Any)
474+ var fromLeft func(Any) Any = util["fromLeft"].(func(Any) Any)
475+
476+ // Start here
477+ fibers := NewRegularIntMap()
478+ var fiberID = 0
479+ var count = 0
480+ return Supervisor{
481+ register: func(fiber Fiber) {
482+ Trace("func: supervisor.register", fiber)
483+ fid := fiberID
484+ fiberID++
485+ fiber["onComplete"].(func(Dict) Any)(
486+ Dict{
487+ "rethrow": true,
488+ "handler": func(result Any) Any {
489+ return func() Any {
490+ Trace(Green("🔛✅ Registered on complete handler running"))
491+ count--
492+ fibers.Delete(fid)
493+ return nil
494+ }
495+ },
496+ }).(func() Any)()
497+ fibers.Store(fid, fiber)
498+ count++
499+ },
500+ isEmpty: func() bool {
501+ Trace("func: supervisor.isEmpty")
502+ return count == 0
503+ },
504+ killAll: func(killError error, cb func() Any) Any {
505+ return func() Any {
506+ Trace("func: supervisor.killAll; count = ", count)
507+ if count == 0 {
508+ Trace("\n\nreturning cb")
509+ return cb()
510+ }
511+ killCount := 0
512+ kills := map[int](func() Any){}
513+
514+ kill := func(fid int, fib Fiber) {
515+ Trace(Red("\tMaking killFn for fiber with id ", fiberID))
516+ kills[fid] = fib["kill"].(func(Any, Any) Any)(killError, func(result Any) Any {
517+ return func() Any {
518+ delete(kills, fid)
519+ killCount--
520+ if isLeft(result).(bool) && fromLeft(result) != nil {
521+ go func() {
522+ panic(fromLeft(result)) // [TODO] Panic better?
523+ }()
524+
525+ }
526+ if killCount == 0 {
527+ Trace(Red("\tCalling cb"))
528+ cb()
529+ }
530+ return nil
531+ }
532+ }).(func() Any)().(func() Any)
533+ }
534+
535+ // [TODO] unsafe iteration
536+ for fiberID, _ := range fibers.internal {
537+ killCount++
538+ fib, nope := fibers.Load(fiberID)
539+ Trace(nope, "Just Chuck Testa")
540+ kill(fiberID, fib.(Dict))
541+ }
542+
543+ fibers = NewRegularIntMap()
544+ fiberID = 0
545+ count = 0
546+
547+ return func(err Any) Any {
548+ return Sync{
549+ eff: func() Any {
550+ for _, killThunk := range kills {
551+ killThunk()
552+ }
553+ return nil
554+ }}
555+ }
556+
557+ }
558+ },
559+ }
560+}
561+
562+func mkFiber(util_ Any, supervisor *Supervisor, aff_ Any) Fiber {
563+ var util map[string]Any = util_.(map[string]Any)
564+ var isLeft func(Any) Any = util["isLeft"].(func(Any) Any)
565+ var left func(Any) Any = util["left"].(func(Any) Any)
566+ var right func(Any) Any = util["right"].(func(Any) Any)
567+ var fromRight func(Any) Any = util["fromRight"].(func(Any) Any)
568+ var fromLeft func(Any) Any = util["fromLeft"].(func(Any) Any)
569+ runTick := 0
570+
571+ stepLock := &sync.Mutex{}
572+ step := aff_ // Successful step
573+ setStep := func(who string, newStep Any) {
574+ stepLock.Lock()
575+ Trace(who, "\n\tfrom:\t", step, "\n\tto:\t", newStep)
576+ step = newStep
577+ stepLock.Unlock()
578+ }
579+ var fail Any // Failure step
580+ var interrupt *Dict = nil // Asynchronous interrupt
581+
582+ // Stack of continuations for the current fiber.
583+ var b Cons = Cons{}
584+
585+ // Stack of attempts and finalizers for error recovery. Every `Cons` is also
586+ // tagged with current `interrupt` state. We use this to track which items
587+ // should be ignored or evaluated as a result of a kill.
588+ var attempts *InterruptCons = &InterruptCons{}
589+
590+ // A special state is needed for Bracket, because it cannot be killed. When
591+ // we enter a bracket acquisition or finalizer, we increment the counter,
592+ // and then decrement once complete.
593+ bracketCount := 0
594+
595+ // Each join gets a new id so they can be revoked.
596+ joinId := 0
597+ var joins map[int]OnComplete = nil
598+ var rethrow = true
599+
600+ status := SUSPENDED
601+
602+ var run func(int) Any
603+ run = func(localRunTick int) Any {
604+
605+ Trace("New round", "localRunTick", localRunTick, "bracketCount", bracketCount)
606+ var tmp *Dict
607+ var result Any
608+ var attempt Any
609+ for {
610+ Trace(Purple("\n=======================\nStatus:\t", statusName(status), "\nStep:\t", step, "\n======================="))
611+ tmp = nil
612+ result = nil
613+ attempt = nil
614+ switch status {
615+ case STEP_BIND:
616+ Trace("STEP_BIND", b.head)
617+ status = CONTINUE // next step
618+ headFn := b.head.(func(Any) Any)
619+ // Makeshift try catch block
620+ func() {
621+ defer func() {
622+ if rawErr := recover(); rawErr != nil {
623+ err, ok := rawErr.(error)
624+ if !ok {
625+ Trace(Red("\tNon error error ", rawErr))
626+ panic(error(errors.New("Error of unexpected type")))
627+ }
628+ if err.Error() == "runtime error: invalid memory address or nil pointer dereference" {
629+ Trace(Red("Invalid cast in STEP_BIND", err))
630+ panic(err)
631+ }
632+ if strings.HasPrefix(err.Error(), "interface conversion:") {
633+ Trace(Red("Wrong cast in STEP_BIND ", err))
634+ panic(err)
635+ }
636+ Trace(Red("\tError oh shit ", err))
637+ // early return on error
638+ status = RETURN
639+ fail = left(err)
640+ // step = nil
641+ setStep("bind error", nil)
642+ }
643+ }()
644+ // step = headFn(step)
645+ setStep("bind success", headFn(step))
646+ Trace("\t> Next step", step)
647+ if b.tail == nil {
648+ b.head = nil
649+ } else {
650+ b.head = b.tail.head
651+ b.tail = b.tail.tail
652+ }
653+ }()
654+ case STEP_RESULT:
655+ Trace("STEP_RESULT", step, reflect.TypeOf(step))
656+ if isLeft(step).(bool) {
657+ // early return on error
658+ status = RETURN
659+ fail = step
660+ // step = nil
661+ setStep("result", nil)
662+ } else if b.head == nil {
663+ // happy case done
664+ status = RETURN
665+ Trace("My work here is done")
666+ } else {
667+ // happy case work left
668+ status = STEP_BIND
669+ // step = fromRight(step)
670+ setStep("result", fromRight(step))
671+ Trace("Next step after happy result", step)
672+ }
673+
674+ case CONTINUE:
675+ Trace("CONTINUE")
676+ switch currentStep := step.(type) {
677+
678+ case Bind:
679+ Trace("\tBind")
680+ if b.head != nil {
681+ b.tail = &Cons{head: b.head, tail: b.tail}
682+ }
683+ b.head = currentStep.bToAff
684+ status = CONTINUE
685+ // step = currentStep.affOfB
686+ setStep("continue", currentStep.affOfB)
687+
688+ case Pure:
689+ Trace("\tPure")
690+ if b.head == nil {
691+
692+ Trace("\t> Head nil")
693+ // we're done
694+ status = RETURN
695+ // step = right(currentStep.value)
696+ setStep("pure, return", right(currentStep.value))
697+ } else {
698+ Trace("\t> Head exists", currentStep.value)
699+ // this happens after a bind
700+ // step = currentStep.value
701+ setStep("pure, bind", currentStep.value)
702+ status = STEP_BIND
703+ }
704+
705+ case Sync:
706+ Trace("\tSync")
707+ // step = runSync(left, right, currentStep.eff)
708+ setStep("sync", runSync(left, right, currentStep.eff))
709+ status = STEP_RESULT
710+
711+ case Async:
712+ Trace("\tAsync")
713+ status = PENDING
714+ var asyncCb K = func(theResult Any) Any {
715+ return func() Unit {
716+ if runTick != localRunTick {
717+ Trace("\t\tRun tick != localRunTick")
718+ return nil
719+ }
720+ runTick++
721+ scheduler.enqueue(func() {
722+ if runTick != localRunTick+1 {
723+ Trace("\t\tRun tick != localRunTick + 1")
724+ return
725+ }
726+ // step = theResult
727+ setStep("Async Callback", theResult)
728+ status = STEP_RESULT
729+ run(runTick)
730+ })
731+ return nil
732+ }
733+ }
734+ // runAsync returns a canceller
735+ // step = runAsync(left, currentStep.asyncFn, asyncCb)
736+ setStep("Async ", runAsync(left, currentStep.asyncFn, asyncCb))
737+ return nil
738+
739+ case Throw:
740+ Trace("\tThrow")
741+ status = RETURN
742+ fail = left(currentStep.err)
743+ // step = nil
744+ setStep("Throw", nil)
745+
746+ case Catch:
747+ Trace("\tCatch", currentStep.aff)
748+ if b.head == nil {
749+ Trace("\t\tHead is nil")
750+ attempts = &InterruptCons{head: step, tail: attempts, interrupt: interrupt}
751+ } else {
752+ Trace("\t\tHead is not nil", b.head)
753+ attempts = &InterruptCons{
754+ interrupt: interrupt,
755+ head: step,
756+ tail: &InterruptCons{
757+ interrupt: interrupt,
758+ head: Resume{b: b},
759+ tail: attempts}}
760+ }
761+ b.head = nil
762+ b.tail = nil
763+ status = CONTINUE
764+ // step = currentStep.aff
765+ setStep("Catch", currentStep.aff)
766+
767+ // Enqueue the Bracket so that we can call the appropriate handlers
768+ // after resource acquisition.
769+ case Bracket:
770+ Trace("\tBracket")
771+ bracketCount++
772+ if b.head == nil {
773+ Trace("\t\tb.head == nil")
774+ attempts = &InterruptCons{head: step, tail: attempts, interrupt: interrupt}
775+ } else {
776+ Trace("\t\tb.head /= nil")
777+ attempts = &InterruptCons{
778+ interrupt: interrupt,
779+ head: step,
780+ tail: &InterruptCons{
781+ interrupt: interrupt,
782+ head: Resume{b: b},
783+ tail: attempts}}
784+ }
785+ b.head = nil
786+ b.tail = nil
787+ status = CONTINUE
788+ // step = currentStep.acquire
789+ setStep("Bracket", currentStep.acquire)
790+
791+ case Fork:
792+ Trace("\tFork")
793+ tmpVar := mkFiber(util, supervisor, currentStep.affOfB)
794+ tmp = &tmpVar
795+ if supervisor != nil {
796+ supervisor.register(*tmp)
797+ }
798+ if currentStep.immediate {
799+ (*tmp)["run"].(func() Any)()
800+ }
801+ // step = right(*tmp)
802+ setStep("Fork", right(*tmp))
803+ status = STEP_RESULT
804+
805+ case Sequential:
806+ Trace("\tSequential")
807+ status = CONTINUE
808+ // step = sequential(util, supervisor, currentStep.parAff)
809+ setStep("Sequential", sequential(util, supervisor, currentStep.parAff))
810+
811+ default:
812+ Trace(Purple("Oh god ", reflect.TypeOf(step)))
813+ panic(step)
814+
815+ }
816+
817+ case RETURN:
818+ Trace("RETURN")
819+ b.head = nil
820+ b.tail = nil
821+ Trace("\tAttempts:", attempts)
822+ if attempts.head == nil {
823+ Trace("\tAttempts are nil", interrupt, fail)
824+ status = COMPLETED
825+ if interrupt != nil {
826+ // step = *interrupt
827+ setStep("return interrupt", *interrupt)
828+ } else if fail != nil {
829+ // step = fail
830+ setStep("return fail", fail)
831+ }
832+ } else {
833+ Trace("\tAttempts aren't nil", attempts.head, attempts.tail)
834+ tmp = attempts.interrupt
835+ attempt = attempts.head
836+ attempts = attempts.tail
837+
838+ switch currentAttempt := attempt.(type) {
839+ case Catch:
840+ Trace("\tReturn Catch")
841+ if interrupt != nil && interrupt != tmp && bracketCount == 0 {
842+ Trace("\t\tGonna RETURN")
843+ status = RETURN
844+ } else if fail != nil {
845+ Trace("\t\tGonna CONTINUE", fromLeft(fail))
846+ status = CONTINUE
847+ // step = currentAttempt.errorToAff(fromLeft(fail))
848+ setStep("return catch", currentAttempt.errorToAff(fromLeft(fail)))
849+ fail = nil
850+ }
851+
852+ // We cannot resume from an unmasked interrupt or exception.
853+ case Resume:
854+ Trace("\tResume")
855+ // As with Catch, we only want to ignore in the case of an
856+ // interrupt since enqueing the item.
857+ if (interrupt != nil && interrupt != tmp && bracketCount == 0) || fail != nil {
858+ status = RETURN
859+ } else {
860+ b.head = currentAttempt.b.head
861+ b.tail = currentAttempt.b.tail
862+ status = STEP_BIND
863+ // step = fromRight(step)
864+ setStep("resume ", fromRight(step))
865+ }
866+
867+ case Bracket:
868+ Trace("\tBracket")
869+ bracketCount--
870+ if fail == nil {
871+ result = fromRight(step)
872+ attempts = &InterruptCons{
873+ head: Release{
874+ bracketConditions: currentAttempt.bracketConditions,
875+ result: result,
876+ },
877+ tail: attempts,
878+ interrupt: tmp,
879+ }
880+
881+ if interrupt == tmp || bracketCount > 0 {
882+ Trace("\t\tContinuing")
883+ status = CONTINUE
884+ // step = currentAttempt.k(result)
885+ setStep("Bracket continue", currentAttempt.k(result))
886+ }
887+ }
888+ case Release:
889+ Trace("\tRelease")
890+ attempts = &InterruptCons{
891+ head: Finalized{step: step, fail: fail},
892+ tail: attempts,
893+ interrupt: interrupt,
894+ }
895+ status = CONTINUE
896+ // It has only been killed if the interrupt status has changed
897+ // since we enqueued the item, and the bracket count is 0. If the
898+ // bracket count is non-zero then we are in a masked state so it's
899+ // impossible to be killed.
900+ if interrupt != nil && &interrupt != &tmp && bracketCount == 0 {
901+ Trace("\t\tkilled branch")
902+ // step = currentAttempt.bracketConditions["killed"].(func(Any) Any)(fromLeft(*interrupt)).(func(Any) Any)(currentAttempt.result)
903+ setStep("Release killed", currentAttempt.bracketConditions["killed"].(func(Any) Any)(fromLeft(*interrupt)).(func(Any) Any)(currentAttempt.result))
904+ } else if fail != nil {
905+ Trace("\t\tfailed branch")
906+ // step = currentAttempt.bracketConditions["failed"].(func(Any) Any)(fromLeft(fail)).(func(Any) Any)(currentAttempt.result)
907+ setStep("Release failed", currentAttempt.bracketConditions["failed"].(func(Any) Any)(fromLeft(fail)).(func(Any) Any)(currentAttempt.result))
908+ } else {
909+ Trace("\t\tcompleted branch")
910+ // step = currentAttempt.bracketConditions["completed"].(func(Any) Any)(fromRight(step)).(func(Any) Any)(currentAttempt.result)
911+ setStep("Release completed", currentAttempt.bracketConditions["completed"].(func(Any) Any)(fromRight(step)).(func(Any) Any)(currentAttempt.result))
912+ }
913+ fail = nil
914+ bracketCount++
915+ case Finalizer:
916+ Trace("\tFinalizer")
917+ bracketCount++
918+ attempts = &InterruptCons{
919+ head: Finalized{step: step, fail: fail},
920+ tail: attempts,
921+ interrupt: interrupt,
922+ }
923+ status = CONTINUE
924+ // step = currentAttempt.finalizer
925+ setStep("Finalizer", currentAttempt.finalizer)
926+ case Finalized:
927+ Trace("\tFinalized")
928+ bracketCount--
929+ status = RETURN
930+ // step = currentAttempt.step
931+ setStep("Finalized", currentAttempt.step)
932+ fail = currentAttempt.fail
933+ default:
934+ Trace(Fata("\tUnknown Attempt type hit", reflect.TypeOf(currentAttempt)))
935+ }
936+ }
937+ case COMPLETED:
938+ Trace("COMPLETED", joins)
939+ for _, join := range joins {
940+ if rethrow {
941+ rethrow = join["rethrow"].(bool)
942+ }
943+ Trace(Green("\tRunning onComplete ✅ handler"))
944+ runEff(join["handler"].(func(Any) Any)(step).(func() Any))
945+ }
946+ joins = nil
947+ // If we have an interrupt and a fail, then the thread threw while
948+ // running finalizers. This should always rethrow in a fresh stack.
949+ if interrupt != nil && fail != nil {
950+ go func() {
951+ // [TODO]: How can we avoid this?
952+ // [TODO]: Do we need this here?
953+ // time.Sleep(50 * time.Millisecond) // [TODO]: How can we avoid this?
954+ go panic(fromLeft(fail))
955+ }()
956+
957+ // If we have an unhandled exception, and no other fiber has joined
958+ // then we need to throw the exception in a fresh stack.
959+ } else if isLeft(step).(bool) && rethrow {
960+ go func() {
961+ // Guard on rethrow because a completely synchronous fiber can
962+ // still have an observer which was added after-the-fact.
963+ time.Sleep(80 * time.Millisecond) // [TODO]: How can we avoid this?
964+ runtime.Gosched()
965+ if rethrow {
966+ panic(fromLeft(fail))
967+ }
968+ }()
969+ }
970+ return nil
971+
972+ case SUSPENDED:
973+ Trace("SUSPENDED")
974+ status = CONTINUE
975+ case PENDING:
976+ Trace("PENDING")
977+ return nil
978+
979+ default:
980+ Trace(Fata("Unknown branch hit", step))
981+ }
982+ }
983+
984+ }
985+
986+ onComplete := func(join OnComplete) Any {
987+ return func() Any {
988+ Trace(Teal("func: onComplete"))
989+ if status == COMPLETED {
990+ Trace("\tstatus == COMPLETED")
991+ rethrow = rethrow && join["rethrow"].(bool)
992+ join["handler"].(func(Any) Any)(step).(func() Any)()
993+ return func() Any { return nil }
994+ }
995+ Trace("\tstatus == ", statusName(status))
996+
997+ var jid = joinId
998+ Trace("\tJoin id", jid)
999+ joinId++
1000+ if joins == nil {
1001+ joins = map[int]OnComplete{}
1002+ }
1003+ joins[jid] = join
1004+
1005+ return func() Any {
1006+ if joins != nil {
1007+ delete(joins, jid)
1008+ }
1009+ return nil
1010+ }
1011+ }
1012+ }
1013+
1014+ kill := func(err Any, cb_ Any) Any {
1015+ cb := cb_.(func(Any) Any)
1016+ return func() Any {
1017+ if status == COMPLETED {
1018+ Trace(Green("Completed, no need to cancel"))
1019+ cb(right(nil)).(func() Any)()
1020+ return func() Any { return nil }
1021+ }
1022+
1023+ var canceler (func() Any) = onComplete(Dict{
1024+ "rethrow": false,
1025+ "handler": func(_ Any) Any {
1026+ return cb(right(nil))
1027+ },
1028+ }).(func() Any)().(func() Any)
1029+
1030+ switch status {
1031+ case SUSPENDED:
1032+ interruptValue := left(err).(Dict)
1033+ interrupt = &interruptValue
1034+ status = COMPLETED
1035+ step = *interrupt
1036+ run(runTick)
1037+ case PENDING:
1038+ if interrupt == nil {
1039+ interruptValue := left(err).(Dict)
1040+ interrupt = &interruptValue
1041+ }
1042+ if bracketCount == 0 {
1043+ if status == PENDING {
1044+ attempts = &InterruptCons{
1045+ head: Finalizer{finalizer: step.(func(Any) Any)(err)},
1046+ tail: attempts,
1047+ interrupt: interrupt}
1048+ }
1049+ status = RETURN
1050+ step = nil
1051+ fail = nil
1052+ runTick++
1053+ run(runTick)
1054+ }
1055+ default:
1056+ if interrupt == nil {
1057+ interruptValue := left(err).(Dict)
1058+ interrupt = &interruptValue
1059+ }
1060+ if bracketCount == 0 {
1061+ status = RETURN
1062+ step = nil
1063+ fail = nil
1064+ }
1065+ }
1066+
1067+ return canceler
1068+ }
1069+ }
1070+
1071+ join := func(cb K) Any {
1072+ return func() Any {
1073+ Trace(Teal("func: join 1"))
1074+ Trace("\tjoin: status: ", statusName(status))
1075+ canceler := onComplete(
1076+ Dict{
1077+ "rethrow": false,
1078+ "handler": cb.(func(Any) Any),
1079+ }).(func() Any)()
1080+ if status == SUSPENDED {
1081+ Trace("join: \tcalling run")
1082+ run(runTick)
1083+ }
1084+ return canceler
1085+ }
1086+ }
1087+
1088+ return Fiber{
1089+ "run": func() Any {
1090+ if status == SUSPENDED {
1091+ if !scheduler.isDraining() {
1092+ scheduler.enqueue(func() {
1093+ run(runTick)
1094+ })
1095+ } else {
1096+ run(runTick)
1097+ }
1098+ }
1099+ return nil // Important to avoid panic
1100+ },
1101+ "kill": kill,
1102+ "join": join,
1103+ "onComplete": onComplete,
1104+ "isSuspended": func() Any { return status == SUSPENDED },
1105+ }
1106+}
1107+
1108+func runPar(util_ Any, supervisor *Supervisor, par Any, cb Any) Any {
1109+
1110+ var util map[string]Any = util_.(map[string]Any)
1111+ var isLeft func(Any) Any = util["isLeft"].(func(Any) Any)
1112+ var left func(Any) Any = util["left"].(func(Any) Any)
1113+ var right func(Any) Any = util["right"].(func(Any) Any)
1114+ var fromRight func(Any) Any = util["fromRight"].(func(Any) Any)
1115+ var fromLeft func(Any) Any = util["fromLeft"].(func(Any) Any)
1116+
1117+ fiberID := 0
1118+ fibers := NewRegularIntMap()
1119+
1120+ killID := 0
1121+ kills := NewRegularIntMap()
1122+
1123+ early := errors.New("[ParAff] Early exit")
1124+
1125+ var interrupt Any = nil
1126+
1127+ var root Any = Empty
1128+
1129+ kill := func(err error, par *AbstractAff, cb K) Any {
1130+ step := par
1131+ var head *AbstractAff
1132+ var tail *Cons
1133+
1134+ count := 0
1135+ kills := NewRegularIntMap()
1136+ var tmp Any
1137+ var kid int
1138+
1139+ loop:
1140+ for {
1141+ tmp = nil
1142+ Trace("Step", reflect.TypeOf(step))
1143+
1144+ switch step.tag {
1145+ case "Forked":
1146+ if step._3 == Empty {
1147+ tmp, _ = fibers.Load(step._1.(int))
1148+ tmpKillFn := tmp.(Fiber)["kill"].(func(Any, Any) Any)
1149+ kills.Store(count, tmpKillFn(err, func(result Any) Any {
1150+ return func() Any {
1151+ count--
1152+ if count == 0 {
1153+ cb.(func(Any) Any)(result).(func() Any)()
1154+ }
1155+ return nil
1156+ }
1157+ }))
1158+ count++
1159+ }
1160+ if head == nil {
1161+ break loop
1162+ }
1163+
1164+ step = head._2.(*AbstractAff)
1165+ if tail == nil {
1166+ head = nil
1167+ } else {
1168+ head = tail.head.(*AbstractAff)
1169+ tail = tail.tail
1170+ }
1171+ case "ParMap":
1172+ step = step._2.(*AbstractAff)
1173+ case "ParApply":
1174+ if head != nil {
1175+ tail = &Cons{head: head, tail: tail}
1176+ }
1177+ head = step
1178+ step = step._1.(*AbstractAff)
1179+ case "ParAlt":
1180+ if head != nil {
1181+ tail = &Cons{head: head, tail: tail}
1182+ }
1183+ head = step
1184+ step = step._1.(*AbstractAff)
1185+ }
1186+ }
1187+ if count == 0 {
1188+ cb.(func(Any) Any)(right(nil)).(func() Any)()
1189+ } else {
1190+ // Run the cancelation effects. We alias `count` because it's mutable.
1191+ tmp = count
1192+ for kid = 0; kid < tmp.(int); kid++ {
1193+ kill, ok := kills.Load(kid)
1194+ if ok {
1195+ kills.Store(kid, kill.(func() Any)())
1196+ }
1197+
1198+ }
1199+ }
1200+ return kills
1201+ }
1202+
1203+ var join func(result Any, cons *Cons)
1204+ join = func(result Any, cons *Cons) {
1205+ Trace("Join")
1206+ var head *AbstractAff
1207+ var tail *Cons
1208+ if cons == nil {
1209+ head = nil
1210+ cons = nil
1211+ } else {
1212+ head = cons.head.(*AbstractAff)
1213+ tail = cons.tail
1214+ }
1215+ Trace(Teal("func: join 2 ", result, head))
1216+ var fail Any
1217+ var step Any
1218+ var lhs Any
1219+ var rhs Any
1220+ var tmp Any
1221+ var kid Any
1222+
1223+ if isLeft(result).(bool) {
1224+ fail = result
1225+ step = nil
1226+ } else {
1227+ step = result
1228+ fail = nil
1229+ }
1230+
1231+ for {
1232+ Trace(Magenta("\n############\njoinPar:\t", head, "\nstep:\t", step, "\n#############"))
1233+ // printCons(cons)
1234+ Trace(head)
1235+ Trace("---------\n")
1236+ lhs = nil
1237+ rhs = nil
1238+ tmp = nil
1239+ kid = nil
1240+
1241+ // We should never continue if the entire tree has been interrupted.
1242+ if interrupt != nil {
1243+ return
1244+ }
1245+
1246+ // We've made it all the way to the root of the tree, which means
1247+ // the tree has fully evaluated.
1248+ if head == nil {
1249+ var cbArg Any = nil
1250+ if fail != nil {
1251+ cbArg = fail
1252+ } else {
1253+ cbArg = step
1254+ }
1255+ cb.(func(Any) Any)(cbArg).(func() Any)()
1256+ return
1257+ }
1258+
1259+ if head._3 != Empty {
1260+ return
1261+ }
1262+
1263+ switch head.tag {
1264+
1265+ case "ParMap":
1266+ Trace("Eating ParMap")
1267+ if fail == nil {
1268+ // Unwrap the Right and apply the function in the map and
1269+ // stick it back in a Right
1270+ head._3 = right(head._1.(func(Any) Any)(fromRight(step)))
1271+ step = head._3
1272+ } else {
1273+ head._3 = fail
1274+ }
1275+ case "ParApply":
1276+ Trace("Eating ParApply")
1277+ lhs = head._1.(*AbstractAff)._3
1278+ rhs = head._2.(*AbstractAff)._3
1279+ // If we have a failure we should kill the other side because we
1280+ // can't possible yield a result anymore.
1281+ if fail != nil {
1282+ head._3 = fail
1283+ tmp = true
1284+ kid = killID
1285+ killID++
1286+
1287+ var someTmp Any
1288+ if isLeft(lhs).(bool) && (fromLeft(fail) == fromLeft(lhs)) {
1289+ someTmp = head._2
1290+ } else {
1291+ someTmp = head._1
1292+ }
1293+ kills.Store(kid.(int), kill(early.(error), someTmp.(*AbstractAff), func(unused Any) Any {
1294+ return func() Any {
1295+ kills.Delete(kid.(int))
1296+ if tmp.(bool) {
1297+ tmp = false
1298+ } else if tail == nil {
1299+ join(fail, nil)
1300+ } else {
1301+ join(fail, tail)
1302+ }
1303+ return nil
1304+ }
1305+ }))
1306+
1307+ if tmp != nil {
1308+ tmp = false
1309+ return
1310+ }
1311+ } else if lhs == Empty || rhs == Empty {
1312+ // We can only proceed if both sides have resolved.
1313+ Trace("One side EMPTY", lhs, rhs)
1314+ return
1315+ } else {
1316+ Trace("Both sides not EMPTY", lhs, rhs)
1317+ step = right(fromRight(lhs).(Fn1)(fromRight(rhs)))
1318+ head._3 = step
1319+ }
1320+ case "ParAlt":
1321+ lhs = head._1.(*AbstractAff)._3
1322+ rhs = head._2.(*AbstractAff)._3
1323+ // We can only proceed if both have resolved or we have a success
1324+ if lhs == Empty && isLeft(rhs).(bool) || rhs == Empty && isLeft(lhs).(bool) {
1325+ return
1326+ }
1327+ // If both sides resolve with an error, we should continue with the
1328+ // first error
1329+ if lhs != Empty && isLeft(lhs).(bool) && rhs != Empty && isLeft(rhs).(bool) {
1330+ var tmpStep Any
1331+ if step == lhs {
1332+ tmpStep = rhs
1333+ } else {
1334+ tmpStep = lhs
1335+ }
1336+ fail = &tmpStep
1337+ step = nil
1338+ head._3 = fail
1339+ } else {
1340+ head._3 = step
1341+ tmp = true
1342+ kid = killID
1343+ killID++
1344+ // Once a side has resolved, we need to cancel the side that is still
1345+ // pending before we can continue.
1346+ var headArg Any
1347+ if &step == &lhs {
1348+ headArg = head._2
1349+ } else {
1350+ headArg = head._1
1351+ }
1352+ kills.Store(kid.(int), kill(early.(error), headArg.(*AbstractAff), func(unused Any) Any {
1353+ return func() Any {
1354+ kills.Delete(kid.(int))
1355+ if tmp.(bool) {
1356+ tmp = false
1357+ } else if tail == nil {
1358+ join(step, nil)
1359+ } else {
1360+ join(step, tail)
1361+ }
1362+ return nil
1363+ }
1364+ }))
1365+
1366+ if tmp.(bool) {
1367+ tmp = false
1368+ return
1369+ }
1370+ }
1371+ }
1372+
1373+ if tail == nil {
1374+ head = nil
1375+ } else {
1376+ head = tail.head.(*AbstractAff)
1377+ tail = tail.tail
1378+ }
1379+
1380+ }
1381+ }
1382+
1383+ resolve := func(fiber *AbstractAff) Any {
1384+ return func(result Any) Any {
1385+ return func() Any {
1386+ Trace("Resolving fiber ", fiber._1.(int))
1387+ fibers.Delete(fiber._1.(int))
1388+ fiber._3 = result
1389+ join(result, fiber._2.(*Cons))
1390+ return nil
1391+ }
1392+ }
1393+ }
1394+
1395+ // Walks the applicative tree, substituting non-applicative nodes with
1396+ // `FORKED` nodes. In this tree, all applicative nodes use the `_3` slot
1397+ // as a mutable slot for memoization. In an unresolved state, the `_3`
1398+ // slot is `EMPTY`. In the cases of `ALT` and `APPLY`, we always walk
1399+ // the left side first, because both operations are left-associative. As
1400+ // we `RETURN` from those branches, we then walk the right side.
1401+
1402+ run := func() {
1403+ Trace(Green("Run"))
1404+ status := CONTINUE
1405+ step := par
1406+ var head *AbstractAff = nil
1407+ var tail *Cons = nil
1408+ var tmp Any = nil
1409+ fid := 0
1410+
1411+ loop:
1412+ for {
1413+ tmp = nil
1414+ Trace(Green("\n############\nrunPar:\t", statusName(status)))
1415+ printCons(&Cons{head: head, tail: tail})
1416+ // Trace("step:\t", step)
1417+ // Trace(Green("#############\n\n"))
1418+ switch status {
1419+ case CONTINUE:
1420+ switch currentStep := step.(type) {
1421+ case AbstractAff:
1422+ switch currentStep.tag {
1423+ case "ParMap":
1424+ Trace(Green("ParMap"))
1425+ if head != nil {
1426+ tail = &Cons{head: head, tail: tail}
1427+ }
1428+ head = &AbstractAff{tag: "ParMap", _1: currentStep._1, _2: Empty, _3: Empty}
1429+ step = currentStep._2
1430+ case "ParApply":
1431+ Trace(Green("ParApply"))
1432+ if head != nil {
1433+ tail = &Cons{head: head, tail: tail}
1434+ }
1435+ head = &AbstractAff{tag: "ParApply", _1: Empty, _2: currentStep._2, _3: Empty}
1436+ step = currentStep._1
1437+ case "ParAlt":
1438+ Trace(Green("ParAlt"))
1439+ if head != nil {
1440+ tail = &Cons{head: head, tail: tail}
1441+ }
1442+ head = &AbstractAff{tag: "ParAlt", _1: Empty, _2: currentStep._2, _3: Empty}
1443+ step = currentStep._1
1444+ default:
1445+ panic(errors.New("Unexpected case " + currentStep.tag))
1446+ }
1447+ default:
1448+ Trace(Green("default, step: ", currentStep))
1449+ // When we hit a leaf value, we suspend the stack in the `FORKED`.
1450+ // When the fiber resolves, it can bubble back up the tree.
1451+ fid = fiberID
1452+ fiberID++
1453+ status = RETURN
1454+ tmp = step
1455+ step = &AbstractAff{tag: "Forked", _1: fid, _2: &Cons{head: head, tail: tail}, _3: Empty}
1456+ tmp = mkFiber(util, supervisor, tmp)
1457+ tmp.(Fiber)["onComplete"].(func(Dict) Any)(OnComplete{
1458+ "rethrow": false,
1459+ "handler": resolve(step.(*AbstractAff)).(func(Any) Any),
1460+ }).(EffFn)()
1461+ fibers.Store(fid, tmp.(Fiber))
1462+ if supervisor != nil {
1463+ supervisor.register(tmp.(Fiber))
1464+ }
1465+ }
1466+ case RETURN:
1467+ // Terminal case. We are back at the root
1468+ if head == nil {
1469+ break loop
1470+ }
1471+ // If we are done with the right side, we need to continue down the
1472+ // left. Otherwise we should continue up the stack.
1473+
1474+ if head._1 == Empty {
1475+ Trace("Head._1 is empty")
1476+ head._1 = step
1477+ status = CONTINUE
1478+ step = head._2
1479+ head._2 = Empty
1480+ } else {
1481+ Trace("Head._1 is not empty")
1482+ head._2 = step
1483+ step = head
1484+ if tail == nil {
1485+ head = nil
1486+ } else {
1487+ head = tail.head.(*AbstractAff)
1488+ tail = tail.tail
1489+ }
1490+ }
1491+ }
1492+ }
1493+ // Keep a reference to the tree root so it can be cancelled.
1494+ root = step
1495+
1496+ for fid = 0; fid < fiberID; fid++ {
1497+ Trace(Magenta("Running fiber ", fid))
1498+ Trace("Id", fid)
1499+ fiber, ok := fibers.Load(fid)
1500+ if !ok {
1501+ Trace(fibers.internal)
1502+ } else {
1503+ runFn := fiber.(Dict)["run"].(func() Any)
1504+ // [TODO] How about some real parallelism with `go` here?
1505+ // Well no luck due to "concurrent map writes"
1506+ go runFn()
1507+ }
1508+ }
1509+
1510+ }
1511+
1512+ // Cancels the entire tree. If there are already subtrees being canceled,
1513+ // we need to first cancel those joins. We will then add fresh joins for
1514+ // all pending branches including those that were in the process of being
1515+ // canceled
1516+ cancel := func(cancelErr error, cb K) Any {
1517+ interrupt = left(cancelErr)
1518+ kills.RWMutex.RLock()
1519+ for innerKillID := range kills.internal {
1520+ innerKillsV, ok := kills.Load(innerKillID)
1521+ innerKills := innerKillsV.(*IntMap)
1522+ innerKills.RWMutex.RLock()
1523+ if ok {
1524+ for innerKillID := range innerKills.internal {
1525+ innerKill, ok := innerKills.Load(innerKillID)
1526+ if ok {
1527+ innerKill.(EffFn)()
1528+ }
1529+ }
1530+ }
1531+ innerKills.RWMutex.RUnlock()
1532+ }
1533+ kills.RWMutex.RUnlock()
1534+ kills = nil
1535+ newKills := kill(cancelErr, root.(*AbstractAff), cb)
1536+
1537+ return func(killError Any) Any {
1538+ return Async{asyncFn: func(killCb K) Any {
1539+ return func() Any {
1540+ for _, killFn := range newKills.(map[Any]Any) {
1541+ killFn.(EffFn)()
1542+ }
1543+ return nonCanceler
1544+ }
1545+ }}
1546+ }
1547+ }
1548+
1549+ run()
1550+
1551+ return func(killError Any) Any {
1552+ return Async{asyncFn: func(k K) Any {
1553+ return func() Any {
1554+ return cancel(killError.(error), k)
1555+ }
1556+ }}
1557+ }
1558+
1559+}
1560+
1561+func init() {
1562+ exports := Foreign("Effect.Aff")
1563+
1564+ // ∷ ∀ a b. Aff a → (a → Aff b) → Aff b
1565+ exports["_pure"] = func(value Any) Any {
1566+ return Pure{Pure: true, value: value}
1567+ }
1568+ // ∷ ∀ a. Error → Aff a
1569+ exports["_throwError"] = func(e_ Any) Any {
1570+ e := e_.(error)
1571+ return Throw{Throw: true, err: e}
1572+ }
1573+ // ∷ ∀ a. Aff a → (Error → Aff a) → Aff a
1574+ exports["_catchError"] = func(aff Any) Any {
1575+ return func(k Any) Any {
1576+ return Catch{aff: aff, errorToAff: k.(func(Any) Any)}
1577+ }
1578+ }
1579+ // ∷ ∀ a b. (a → b) → Aff a → Aff b
1580+ exports["_map"] = func(f_ Any) Any {
1581+ Trace(Yellow("map"))
1582+ f := f_.(func(Any) Any)
1583+ return func(aff Any) Any {
1584+ switch a := aff.(type) {
1585+ case Pure:
1586+ return Pure{Pure: true, value: f(a.value)}
1587+ default:
1588+ return Bind{
1589+ Bind: true,
1590+ affOfB: aff,
1591+ bToAff: func(b Any) Any { return Pure{Pure: true, value: f(b)} }}
1592+ }
1593+ }
1594+ }
1595+
1596+ // ∷ ∀ a b. Aff a → (a → Aff b) → Aff b
1597+ exports["_bind"] = func(aff Any) Any {
1598+ Trace(Yellow("bind"))
1599+ return func(f_ Any) Any {
1600+ f := f_.(func(Any) Any)
1601+ bToAff := func(b Any) Any { return f(b) }
1602+ return Bind{affOfB: aff, bToAff: bToAff}
1603+ }
1604+ }
1605+
1606+ exports["_fork"] = func(immediate Any) Any {
1607+ return func(aff Any) Any {
1608+ return Fork{
1609+ immediate: immediate.(bool),
1610+ affOfB: aff,
1611+ }
1612+ }
1613+ }
1614+
1615+ // ∀ a. Effect a → Aff a
1616+ exports["_liftEffect"] = func(effect_ Any) Any {
1617+ effect := effect_.(func() Any)
1618+ return Sync{Sync: true, eff: effect}
1619+ }
1620+
1621+ exports["_parAffMap"] = func(f Any) Any {
1622+ return func(aff Any) Any {
1623+ return AbstractAff{tag: "ParMap", _1: f, _2: aff}
1624+ }
1625+ }
1626+
1627+ exports["_parAffApply"] = func(aff1 Any) Any {
1628+ return func(aff2 Any) Any {
1629+ return AbstractAff{tag: "ParApply", _1: aff1, _2: aff2}
1630+ }
1631+ }
1632+
1633+ exports["_parAffAlt"] = func(aff1 Any) Any {
1634+ return func(aff2 Any) Any {
1635+ return AbstractAff{tag: "ParAlt", _1: aff1, _2: aff2}
1636+ }
1637+ }
1638+
1639+ // ∷ ∀ a. Fn.Fn2 FFIUtil (Aff a) (Effect (Fiber a))
1640+ exports["_makeFiber"] = func(util Any, aff Any) Any {
1641+ return func() Any {
1642+ return mkFiber(util, nil, aff)
1643+ }
1644+ }
1645+
1646+ // ∷ ∀ a. Fn.Fn2 FFIUtil (Aff a) (Effect (Fiber a))
1647+ exports["_makeSupervisedFiber"] = func(util Any, aff Any) Any {
1648+ return func() Any {
1649+ supervisor := mkSupervisor(util)
1650+ return Dict{
1651+ "fiber": mkFiber(util, &supervisor, aff),
1652+ "supervisor": supervisor,
1653+ }
1654+ }
1655+ }
1656+
1657+ // Fn.Fn3 Error Supervisor (Effect Unit) (Effect Canceler)
1658+ exports["_killAll"] = func(err_ Any, supervisor_ Any, cb_ Any) Any {
1659+ supervisor := supervisor_.(Supervisor)
1660+ cb := cb_.(func() Any)
1661+ err := err_.(error)
1662+ return supervisor.killAll(err, cb)
1663+ }
1664+
1665+ // ∀ a. Fn.Fn2 (Unit → Either a Unit) Number (Aff Unit)
1666+ exports["_delay"] = (func() Any {
1667+
1668+ setDelay := func(duration time.Duration, k func()) *time.Timer {
1669+ return time.AfterFunc(duration, k)
1670+ }
1671+
1672+ clearDelay := func(timer *time.Timer) {
1673+ if timer != nil {
1674+ if !timer.Stop() {
1675+ <-timer.C
1676+ }
1677+ }
1678+ }
1679+
1680+ return func(right_ Any, millis_ Any) Any {
1681+ right := right_.(func(Any) Any)
1682+ var millis int = int(millis_.(float64))
1683+ return Async{
1684+ asyncFn: func(cb K) Any {
1685+ return func() Any {
1686+ duration := time.Duration(millis) * time.Millisecond
1687+ k := Apply(cb, right(nil))
1688+ t1 := time.Now()
1689+ timer := setDelay(duration, func() {
1690+ Trace("Done after: ", time.Now().Sub(t1))
1691+ k.(func() Any)()
1692+ })
1693+ return func(err Any) Any {
1694+ Trace(Magenta("Almost canceling delay"))
1695+ return Sync{eff: func() Any {
1696+ // Trace(Magenta("Canceling delay"))
1697+ clearDelay(timer)
1698+ return right(nil)
1699+ }}
1700+ }
1701+ }
1702+ },
1703+ }
1704+ }
1705+ })()
1706+
1707+ exports["makeAff"] = func(asyncFn Any) Any {
1708+ Trace("I'm making an aff")
1709+ return Async{asyncFn: asyncFn}
1710+ }
1711+
1712+ exports["generalBracket"] = func(acquire Any) Any {
1713+ return func(options Any) Any {
1714+ bracketConditions := options.(Dict)
1715+ return func(k_ Any) Any {
1716+ k := k_.(func(Any) Any)
1717+ return Bracket{
1718+ acquire: acquire,
1719+ bracketConditions: bracketConditions,
1720+ k: k,
1721+ }
1722+ }
1723+ }
1724+ }
1725+
1726+ // ParAff ~> Aff
1727+ exports["_sequential"] = func(aff Any) Any {
1728+ return Sequential{parAff: aff}
1729+ }
1730+
1731+}
1732+
1733+type IntMap struct {
1734+ sync.RWMutex
1735+ internal map[int]Any
1736+}
1737+
1738+func NewRegularIntMap() *IntMap {
1739+ return &IntMap{
1740+ internal: make(map[int]Any),
1741+ }
1742+}
1743+
1744+func (rm *IntMap) Load(key int) (value Any, ok bool) {
1745+ rm.RLock()
1746+ result, ok := rm.internal[key]
1747+ rm.RUnlock()
1748+ return result, ok
1749+}
1750+
1751+func (rm *IntMap) Delete(key int) {
1752+ Trace(Red("Deleting key ", key))
1753+ rm.Lock()
1754+ delete(rm.internal, key)
1755+ rm.Unlock()
1756+}
1757+
1758+func (rm *IntMap) Store(key int, value Any) {
1759+ Trace(Green("Storing key ", key))
1760+ rm.Lock()
1761+ rm.internal[key] = value
1762+ rm.Unlock()
1763+}
packages/core/ffi/purescript-debug/Debug.gonew file+84
@@ -0,0 +1,84 @@
1+package purescript_debug
2+
3+import (
4+ "fmt"
5+ "reflect"
6+ "strconv"
7+
8+ . "github.com/purescript-native/go-runtime"
9+)
10+
11+func init() {
12+ exports := Foreign("Debug")
13+
14+ exports["_spy"] = func(str_ Any, value_ Any) Any {
15+ str := str_.(string)
16+ fmt.Printf("%v", str)
17+ display(0, "", reflect.ValueOf(value_))
18+ return value_
19+ }
20+
21+}
22+
23+func display(depth int, path string, v reflect.Value) {
24+ if depth > 4 {
25+ return
26+ }
27+ switch v.Kind() {
28+ case reflect.Invalid:
29+ fmt.Printf("%s = invalid\n", path)
30+ case reflect.Slice, reflect.Array:
31+ for i := 0; i < v.Len(); i++ {
32+ display(depth+1, fmt.Sprintf("%s[%d]", path, i), v.Index(i))
33+ }
34+ case reflect.Struct:
35+ for i := 0; i < v.NumField(); i++ {
36+ fieldPath := fmt.Sprintf("%s.%s", path, v.Type().Field(i).Name)
37+ display(depth+1, fieldPath, v.Field(i))
38+ }
39+ case reflect.Map:
40+ for _, key := range v.MapKeys() {
41+ display(depth+1, fmt.Sprintf("%s[%s]", path,
42+ formatAtom(key)), v.MapIndex(key))
43+ }
44+ case reflect.Ptr:
45+ if v.IsNil() {
46+ fmt.Printf("%s = nil\n", path)
47+ } else {
48+ display(depth+1, fmt.Sprintf("(*%s)", path), v.Elem())
49+ }
50+ case reflect.Interface:
51+ if v.IsNil() {
52+ fmt.Printf("%s = nil\n", path)
53+ } else {
54+ fmt.Printf("%s.type = %s\n", path, v.Elem().Type())
55+ display(depth+1, path+".value", v.Elem())
56+ }
57+ default: // basic types, channels, funcs
58+ fmt.Printf("%s = %s\n", path, formatAtom(v))
59+ }
60+}
61+
62+// formatAtom formats a value without inspecting its internal structure.
63+func formatAtom(v reflect.Value) string {
64+ switch v.Kind() {
65+ case reflect.Invalid:
66+ return "invalid"
67+ case reflect.Int, reflect.Int8, reflect.Int16,
68+ reflect.Int32, reflect.Int64:
69+ return strconv.FormatInt(v.Int(), 10)
70+ case reflect.Uint, reflect.Uint8, reflect.Uint16,
71+ reflect.Uint32, reflect.Uint64, reflect.Uintptr:
72+ return strconv.FormatUint(v.Uint(), 10)
73+ // ...floating-point and complex cases omitted for brevity...
74+ case reflect.Bool:
75+ return strconv.FormatBool(v.Bool())
76+ case reflect.String:
77+ return strconv.Quote(v.String())
78+ case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Slice, reflect.Map:
79+ return v.Type().String() + " 0x" +
80+ strconv.FormatUint(uint64(v.Pointer()), 16)
81+ default: // reflect.Array, reflect.Struct, reflect.Interface
82+ return v.Type().String() + " value"
83+ }
84+}
packages/core/ffi/purescript-go-dhall-golang/DhallGolang.gonew file+273
@@ -0,0 +1,273 @@
1+package purescript_go_dhall_golang
2+
3+import (
4+ "errors"
5+ "fmt"
6+ "reflect"
7+
8+ "github.com/philandstuff/dhall-golang/v6/parser"
9+ "github.com/philandstuff/dhall-golang/v6/term"
10+ . "github.com/purescript-native/go-runtime"
11+)
12+
13+func init() {
14+ exports := Foreign("Dhall.Golang")
15+
16+ exports["parseSpagoDhall_"] = func(left Any, right Any, just Any, nothing Any, path_ Any) Any {
17+
18+ var errs []Any
19+ path := path_.(string)
20+
21+ res, err := parser.ParseFile(path)
22+ if err != nil {
23+ errs = append(errs, errors.New("Could not parse file "+path))
24+ return Apply(left, errs)
25+ }
26+ result := Dict{}
27+ switch root := res.(type) {
28+ case term.RecordLit:
29+
30+ // name
31+ name, err := parseString("name", root["name"])
32+ if err != nil {
33+ errs = append(errs, err)
34+ }
35+ result["name"] = name
36+
37+ // dependencies
38+ dependencies, err := parseStringArray("dependencies", root["dependencies"])
39+ if err != nil {
40+ errs = append(errs, err)
41+ }
42+ result["dependencies"] = dependencies
43+
44+ // packages
45+ packages, err := parseImportAsString("packages", root["packages"])
46+ if err != nil {
47+ errs = append(errs, err)
48+ }
49+ result["packages"] = packages
50+
51+ // sources
52+ sources, err := parseStringArray("sources", root["sources"])
53+ if err != nil {
54+ errs = append(errs, err)
55+ }
56+ result["sources"] = sources
57+
58+ default:
59+ errs = append(errs, errors.New(path+" is a valid .dhall file but does not have a record at the top-level"))
60+
61+ }
62+ if errs != nil && len(errs) != 0 {
63+ return Apply(left, errs)
64+ }
65+ fmt.Println(result)
66+ return Apply(right, result)
67+ }
68+
69+ exports["parsePackagesDhall_"] = func(left Any, right Any, just Any, nothing Any, path_ Any) Any {
70+
71+ var errs []Any
72+ path := path_.(string)
73+
74+ res, err := parser.ParseFile(path)
75+ if err != nil {
76+ errs = append(errs, errors.New("Could not parse file "+path))
77+ return Apply(left, errs)
78+ }
79+ result := Dict{}
80+ fmt.Println(reflect.TypeOf(res))
81+ switch lets := res.(type) {
82+ case term.Let:
83+
84+ var mkPackage Any = nil
85+ var upstream Any = nil
86+ var additions Any = nil
87+ for _, binding := range lets.Bindings {
88+ switch binding.Variable {
89+
90+ case "mkPackage":
91+ url, err := parseImportAsString("mkPackage", binding.Value)
92+ if err != nil {
93+ // [TODO]: There could be some malformed shit
94+ // errs = append(errs, err)
95+ mkPackage = nothing
96+ } else {
97+ mkPackage = Apply(just, Dict{"url": *url})
98+ }
99+
100+ case "upstream":
101+ url, err := parseImportAsString("upstream", binding.Value)
102+ if err != nil {
103+ errs = append(errs, err)
104+ }
105+ if url != nil {
106+ upstream = Dict{"url": *url}
107+ }
108+ fmt.Println("\n\n\n\n", binding, "\n\n\n")
109+
110+ case "additions":
111+ var adds []Any = nil
112+ err := parseRecord("additions", binding.Value, func(rec term.RecordLit) {
113+ for name, addition := range rec {
114+ local, localErr := parseLocalDep("addition "+name, addition)
115+ if localErr != nil {
116+ // parse the alternative
117+ mkPackage, mkPackageErr := parseMkPackage("addition "+name, addition)
118+ if mkPackageErr != nil {
119+ errs = append(errs, mkPackageErr)
120+ errs = append(errs, localErr)
121+ } else { // isMkPackage
122+ adds = append(adds, Apply(right, mkPackage))
123+ }
124+ } else { // isLocal
125+ adds = append(adds, Apply(left, local))
126+ }
127+ }
128+ })
129+ if err != nil {
130+ errs = append(errs, err)
131+ }
132+ if additions != nil {
133+ additions = adds
134+ }
135+
136+ default:
137+ errs = append(errs, errors.New("Unexpected binding "+binding.Variable))
138+ }
139+
140+ }
141+ if mkPackage == nil {
142+ errs = append(errs, errors.New("Missing binding mkPackage"))
143+ } else {
144+ result["mkPackage"] = mkPackage
145+ }
146+ if upstream == nil {
147+ errs = append(errs, errors.New("Missing binding upstream"))
148+ } else {
149+ result["upstream"] = upstream
150+ }
151+ if additions == nil {
152+ errs = append(errs, errors.New("Missing binding additions"))
153+ } else {
154+ result["additions"] = additions
155+ }
156+
157+ // fmt.Println(lets, reflect.TypeOf(lets))
158+ default:
159+ errs = append(errs, errors.New(path+" is a valid .dhall file but does not have the required bindings mkPackage, upstream, and additions"))
160+ }
161+ fmt.Println(result)
162+ if errs != nil && len(errs) != 0 {
163+ return Apply(left, errs)
164+ }
165+ return Apply(right, result)
166+ }
167+
168+}
169+
170+func parseLocalDep(keyName string, t term.Term) (*string, error) {
171+ return parseImportAsString(keyName, t)
172+}
173+
174+func parseMkPackage(keyName string, t term.Term) (Dict, error) {
175+ result := Dict{}
176+ // Parses from right to left
177+ versionApp, versionAppErr := parseApp("version", t)
178+ if versionAppErr != nil {
179+ return nil, versionAppErr
180+ }
181+ version, versionErr := parseString("version", versionApp.Fn)
182+ if versionAppErr != nil {
183+ return nil, versionErr
184+ }
185+ result["version"] = version
186+
187+ addressApp, addressAppErr := parseApp("address", versionApp.Arg)
188+ if addressAppErr != nil {
189+ return nil, addressAppErr
190+ }
191+ address, addressErr := parseString("address", addressApp.Fn)
192+ if addressErr != nil {
193+ return nil, addressErr
194+ }
195+ result["address"] = address
196+
197+ dependenciesApp, dependenciesAppErr := parseApp("dependencies", addressApp.Arg)
198+ if dependenciesAppErr != nil {
199+ return nil, dependenciesAppErr
200+ }
201+ dependencies, dependenciesErr := parseStringArray("dependencies", dependenciesApp.Fn)
202+ if dependenciesErr != nil {
203+ return nil, dependenciesErr
204+ }
205+ result["dependencies"] = dependencies
206+
207+ fnNameApp, fnNameAppErr := parseApp("function name", dependenciesApp.Arg)
208+ if fnNameAppErr != nil {
209+ return nil, fnNameAppErr
210+ }
211+ fnName, fnNameErr := parseString("function name", fnNameApp.Fn)
212+ if fnNameErr != nil {
213+ return nil, fnNameErr
214+ }
215+ if *fnName != "mkPackage" {
216+ return nil, errors.New("Used function " + *fnName + " instead of mkFunction")
217+ }
218+
219+ return result, nil
220+}
221+
222+func parseApp(keyName string, t term.Term) (*term.App, error) {
223+ value, isApp := t.(term.App)
224+ if !isApp {
225+ return nil, errors.New(keyName + " is not a function application")
226+ }
227+ return &value, nil
228+}
229+
230+func parseRecord(keyName string, t term.Term, parse func(term.RecordLit)) error {
231+ valueRec, valueIsRecord := t.(term.RecordLit)
232+ if !valueIsRecord {
233+ return errors.New(keyName + " is not a record")
234+ }
235+ parse(valueRec)
236+ return nil
237+}
238+
239+func parseImportAsString(keyName string, t term.Term) (*string, error) {
240+ valueLit, valueIsImport := t.(term.Import)
241+ if !valueIsImport {
242+ return nil, errors.New(keyName + " is not an import")
243+ }
244+ n := valueLit.String()
245+ return &n, nil
246+}
247+
248+func parseString(keyName string, t term.Term) (*string, error) {
249+ valueLit, valueIsString := t.(term.TextLit)
250+ if !valueIsString {
251+ return nil, errors.New(keyName + " is not a string")
252+ }
253+ n := valueLit.String()
254+ return &n, nil
255+}
256+
257+func parseStringArray(name string, t term.Term) (*[]string, error) {
258+ nonEmpty, isNonEmpty := t.(term.NonEmptyList)
259+ _, isEmpty := t.(term.EmptyList)
260+ if !isNonEmpty && !isEmpty {
261+ return nil, errors.New(name + " is neither empty nor non-empty")
262+ }
263+ length := len(nonEmpty)
264+ dependencies := make([]string, length)
265+ for idx, dep := range nonEmpty {
266+ str, ok := dep.(term.TextLit)
267+ if !ok {
268+ return nil, errors.New(name + "Encountered non string in dependencies")
269+ }
270+ dependencies[idx] = str.String()
271+ }
272+ return &dependencies, nil
273+}
packages/core/ffi/purescript-go-gin/Gin.gonew file+116
@@ -0,0 +1,116 @@
1+package purescript_go_gin
2+
3+import (
4+ "net/http"
5+
6+ "github.com/gin-gonic/gin"
7+ "github.com/gin-gonic/gin/binding"
8+ . "github.com/purescript-native/go-runtime"
9+)
10+
11+func init() {
12+ exports := Foreign("Gin")
13+
14+ exports["mkDefaultGin"] = func() Any {
15+ return gin.Default()
16+ }
17+
18+ exports["mkHandler"] =
19+ func(handler_ Any) Any {
20+ return func(c *gin.Context) {
21+ Apply(handler_, c)
22+ }
23+ }
24+
25+ exports["staticImpl"] = func(r_ Any) Any {
26+ return func(route_ Any) Any {
27+ return func(path_ Any) Any {
28+ return func() Any {
29+ route := route_.(string)
30+ path := path_.(string)
31+ r := r_.(*gin.Engine)
32+ r.Static(route, path)
33+ return nil
34+ }
35+ }
36+ }
37+ }
38+
39+ exports["noRouteImpl"] = func(r_ Any) Any {
40+ return func(handler_ Any) Any {
41+ return func() Any {
42+ r := r_.(*gin.Engine)
43+ handler := handler_.(func(*gin.Context))
44+ r.NoRoute(handler)
45+ return nil
46+ }
47+ }
48+ }
49+
50+ exports["getBodyImpl"] = func(ctx_ Any) Any {
51+ ctx := ctx_.(*gin.Context)
52+ var b Dict
53+ ctx.ShouldBindBodyWith(&b, binding.JSON)
54+ return b
55+ }
56+
57+ exports["sendNoContentImpl"] =
58+ func(ctx_ Any) Any {
59+ ctx := ctx_.(*gin.Context)
60+ ctx.Status(http.StatusNoContent)
61+ return nil
62+ }
63+
64+ exports["sendJsonImpl"] =
65+ func(code_ Any, body_ Any, ctx_ Any) Any {
66+ ctx := ctx_.(*gin.Context)
67+ code := code_.(int)
68+ body := body_.(Dict)
69+ ctx.JSON(code, body)
70+ return nil
71+ }
72+
73+ exports["sendFileImpl"] = func(path_ Any) Any {
74+ return func(ctx_ Any) Any {
75+ ctx := ctx_.(*gin.Context)
76+ path := path_.(string)
77+ ctx.File(path)
78+ return nil
79+ }
80+ }
81+
82+ exports["getImpl"] = func(r_ Any) Any {
83+ return func(path_ Any) Any {
84+ return func(handler_ Any) Any {
85+ return func() Any {
86+ r := r_.(*gin.Engine)
87+ path := path_.(string)
88+ handler := handler_.(func(*gin.Context))
89+ r.GET(path, handler)
90+ return nil
91+ }
92+ }
93+ }
94+ }
95+
96+ exports["postImpl"] = func(r_ Any) Any {
97+ return func(path_ Any) Any {
98+ return func(handler_ Any) Any {
99+ return func() Any {
100+ r := r_.(*gin.Engine)
101+ path := path_.(string)
102+ handler := handler_.(func(*gin.Context))
103+ r.POST(path, handler)
104+ return nil
105+ }
106+ }
107+ }
108+ }
109+
110+ exports["runImpl"] = func(r_ Any) Any {
111+ r := r_.(*gin.Engine)
112+ r.Run()
113+ return nil
114+ }
115+
116+}
packages/core/ffi/purescript-go-glsp/Go_LanguageServerProtocol.gonew file+110
@@ -0,0 +1,110 @@
1+package purescript_go_language_server_protocol
2+
3+import (
4+ "fmt"
5+ "reflect"
6+ "strconv"
7+
8+ "github.com/tliron/glsp"
9+
10+ protocol "github.com/tliron/glsp/protocol_3_16"
11+ serverpkg "github.com/tliron/glsp/server"
12+
13+ . "github.com/purescript-native/go-runtime"
14+)
15+
16+func init() {
17+ exports := Foreign("Go.LanguageServerProtocol")
18+
19+ // EffectFn3
20+ exports["newServerImpl"] = func(handler Any, logBaseName Any, debug Any) Any {
21+ return serverpkg.NewServer(handler, logBaseName, debug)
22+ }
23+
24+ exports["newHandlerImpl"] = func(fn Any) {
25+ var handler = protocol.Handler
26+ handler.Initialize = func(context *glsp.Context, params *protocol.InitializeParams) (interface{}, error) {
27+ clientCapabilities = &params.Capabilities
28+
29+ if params.Trace != nil {
30+ protocol.SetTraceValue(*params.Trace)
31+ }
32+
33+ serverCapabilities := Handler.CreateServerCapabilities()
34+ serverCapabilities.TextDocumentSync = protocol.TextDocumentSyncKindIncremental
35+ serverCapabilities.CompletionProvider = &protocol.CompletionOptions{}
36+
37+ return &protocol.InitializeResult{
38+ Capabilities: serverCapabilities,
39+ ServerInfo: &protocol.InitializeResultServerInfo{
40+ Name: "puccini-language-server",
41+ Version: &version.GitVersion,
42+ },
43+ }, nil
44+ }
45+ }
46+
47+}
48+
49+func display(depth int, path string, v reflect.Value) {
50+ if depth > 4 {
51+ return
52+ }
53+ switch v.Kind() {
54+ case reflect.Invalid:
55+ fmt.Printf("%s = invalid\n", path)
56+ case reflect.Slice, reflect.Array:
57+ for i := 0; i < v.Len(); i++ {
58+ display(depth+1, fmt.Sprintf("%s[%d]", path, i), v.Index(i))
59+ }
60+ case reflect.Struct:
61+ for i := 0; i < v.NumField(); i++ {
62+ fieldPath := fmt.Sprintf("%s.%s", path, v.Type().Field(i).Name)
63+ display(depth+1, fieldPath, v.Field(i))
64+ }
65+ case reflect.Map:
66+ for _, key := range v.MapKeys() {
67+ display(depth+1, fmt.Sprintf("%s[%s]", path,
68+ formatAtom(key)), v.MapIndex(key))
69+ }
70+ case reflect.Ptr:
71+ if v.IsNil() {
72+ fmt.Printf("%s = nil\n", path)
73+ } else {
74+ display(depth+1, fmt.Sprintf("(*%s)", path), v.Elem())
75+ }
76+ case reflect.Interface:
77+ if v.IsNil() {
78+ fmt.Printf("%s = nil\n", path)
79+ } else {
80+ fmt.Printf("%s.type = %s\n", path, v.Elem().Type())
81+ display(depth+1, path+".value", v.Elem())
82+ }
83+ default: // basic types, channels, funcs
84+ fmt.Printf("%s = %s\n", path, formatAtom(v))
85+ }
86+}
87+
88+// formatAtom formats a value without inspecting its internal structure.
89+func formatAtom(v reflect.Value) string {
90+ switch v.Kind() {
91+ case reflect.Invalid:
92+ return "invalid"
93+ case reflect.Int, reflect.Int8, reflect.Int16,
94+ reflect.Int32, reflect.Int64:
95+ return strconv.FormatInt(v.Int(), 10)
96+ case reflect.Uint, reflect.Uint8, reflect.Uint16,
97+ reflect.Uint32, reflect.Uint64, reflect.Uintptr:
98+ return strconv.FormatUint(v.Uint(), 10)
99+ // ...floating-point and complex cases omitted for brevity...
100+ case reflect.Bool:
101+ return strconv.FormatBool(v.Bool())
102+ case reflect.String:
103+ return strconv.Quote(v.String())
104+ case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Slice, reflect.Map:
105+ return v.Type().String() + " 0x" +
106+ strconv.FormatUint(uint64(v.Pointer()), 16)
107+ default: // reflect.Array, reflect.Struct, reflect.Interface
108+ return v.Type().String() + " value"
109+ }
110+}
packages/core/ffi/purescript-go-os/OS.gonew file+320
@@ -0,0 +1,320 @@
1+package purescript_go_os
2+
3+import (
4+ "bytes"
5+ "fmt"
6+ "io/ioutil"
7+ "os"
8+ "os/exec"
9+ "path/filepath"
10+ "strconv"
11+ "time"
12+
13+ . "github.com/purescript-native/go-runtime"
14+)
15+
16+func init() {
17+ exports := Foreign("OS")
18+ exports["sleep"] = func(millis_ Any) Any {
19+ return func() Any {
20+ var millis int = int(millis_.(float64))
21+ duration := time.Duration(millis) * time.Millisecond
22+ time.Sleep(duration)
23+ return nil
24+ }
25+ }
26+
27+ exports["runEffectFn2"] = func(fn_ Any) Any {
28+ return func(a Any) Any {
29+ return func(b Any) Any {
30+ return func() Any {
31+ fn := fn_.(Fn2)
32+ return fn(a, b)
33+ }
34+ }
35+ }
36+ }
37+
38+ exports["runEffectFn3"] = func(fn_ Any) Any {
39+ return func(a Any) Any {
40+ return func(b Any) Any {
41+ return func(c Any) Any {
42+ return func() Any {
43+ fn := fn_.(Fn3)
44+ return fn(a, b, c)
45+ }
46+ }
47+ }
48+ }
49+ }
50+
51+ exports["runEffectFn4"] = func(fn_ Any) Any {
52+ return func(a Any) Any {
53+ return func(b Any) Any {
54+ return func(c Any) Any {
55+ return func(d Any) Any {
56+ return func() Any {
57+ fn := fn_.(Fn4)
58+ return fn(a, b, c, d)
59+ }
60+ }
61+ }
62+ }
63+ }
64+ }
65+
66+ exports["runEffectFn5"] = func(fn_ Any) Any {
67+ return func(a Any) Any {
68+ return func(b Any) Any {
69+ return func(c Any) Any {
70+ return func(d Any) Any {
71+ return func(e Any) Any {
72+ return func() Any {
73+ fn := fn_.(Fn5)
74+ return fn(a, b, c, d, e)
75+ }
76+ }
77+ }
78+ }
79+ }
80+ }
81+ }
82+
83+ exports["runEffectFn6"] = func(fn_ Any) Any {
84+ return func(a Any) Any {
85+ return func(b Any) Any {
86+ return func(c Any) Any {
87+ return func(d Any) Any {
88+ return func(e Any) Any {
89+ return func(f Any) Any {
90+ return func() Any {
91+ fn := fn_.(Fn6)
92+ return fn(a, b, c, d, e, f)
93+ }
94+ }
95+ }
96+ }
97+ }
98+ }
99+ }
100+ }
101+
102+ exports["runEffectFn7"] = func(fn_ Any) Any {
103+ return func(a Any) Any {
104+ return func(b Any) Any {
105+ return func(c Any) Any {
106+ return func(d Any) Any {
107+ return func(e Any) Any {
108+ return func(f Any) Any {
109+ return func(g Any) Any {
110+ return func() Any {
111+ fn := fn_.(Fn7)
112+ return fn(a, b, c, d, e, f, g)
113+ }
114+ }
115+ }
116+ }
117+ }
118+ }
119+ }
120+ }
121+ }
122+
123+ exports["runEffectFn8"] = func(fn_ Any) Any {
124+ return func(a Any) Any {
125+ return func(b Any) Any {
126+ return func(c Any) Any {
127+ return func(d Any) Any {
128+ return func(e Any) Any {
129+ return func(f Any) Any {
130+ return func(g Any) Any {
131+ return func(h Any) Any {
132+ return func() Any {
133+ fn := fn_.(Fn8)
134+ return fn(a, b, c, d, e, f, g, h)
135+ }
136+ }
137+ }
138+ }
139+ }
140+ }
141+ }
142+ }
143+ }
144+ }
145+
146+ exports["runEffectFn9"] = func(fn_ Any) Any {
147+ return func(a Any) Any {
148+ return func(b Any) Any {
149+ return func(c Any) Any {
150+ return func(d Any) Any {
151+ return func(e Any) Any {
152+ return func(f Any) Any {
153+ return func(g Any) Any {
154+ return func(h Any) Any {
155+ return func(i Any) Any {
156+ return func() Any {
157+ fn := fn_.(Fn9)
158+ return fn(a, b, c, d, e, f, g, h, i)
159+ }
160+ }
161+ }
162+ }
163+ }
164+ }
165+ }
166+ }
167+ }
168+ }
169+ }
170+
171+ exports["runEffectFn10"] = func(fn_ Any) Any {
172+ return func(a Any) Any {
173+ return func(b Any) Any {
174+ return func(c Any) Any {
175+ return func(d Any) Any {
176+ return func(e Any) Any {
177+ return func(f Any) Any {
178+ return func(g Any) Any {
179+ return func(h Any) Any {
180+ return func(i Any) Any {
181+ return func(j Any) Any {
182+ return func() Any {
183+ fn := fn_.(Fn10)
184+ return fn(a, b, c, d, e, f, g, h, i, j)
185+ }
186+ }
187+ }
188+ }
189+ }
190+ }
191+ }
192+ }
193+ }
194+ }
195+ }
196+ }
197+
198+ exports["concatPaths"] = func(args_ Any) Any {
199+ args := args_.([]Any)
200+ args2 := make([]string, len(args))
201+ for i, arg := range args {
202+ args2[i] = arg.(string)
203+ }
204+ return filepath.Join(args2...)
205+ }
206+
207+ exports["fromSlash"] = func(name_ Any) Any {
208+ name := name_.(string)
209+ return filepath.FromSlash(name)
210+ }
211+
212+ exports["writeStringToFileImpl"] = func(just Any, nothing Any, toWrite_ Any, filePath_ Any) Any {
213+ filePath := filePath_.(string)
214+ toWrite := toWrite_.(string)
215+ fileHandle, err := os.Create(filePath)
216+ if err != nil {
217+ return Apply(just, err.Error())
218+ }
219+ defer fileHandle.Close()
220+ _, err = fileHandle.WriteString(toWrite)
221+ if err != nil {
222+ return Apply(just, err.Error())
223+ }
224+ fileHandle.Sync()
225+ return nothing
226+ }
227+
228+ exports["mkdirAllImpl"] = func(just Any, nothing Any, path_ Any) Any {
229+ path := path_.(string)
230+ err := os.MkdirAll(path, os.ModePerm)
231+ if err != nil {
232+ return Apply(just, err.Error())
233+ }
234+ return nothing
235+
236+ }
237+
238+ exports["folderExistsImpl"] = func(folderName_ Any) Any {
239+ folderName := folderName_.(string)
240+ info, err := os.Stat(folderName)
241+ if os.IsNotExist(err) || !info.IsDir() {
242+ return false
243+ }
244+ return true
245+ }
246+
247+ exports["fileExistsImpl"] = func(fileName_ Any) Any {
248+ fileName := fileName_.(string)
249+ info, err := os.Stat(fileName)
250+ if os.IsNotExist(err) || info.IsDir() {
251+ return false
252+ }
253+ return true
254+ }
255+
256+ exports["lookPathImpl"] =
257+ func(just Any, nothing Any, name_ Any) Any {
258+ name := name_.(string)
259+ res, err := exec.LookPath(name)
260+ if err != nil {
261+ return nothing
262+ }
263+ return Apply(just, res)
264+ }
265+
266+ exports["readFileAsStringImpl"] = func(left Any, right Any, path_ Any) Any {
267+ path := path_.(string)
268+ dat, err := ioutil.ReadFile(path)
269+ if err != nil {
270+ return Apply(left, err.Error())
271+ }
272+ return Apply(right, string(dat))
273+ }
274+
275+ exports["execImpl"] =
276+ func(left Any, right Any, mkResult Any, name_ Any, args_ Any) Any {
277+ name := name_.(string)
278+ args := args_.([]Any)
279+ args2 := make([]string, len(args))
280+ for i, arg := range args {
281+ args2[i] = arg.(string)
282+ }
283+
284+ cmd := exec.Command(name, args2...)
285+ fmt.Printf("Cmd %v \n", cmd)
286+
287+ var stdout, stderr bytes.Buffer
288+ cmd.Stdout = &stdout
289+ cmd.Stderr = &stderr
290+
291+ err := cmd.Run()
292+ if err != nil {
293+ return Apply(left, err)
294+ }
295+ outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
296+ return Apply(right, Apply(mkResult, outStr, errStr))
297+ }
298+
299+ exports["fromStringAsImpl"] = func(just Any) Any {
300+ return func(nothing Any) Any {
301+ return func(radix_ Any) Any {
302+ return func(s_ Any) Any {
303+ radix := radix_.(int)
304+ s := s_.(string)
305+ res, err := strconv.ParseInt(s, 0, radix)
306+ if err != nil {
307+ return nothing
308+ }
309+ return Apply(just, res)
310+ }
311+ }
312+ }
313+ }
314+
315+ exports["stdinAsString"] = func() Any {
316+ bytes, _ := ioutil.ReadAll(os.Stdin)
317+ return string(bytes)
318+ }
319+
320+}
packages/core/ffi/purescript-now/Now.gonew file+16
@@ -0,0 +1,16 @@
1+package purescript_now
2+
3+import (
4+ "time"
5+
6+ . "github.com/purescript-native/go-runtime"
7+)
8+
9+func init() {
10+ exports := Foreign("Effect.Now")
11+
12+ exports["now"] = func() Any {
13+ return float64(time.Now().Unix())
14+ }
15+
16+}
packages/core/ffi/purescript-record/RecordBuilder.pursnew file

No changes to the content.

packages/core/ffi/purescript-spec/Test_Spec_Console.gonew file+19
@@ -0,0 +1,19 @@
1+package purescript_spec
2+
3+import (
4+ "os"
5+
6+ . "github.com/purescript-native/go-runtime"
7+)
8+
9+func init() {
10+ exports := Foreign("Test.Spec.Console")
11+
12+ exports["write"] = func(s_ Any) Any {
13+ return func() Any {
14+ s := s_.(string)
15+ os.Stdout.WriteString(s)
16+ return nil
17+ }
18+ }
19+}
packages/core/ffi/purescript-spec/Test_Spec_Runner.gonew file+19
@@ -0,0 +1,19 @@
1+package purescript_spec
2+
3+import (
4+ "os"
5+
6+ . "github.com/purescript-native/go-runtime"
7+)
8+
9+func init() {
10+ exports := Foreign("Test.Spec.Runner")
11+
12+ exports["exit"] = func(code_ Any) Any {
13+ return func() Any {
14+ code := code_.(int)
15+ os.Exit(code)
16+ return nil
17+ }
18+ }
19+}
packages/core/ffi/purescript-strings/Data_String_CodePoints.gonew file+94
@@ -0,0 +1,94 @@
1+package purescript_strings
2+
3+import (
4+ . "github.com/purescript-native/go-runtime"
5+ "unicode/utf8"
6+)
7+
8+func init() {
9+ exports := Foreign("Data.String.CodePoints")
10+
11+ exports["_unsafeCodePointAt0"] = func(_ Any) Any {
12+ return func(str Any) Any {
13+ r, size := utf8.DecodeRuneInString(str.(string))
14+ if r == utf8.RuneError || size == 0 {
15+ return Undefined
16+ }
17+ return int(r)
18+ }
19+ }
20+
21+ exports["_codePointAt"] = func(_ Any) Any {
22+ return func(just Any) Any {
23+ return func(nothing Any) Any {
24+ return func(unsafeCodePointAt0 Any) Any {
25+ return func(index_ Any) Any {
26+ return func(s Any) Any {
27+ index, _ := index_.(int)
28+ runes := []rune(s.(string))
29+ if index < 0 || index >= len(runes) {
30+ return nothing
31+ }
32+ result := Apply(unsafeCodePointAt0, string(runes[index]))
33+ return Apply(just, result)
34+ }
35+ }
36+ }
37+ }
38+ }
39+ }
40+
41+ exports["_countPrefix"] = func(_ Any) Any {
42+ return func(unsafeCodePointAt0 Any) Any {
43+ return func(pred Any) Any {
44+ return func(s Any) Any {
45+ runes := []rune(s.(string))
46+ i := 0
47+ for _, r := range runes {
48+ cp := Apply(unsafeCodePointAt0, string(r))
49+ cond, _ := Apply(pred, cp).(bool)
50+ if !cond {
51+ return i
52+ }
53+ i++
54+ }
55+ return i
56+ }
57+ }
58+ }
59+ }
60+
61+ exports["_singleton"] = func(_ Any) Any {
62+ return func(c Any) Any {
63+ return string(rune(c.(int)))
64+ }
65+ }
66+
67+ exports["_take"] = func(_ Any) Any {
68+ return func(n_ Any) Any {
69+ return func(s_ Any) Any {
70+ n, _ := n_.(int)
71+ s, _ := s_.(string)
72+ if n < 0 {
73+ return ""
74+ }
75+ runes := []rune(s)
76+ // return string(runes[:n])
77+ return string(runes[:min(n, len(runes))])
78+ }
79+ }
80+ }
81+
82+ exports["_toCodePointArray"] = func(_ Any) Any {
83+ return func(unsafeCodePointAt0 Any) Any {
84+ return func(s Any) Any {
85+ runes := []rune(s.(string))
86+ result := make([]Any, 0, len(runes))
87+ for _, r := range runes {
88+ result = append(result, Apply(unsafeCodePointAt0, string(r)))
89+ }
90+ return result
91+ }
92+ }
93+ }
94+}
packages/core/ffi/purescript-strings/Data_String_CodeUnits.gonew file+238
@@ -0,0 +1,238 @@
1+package purescript_strings
2+
3+import (
4+ // "fmt"
5+ . "github.com/purescript-native/go-runtime"
6+ "strings"
7+ "unicode/utf8"
8+)
9+
10+func min(a, b int) int {
11+ if a < b {
12+ return a
13+ }
14+ return b
15+}
16+
17+func max(a, b int) int {
18+ if a > b {
19+ return a
20+ }
21+ return b
22+}
23+
24+func init() {
25+ exports := Foreign("Data.String.CodeUnits")
26+
27+ exports["fromCharArray"] = func(a Any) Any {
28+ var buf strings.Builder
29+ for _, c_ := range a.([]Any) {
30+ c, _ := c_.(string)
31+ buf.WriteString(c)
32+ }
33+ return buf.String()
34+ }
35+
36+ exports["toCharArray"] = func(s Any) Any {
37+ strs := strings.Split(s.(string), "")
38+ result := make([]Any, 0, len(strs))
39+ for _, str := range strs {
40+ result = append(result, str)
41+ }
42+ return result
43+ }
44+
45+ exports["singleton"] = func(s Any) Any {
46+ return s
47+ }
48+
49+ exports["_charAt"] = func(just Any) Any {
50+ return func(nothing Any) Any {
51+ return func(i_ Any) Any {
52+ return func(s_ Any) Any {
53+ i, _ := i_.(int)
54+ s, _ := s_.(string)
55+ runes := []rune(s)
56+ if i >= 0 && i < len(runes) {
57+ return Apply(just, string(runes[i]))
58+ }
59+ return nothing
60+ }
61+ }
62+ }
63+ }
64+
65+ exports["_toChar"] = func(just Any) Any {
66+ return func(nothing Any) Any {
67+ return func(s Any) Any {
68+ if utf8.RuneCountInString(s.(string)) == 1 {
69+ return Apply(just, s)
70+ }
71+ return nothing
72+ }
73+ }
74+ }
75+
76+ exports["length"] = func(s Any) Any {
77+ return utf8.RuneCountInString(s.(string))
78+ }
79+
80+ exports["countPrefix"] = func(p Any) Any {
81+ return func(s Any) Any {
82+ runes := []rune(s.(string))
83+ i := 0
84+ for _, c := range runes {
85+ b, _ := Apply(p, string(c)).(bool)
86+ if !b {
87+ break
88+ }
89+ i++
90+ }
91+ return i
92+ }
93+ }
94+
95+ exports["_indexOf"] = func(just Any) Any {
96+ return func(nothing Any) Any {
97+ return func(x_ Any) Any {
98+ return func(s_ Any) Any {
99+ x, _ := x_.(string)
100+ s, _ := s_.(string)
101+ i := strings.Index(s, x)
102+ if i == -1 {
103+ return nothing
104+ } else {
105+ return Apply(just, utf8.RuneCountInString(s[:i]))
106+ }
107+ }
108+ }
109+ }
110+ }
111+
112+ exports["_indexOfStartingAt"] = func(just Any) Any {
113+ return func(nothing Any) Any {
114+ return func(x_ Any) Any {
115+ return func(startAt_ Any) Any {
116+ return func(s_ Any) Any {
117+ x, _ := x_.(string)
118+ startAt, _ := startAt_.(int)
119+ s, _ := s_.(string)
120+ runes := []rune(s)
121+ if startAt < 0 || startAt > len(runes) {
122+ return nothing
123+ }
124+ substr := string(runes[startAt:])
125+ i := strings.Index(substr, x)
126+ if i == -1 {
127+ return nothing
128+ } else {
129+ return Apply(just, utf8.RuneCountInString(substr[:i])+startAt)
130+ }
131+ return nothing
132+ }
133+ }
134+ }
135+ }
136+ }
137+
138+ exports["_lastIndexOf"] = func(just Any) Any {
139+ return func(nothing Any) Any {
140+ return func(x_ Any) Any {
141+ return func(s_ Any) Any {
142+ x, _ := x_.(string)
143+ s, _ := s_.(string)
144+ i := strings.LastIndex(s, x)
145+ if i == -1 {
146+ return nothing
147+ } else {
148+ return Apply(just, utf8.RuneCountInString(s[:i]))
149+ }
150+ }
151+ }
152+ }
153+ }
154+
155+ exports["_lastIndexOfStartingAt"] = func(just Any) Any {
156+ return func(nothing Any) Any {
157+ return func(x_ Any) Any {
158+ return func(startAt_ Any) Any {
159+ return func(s_ Any) Any {
160+ x, _ := x_.(string)
161+ startAt, _ := startAt_.(int)
162+ s, _ := s_.(string)
163+ runes := []rune(s)
164+ if startAt < 0 || startAt > len(runes) {
165+ return nothing
166+ }
167+ substr := string(runes[:min(startAt+utf8.RuneCountInString(x), len(runes))])
168+ i := strings.LastIndex(substr, x)
169+ if i == -1 {
170+ return nothing
171+ } else {
172+ return Apply(just, utf8.RuneCountInString(substr[:i]))
173+ }
174+ return nothing
175+ }
176+ }
177+ }
178+ }
179+ }
180+
181+ exports["take"] = func(n_ Any) Any {
182+ return func(s_ Any) Any {
183+ n, _ := n_.(int)
184+ if n < 0 {
185+ return ""
186+ }
187+ s, _ := s_.(string)
188+ runes := []rune(s)
189+ return string(runes[:min(n, len(runes))])
190+ }
191+ }
192+
193+ exports["drop"] = func(n_ Any) Any {
194+ return func(s_ Any) Any {
195+ n, _ := n_.(int)
196+ s, _ := s_.(string)
197+ if n < 0 {
198+ return s
199+ }
200+ runes := []rune(s)
201+ return string(runes[min(n, len(runes)):])
202+ }
203+ }
204+
205+ exports["_slice"] = func(b_ Any) Any {
206+ return func(e_ Any) Any {
207+ return func(s_ Any) Any {
208+ b, _ := b_.(int)
209+ e, _ := e_.(int)
210+ s, _ := s_.(string)
211+ runes := []rune(s)
212+ if b < 0 {
213+ b = max(len(runes)+b, 0)
214+ }
215+ if e < 0 {
216+ e = max(len(runes)+e, 0)
217+ }
218+ return string(runes[b:e])
219+ }
220+ }
221+ }
222+
223+ exports["splitAt"] = func(n_ Any) Any {
224+ return func(s_ Any) Any {
225+ n, _ := n_.(int)
226+ s, _ := s_.(string)
227+ if n < 0 {
228+ return Dict{"before": "", "after": s}
229+ } else {
230+ runes := []rune(s)
231+ before := runes[:min(n, len(runes))]
232+ after := runes[min(n, len(runes)):]
233+ return Dict{"before": string(before), "after": string(after)}
234+ }
235+ }
236+ }
237+
238+}
packages/core/ffi/purescript-strings/Data_String_Common.gonew file+79
@@ -0,0 +1,79 @@
1+package purescript_strings
2+
3+import (
4+ . "github.com/purescript-native/go-runtime"
5+ "strings"
6+)
7+
8+func init() {
9+ exports := Foreign("Data.String.Common")
10+
11+ exports["_localeCompare"] = func(lt Any) Any {
12+ return func(eq Any) Any {
13+ return func(gt Any) Any {
14+ return func(s1 Any) Any {
15+ return func(s2 Any) Any {
16+ var result = strings.Compare(s1.(string), s2.(string))
17+ if result < 0 {
18+ return lt
19+ } else if result > 0 {
20+ return gt
21+ } else {
22+ return eq
23+ }
24+ }
25+ }
26+ }
27+ }
28+ }
29+
30+ exports["replace"] = func(s1 Any) Any {
31+ return func(s2 Any) Any {
32+ return func(s3 Any) Any {
33+ return strings.Replace(s3.(string), s1.(string), s2.(string), 1)
34+ }
35+ }
36+ }
37+
38+ exports["replaceAll"] = func(s1 Any) Any {
39+ return func(s2 Any) Any {
40+ return func(s3 Any) Any {
41+ return strings.ReplaceAll(s3.(string), s1.(string), s2.(string))
42+ }
43+ }
44+ }
45+
46+ exports["split"] = func(sep Any) Any {
47+ return func(s Any) Any {
48+ xs := strings.Split(s.(string), sep.(string))
49+ result := make([]Any, 0, len(xs))
50+ for _, x := range xs {
51+ result = append(result, x)
52+ }
53+ return result
54+ }
55+ }
56+
57+ exports["toLower"] = func(s Any) Any {
58+ return strings.ToLower(s.(string))
59+ }
60+
61+ exports["toUpper"] = func(s Any) Any {
62+ return strings.ToUpper(s.(string))
63+ }
64+
65+ exports["trim"] = func(s Any) Any {
66+ return strings.TrimSpace(s.(string))
67+ }
68+
69+ exports["joinWith"] = func(s Any) Any {
70+ return func(xs_ Any) Any {
71+ xs := xs_.([]Any)
72+ ss := make([]string, 0, len(xs))
73+ for _, x := range xs {
74+ ss = append(ss, x.(string))
75+ }
76+ return strings.Join(ss, s.(string))
77+ }
78+ }
79+}
packages/core/ffi/purescript-strings/Data_String_Regex.gonew file+180
@@ -0,0 +1,180 @@
1+package purescript_strings
2+
3+import (
4+ "fmt"
5+ "strings"
6+
7+ "github.com/dlclark/regexp2"
8+ . "github.com/purescript-native/go-runtime"
9+)
10+
11+type regex_pair struct {
12+ regex *regexp2.Regexp
13+ global bool
14+}
15+
16+func FindAllString(re *regexp2.Regexp, s string) []string {
17+ var matches []string
18+ m, _ := re.FindStringMatch(s)
19+ for m != nil {
20+ matches = append(matches, m.String())
21+ m, _ = re.FindNextMatch(m)
22+ }
23+ return matches
24+}
25+
26+func init() {
27+ exports := Foreign("Data.String.Regex")
28+
29+ exports["regexImpl"] = func(left Any) Any {
30+ return func(right Any) Any {
31+ return func(s_ Any) Any {
32+ return func(flags_ Any) Any {
33+ s := s_.(string)
34+ flags := flags_.(string)
35+ // I think unicode is implied
36+ flags = strings.ReplaceAll(flags, "u", "")
37+ global := false
38+ if strings.Contains(flags, "g") {
39+ global = true
40+ flags = strings.ReplaceAll(flags, "g", "")
41+ if flags != "" {
42+ flags = fmt.Sprintf("(?%s)", flags)
43+ }
44+ }
45+ r, err := regexp2.Compile(flags+s, 0)
46+ if err == nil {
47+ return Apply(right, regex_pair{r, global})
48+ } else {
49+ return Apply(left, err.Error())
50+ }
51+ }
52+ }
53+ }
54+ }
55+
56+ exports["test"] = func(p_ Any) Any {
57+ return func(s_ Any) Any {
58+ p := p_.(regex_pair)
59+ r := p.regex
60+ s := s_.(string)
61+ _, result := r.MatchString(s)
62+ return result
63+ }
64+ }
65+
66+ exports["_match"] = func(just Any) Any {
67+ return func(nothing Any) Any {
68+ return func(p_ Any) Any {
69+ return func(s_ Any) Any {
70+ p := p_.(regex_pair)
71+ r := p.regex
72+ s := s_.(string)
73+ ms := FindAllString(r, s)
74+ if ms == nil {
75+ return nothing
76+ }
77+ result := make([]Any, 0, len(ms))
78+ for _, m := range ms {
79+ if m == "" {
80+ result = append(result, nothing)
81+ } else {
82+ result = append(result, Apply(just, m))
83+ }
84+ }
85+ return Apply(just, result)
86+ }
87+ }
88+ }
89+ }
90+
91+ exports["replace"] = func(p_ Any) Any {
92+ return func(s1_ Any) Any {
93+ return func(s2_ Any) Any {
94+ p := p_.(regex_pair)
95+ r := p.regex
96+ global := p.global
97+
98+ s1 := s1_.(string)
99+ s2 := s2_.(string)
100+
101+ if global {
102+ res, _ := r.Replace(s2, s1, -1, -1)
103+ return res
104+ }
105+
106+ match, _ := r.FindStringMatch(s2)
107+ if match != nil {
108+ return strings.Replace(s2, match.String(), s1, 1)
109+ }
110+ return s2
111+ }
112+ }
113+ }
114+
115+ // exports["replaceBy"] = func(p_ Any) Any {
116+ // return func(f Any) Any {
117+ // return func(s_ Any) Any {
118+ // p := p_.(regex_pair)
119+ // r := p.regex
120+ // global := p.global
121+ // s := s_.(string)
122+
123+ // all := FindAllString(r, s)
124+ // submatches := make([]Any, 0, len(all))
125+ // for _, submatch := range all {
126+ // submatches = append(submatches, submatch)
127+ // }
128+
129+ // frepl := func(str string) string {
130+ // return Apply(f, str, submatches).(string)
131+ // }
132+
133+ // if global {
134+ // return r.ReplaceAllStringFunc(s, frepl)
135+ // }
136+
137+ // found := r.FindString(s)
138+ // if found != "" {
139+ // fmt.Println(r.ReplaceAllStringFunc(s, frepl))
140+ // return strings.Replace(s, found, frepl(r.String()), 1)
141+ // }
142+ // return s
143+ // }
144+ // }
145+ // }
146+
147+ // exports["_search"] = func(just Any) Any {
148+ // return func(nothing Any) Any {
149+ // return func(p_ Any) Any {
150+ // return func(s_ Any) Any {
151+ // p := p_.(regex_pair)
152+ // r := p.regex
153+ // s := s_.(string)
154+ // // found := r.FindStringIndex(s)
155+ // found, _ := r.FindStringMatch(s)
156+ // if found == nil {
157+ // return nothing
158+ // }
159+ // // TODO: is there a way to do this that is faster?
160+ // return Apply(just, found.Index)
161+ // }
162+ // }
163+ // }
164+ // }
165+
166+ // Not implemented in the lib
167+ // exports["split"] = func(p_ Any) Any {
168+ // return func(s_ Any) Any {
169+ // p := p_.(regex_pair)
170+ // r := p.regex
171+ // s := s_.(string)
172+ // ss := r.Split(s, -1)
173+ // result := make([]Any, 0, len(ss))
174+ // for _, str := range ss {
175+ // result = append(result, str)
176+ // }
177+ // return result
178+ // }
179+ // }
180+}
packages/core/ffi/purescript-strings/Data_String_Unsafe.gonew file+30
@@ -0,0 +1,30 @@
1+package purescript_strings
2+
3+import (
4+ . "github.com/purescript-native/go-runtime"
5+ "unicode/utf8"
6+)
7+
8+func init() {
9+ exports := Foreign("Data.String.Unsafe")
10+
11+ exports["charAt"] = func(i_ Any) Any {
12+ return func(s_ Any) Any {
13+ i, _ := i_.(int)
14+ s, _ := s_.(string)
15+ runes := []rune(s)
16+ if i < 0 || i >= len(runes) {
17+ panic("Data.String.Unsafe.charAt: Invalid index.")
18+ }
19+ return string(runes[i : i+1])
20+ }
21+ }
22+
23+ exports["char"] = func(s Any) Any {
24+ if utf8.RuneCountInString(s.(string)) != 1 {
25+ panic("Data.String.Unsafe.char: Expected string of length 1.")
26+ }
27+ return s
28+ }
29+
30+}
packages/core/ffi/purescript-unicode/Data_Char_Unicode.gonew file+16
@@ -0,0 +1,16 @@
1+package purescript_unicode
2+
3+import (
4+ . "github.com/purescript-native/go-runtime"
5+)
6+
7+func init() {
8+ exports := Foreign("Data.Char.Unicode")
9+
10+ exports["withCharCode"] = func(f Any) Any {
11+ return func(c_ Any) Any {
12+ c := c_.(rune)
13+ return Apply(f, c).(string)
14+ }
15+ }
16+}
packages/core/go.mod+6−2
@@ -6,9 +6,13 @@ replace project.localhost/purescript-native/ffi-loader => ./purescript-native
66
77replace project.localhost/purescript-native/output => ./output
88
9+replace project.localhost/ffi => ./ffi
10+
911require (
10− github.com/purescript-native/go-ffi v0.0.0-20201213185134-1d36dd2917f6 // indirect
11− github.com/purescript-native/go-runtime v0.1.2 // indirect
12+ github.com/dlclark/regexp2 v1.4.0 // indirect
13+ github.com/i-am-the-slime/go-ffi v0.0.0-20210708182442-8ad06bcde03a // indirect
14+ github.com/purescript-native/go-runtime v0.1.2
15+ project.localhost/ffi v0.1.0 // indirect
1216 project.localhost/purescript-native/ffi-loader v0.0.0-00010101000000-000000000000 // indirect
1317 project.localhost/purescript-native/output v0.0.0-00010101000000-000000000000 // indirect
1418)
packages/core/go.sum+70
@@ -1,4 +1,74 @@
1+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
3+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
6+github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
7+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
8+github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
9+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
10+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
11+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
12+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
13+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
14+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
15+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
16+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
17+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
18+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
19+github.com/i-am-the-slime/go-ffi v0.0.0-20200803133247-bd2d68b26de0/go.mod h1:iKWcW1q4lUMFRXVM3jlxKklb5870vCyRqSMBZTRMR+M=
20+github.com/i-am-the-slime/go-ffi v0.0.0-20210321150428-04e841c62bda h1:cnuGwhAqh6Te33W3eMYIw8BKr3QeMq/67aoTlaiLAww=
21+github.com/i-am-the-slime/go-ffi v0.0.0-20210321150428-04e841c62bda/go.mod h1:G20T9FXpgn6M3s1pnXDAOTwAXKQgDwl/uhMLfo5h6PA=
22+github.com/i-am-the-slime/go-ffi v0.0.0-20210708182442-8ad06bcde03a h1:FKVI3W9bKwRqcaxh02VGFj47ub8QtZARHo2CMAy5MIQ=
23+github.com/i-am-the-slime/go-ffi v0.0.0-20210708182442-8ad06bcde03a/go.mod h1:G20T9FXpgn6M3s1pnXDAOTwAXKQgDwl/uhMLfo5h6PA=
24+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
25+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
26+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
27+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
28+github.com/leanovate/gopter v0.2.5-0.20190402064358-634a59d12406/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8=
29+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
30+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
31+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
32+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
33+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
34+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
35+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
36+github.com/philandstuff/dhall-golang/v6 v6.0.1/go.mod h1:XRoxjsqZM2y7KPFhjV7CSVdWpV5CwuTzGjAY/v+1SUU=
37+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
38+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
39+github.com/purescript-native/go-ffi v0.0.0-20200509223002-f51b7dc5ebfe h1:w//PiWSs9gwBf1XuFWzLwIm0m/YdbVpBna0CMPZ/IGY=
40+github.com/purescript-native/go-ffi v0.0.0-20200509223002-f51b7dc5ebfe/go.mod h1:1TvaJdjRUFHRmoLQ5QvpR1pnivyd7eBjNA+j1PuktBM=
141github.com/purescript-native/go-ffi v0.0.0-20201213185134-1d36dd2917f6 h1:m9ZH7wktv/gL/m8OT8DDyy9EGl0axN+DPYZFZyFAUTA=
242github.com/purescript-native/go-ffi v0.0.0-20201213185134-1d36dd2917f6/go.mod h1:1TvaJdjRUFHRmoLQ5QvpR1pnivyd7eBjNA+j1PuktBM=
43+github.com/purescript-native/go-runtime v0.1.0/go.mod h1:Pl7TR9c9Al8GMlY/R2D7joWjlQuTiB9eBN2a9aXd6GQ=
44+github.com/purescript-native/go-runtime v0.1.1/go.mod h1:Pl7TR9c9Al8GMlY/R2D7joWjlQuTiB9eBN2a9aXd6GQ=
345github.com/purescript-native/go-runtime v0.1.2 h1:vxVmLXojzc6nkP29qMxHmEd6iwolF309yP/FskRY88Y=
446github.com/purescript-native/go-runtime v0.1.2/go.mod h1:Pl7TR9c9Al8GMlY/R2D7joWjlQuTiB9eBN2a9aXd6GQ=
47+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
48+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
49+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
50+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
51+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
52+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
53+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
54+github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
55+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
56+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
57+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
58+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
59+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
60+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
61+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
62+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
63+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
65+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
66+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
67+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
68+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
69+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
70+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
71+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
72+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
73+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
74+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
packages/core/purescript-native/ffi_loader.go+18−10
@@ -4,27 +4,35 @@ package ffi_loader
44// faster/smaller builds.
55
66import (
7− _ "github.com/purescript-native/go-ffi/purescript-arrays"
7+ _ "github.com/i-am-the-slime/go-ffi/purescript-arrays"
8+ _ "github.com/i-am-the-slime/go-ffi/purescript-effect"
9+ _ "github.com/i-am-the-slime/go-ffi/purescript-integers"
10+ _ "github.com/i-am-the-slime/go-ffi/purescript-partial"
11+ _ "github.com/i-am-the-slime/go-ffi/purescript-prelude"
812 _ "github.com/purescript-native/go-ffi/purescript-assert"
913 _ "github.com/purescript-native/go-ffi/purescript-console"
10− _ "github.com/purescript-native/go-ffi/purescript-effect"
1114 _ "github.com/purescript-native/go-ffi/purescript-enums"
1215 _ "github.com/purescript-native/go-ffi/purescript-exceptions"
1316 _ "github.com/purescript-native/go-ffi/purescript-foldable-traversable"
17+ _ "github.com/purescript-native/go-ffi/purescript-foreign"
1418 _ "github.com/purescript-native/go-ffi/purescript-functions"
1519 _ "github.com/purescript-native/go-ffi/purescript-globals"
16− _ "github.com/purescript-native/go-ffi/purescript-integers"
1720 _ "github.com/purescript-native/go-ffi/purescript-lazy"
1821 _ "github.com/purescript-native/go-ffi/purescript-math"
19− _ "github.com/purescript-native/go-ffi/purescript-partial"
20− _ "github.com/purescript-native/go-ffi/purescript-prelude"
2122 _ "github.com/purescript-native/go-ffi/purescript-random"
23+ _ "github.com/purescript-native/go-ffi/purescript-record"
2224 _ "github.com/purescript-native/go-ffi/purescript-refs"
25+ _ "github.com/purescript-native/go-ffi/purescript-simple-json"
2326 _ "github.com/purescript-native/go-ffi/purescript-st"
24− _ "github.com/purescript-native/go-ffi/purescript-strings"
2527 _ "github.com/purescript-native/go-ffi/purescript-unfoldable"
26−)
27−
28−// Add your own FFI packages here.
28+ _ "github.com/purescript-native/go-ffi/purescript-unsafe-coerce"
2929
30−import ()
30+ // Add your own FFI packages here.
31+ _ "project.localhost/ffi/purescript-aff"
32+ _ "project.localhost/ffi/purescript-debug"
33+ _ "project.localhost/ffi/purescript-go-os"
34+ _ "project.localhost/ffi/purescript-now"
35+ _ "project.localhost/ffi/purescript-spec"
36+ _ "project.localhost/ffi/purescript-strings"
37+ _ "project.localhost/ffi/purescript-unicode"
38+)
packages/core/purescript-native/go.mod+7
@@ -1,2 +1,9 @@
11module project.localhost/purescript-native/ffi-loader
22
3+go 1.16
4+
5+require (
6+ github.com/i-am-the-slime/go-ffi v0.0.0-20200803133247-bd2d68b26de0
7+ github.com/purescript-native/go-ffi v0.0.0-20200509223002-f51b7dc5ebfe
8+ github.com/purescript-native/go-runtime v0.1.1 // indirect
9+)
packages/core/src/Format.purs+2−9
@@ -1,23 +1,16 @@
11module Format (format) where
22
33import Prelude
4−import Data.Array (any, foldl, intercalate, intersperse)
4+
55import Data.Array as Array
66import Data.Array.NonEmpty as NE
77import Data.Array.NonEmpty.Internal (NonEmptyArray)
8−import Data.Bitraversable (bisequence)
9−import Data.Foldable (fold, foldMap, sum)
8+import Data.Foldable (any, fold, foldMap, sum)
109import Data.FoldableWithIndex (foldMapWithIndex)
1110import Data.Maybe (Maybe(..), fromMaybe, maybe)
12−import Data.Monoid.Additive (Additive(..))
13−import Data.Newtype (ala)
1411import Data.Semigroup.Foldable (intercalateMap)
15−import Data.String (Pattern(..), split)
16−import Data.String.CodeUnits (lastIndexOf)
17−import Data.String.CodeUnits as String
1812import Data.Tuple (fst, snd)
1913import Data.Tuple.Nested (type (/\), (/\))
20−import Foreign.Internal.Stringify (unsafeStringify)
2114import Partial.Unsafe (unsafeCrashWith)
2215import PureScript.CST.Print as Print
2316import PureScript.CST.Range (class RangeOf, class TokensOf, rangeOf, tokensOf)
packages/core/src/Main.purs+5−13
@@ -15,24 +15,16 @@ import Format (format)
1515import Node.Encoding (Encoding(..))
1616import Node.FS.Aff (readTextFile)
1717import Node.Path (FilePath)
18+import OS (stdinAsString)
1819import PureScript.CST (RecoveredParserResult(..), parseModule)
1920import PureScript.CST.Errors (printParseError)
2021import Settings (Settings, defaultSettings)
2122
22−foreign import argv :: Array String
23−
24−foreign import stdinFile :: FilePath
25−
2623main :: Effect Unit
27−main =
28− launchAff_ do
29− stdinContent <- readTextFile UTF8 stdinFile
30− if stdinContent /= "" then
31− parseAndFormatOrThrow defaultSettings stdinContent
32− else case Array.drop 2 argv of
33− [ fileName ] -> do
34− readTextFile UTF8 fileName >>= parseAndFormatOrThrow defaultSettings
35− _ -> Log.error "Please only supply one argument"
24+main = do
25+ input <- stdinAsString
26+ launchAff_ $ parseAndFormatOrThrow defaultSettings input
27+
3628
3729parseAndFormatOrThrow :: Settings -> String -> Aff Unit
3830parseAndFormatOrThrow settings =
packages/core/src/OS.jsnew file+4
@@ -0,0 +1,4 @@
1+var fs = require('fs');
2+exports.stdinAsString = () => {
3+ return fs.readFileSync(0, 'utf-8');
4+}
packages/core/src/OS.pursnew file+7
@@ -0,0 +1,7 @@
1+module OS
2+ ( stdinAsString
3+ ) where
4+
5+import Effect (Effect)
6+
7+foreign import stdinAsString ∷ Effect String