Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whistle does not work correctly with TinyGo #11

Open
deadprogram opened this issue Jun 6, 2023 · 4 comments
Open

Whistle does not work correctly with TinyGo #11

deadprogram opened this issue Jun 6, 2023 · 4 comments

Comments

@deadprogram
Copy link
Contributor

It would be great to be able to run Whistle using TinyGo. I am trying with the latest dev branch build.

$ tinygo version
tinygo version 0.28.0-dev-4a240827 linux/amd64 (using go version go1.20 and LLVM version 15.0.0)

The cmd/whistle itself compiles:

$ tinygo build -o ./build/tinywhistle ./cmd/whistle/

$ ls -l build/
total 3452
-rwxrwxr-x 1 ron ron 1053904 jun  6 18:25 tinywhistle
-rwxrwxr-x 1 ron ron 2478072 jun  4 22:11 whistle

but does not really work:

$ ./build/tinywhistle ./examples/hello.lisp 
42

$ ./build/tinywhistle ./examples/datalog.lisp 
panic: pattern assumed to be list
Aborted (core dumped)

Running the tests using tinygo test shows this same error.

$ tinygo test ./...
?       github.com/deosjr/whistle/cmd/whistle   [no test files]
panic: pattern assumed to be list
FAIL    github.com/deosjr/whistle/datalog       0.137s
panic: pattern assumed to be list
FAIL    github.com/deosjr/whistle/erlang        0.205s
?       github.com/deosjr/whistle/examples/continuations        [no test files]
?       github.com/deosjr/whistle/examples/datalog      [no test files]
?       github.com/deosjr/whistle/examples/hello        [no test files]
?       github.com/deosjr/whistle/examples/minikanren   [no test files]
?       github.com/deosjr/whistle/examples/repl [no test files]
panic: pattern assumed to be list
FAIL    github.com/deosjr/whistle/kanren        0.253s
FAIL    github.com/deosjr/whistle/lisp  0.138s
@deadprogram
Copy link
Contributor Author

deadprogram commented Jun 6, 2023

Some additional info. The core tests in Whistle pass if you increase the stack size, e.g.

$ tinygo test -stack-size=1MB ./lisp/
ok      github.com/deosjr/whistle/lisp  20.813s

However even when setting to a very high number (-stack-size=16MB) the other tests still fail the same way.

@deosjr
Copy link
Owner

deosjr commented Jun 6, 2023

The direct panic is coming from the macro system, which is not the greatest code I've ever written.
You could consider disabling macros altogether in tinywhisper for starters, or perhaps only add a few if a particular one is causing trouble. Would be a matter of removing define-syntax from the eval loop, and commenting out the macromap global var in macro.go

I don't know yet why this would be using massive amounts of stack space, but the fact that a macro is interpreted into a transformer (anonymous func) and stored in a map means it uses some less well supported parts of tinygo, perhaps?
The other hint is this is the only part that is using the reflect package other than builtin 'eqv?' checks, that is:

sdost@Sjoerds-MacBook-Pro whistle % grep -R 'reflect' .
./lisp/global.go: "reflect"
./lisp/global.go: return NewPrimitive(reflect.DeepEqual(args[0], args[1])), nil
./lisp/macro_test.go: "reflect"
./lisp/macro_test.go: if !reflect.DeepEqual(got, tt.want) {
./lisp/macro_test.go: if !reflect.DeepEqual(got, tt.want) {
./lisp/macro_test.go: if !ok || !reflect.DeepEqual(s, tt.want) {
./lisp/macro_test.go: if !reflect.DeepEqual(got, want) {
./lisp/macro.go: "reflect"
./lisp/macro.go: return reflect.DeepEqual(p.content, q)```

@deadprogram
Copy link
Contributor Author

@deosjr please see tinygo-org/tinygo#3771 (comment)

@deosjr
Copy link
Owner

deosjr commented Jun 9, 2023

Unoptimised, not even hello.lisp works. This is because many different parts go out of stack quite easily.

I have isolated them one by one and found that parsing complex lines, too many macros, too many builtin funcs and the anonymous functions in the process implementation in erlang.go all contribute to this problem. If you remove the dependency on kanren/erlang/datalog in cmd/whistle/main.go, comment out all but * display newline builtins, remove most of erlang.newProcess (since this is still called, see #9 ) and remove the list and quasiquote macros, then tinygo using -opt=0 will run hello.lisp just fine :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants