Eval behaves differently in compiled binaries
corpix opened this issue · 6 comments
I have faced an issue with eval environment inside compiled binaries. Here is the example...
Gerbil:
~/projects/src/git.backbone/corpix/schemered λ cat yyy.ss
(export main)
(def x 1)
(def file-path "xxx.ss")
(def (main . args)
(eval `(include ,file-path)))
~/projects/src/git.backbone/corpix/schemered λ cat xxx.ss
(display x)
(display "\n")
~/projects/src/git.backbone/corpix/schemered λ gxc -static -exe -o yyy yyy.ss
...
~/projects/src/git.backbone/corpix/schemered λ ./yyy
*** ERROR IN "xxx.ss"@1.10-1.11 -- Unbound variable: x
--- continuation backtrace:
[0] ##primordial-exception-handler-hook
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ xxx.ss ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1┃(display x)
2┃(display "\n")
Gerbil interpreter works fine:
~/projects/src/git.backbone/corpix/schemered λ gxi
Gerbil v0.18.1-111-g708c85bd on Gambit v4.9.5-130-g09335d95
> (def x 1)
> (eval '(include "xxx.ss"))
1
>
Gambit works fine:
~/projects/src/git.backbone/corpix/schemered λ cat yyy.scm
(define x 1)
(define file-path "xxx.scm")
(eval `(include ,file-path))
~/projects/src/git.backbone/corpix/schemered λ cat xxx.scm
(display x)
(display "\n")
~/projects/src/git.backbone/corpix/schemered λ gsc -exe -cc-options '-static' yyy.scm
...
~/projects/src/git.backbone/corpix/schemered λ ./yyy
1
You need to initialize the expander explicitly in binaries!
So, import :getbil/expander
in your binary to make sure the relevant code is linked, and then call (gerbil-load-expander!)
.
Thanks for quick reply! I have changed my code to be:
(import :gerbil/expander)
(export main)
(def x 1)
(def file-path "xxx.ss")
(def (main . args)
(gerbil-load-expander!)
(eval `(include ,file-path)))
calling
gerbil-load-expander!
frommain
because otherwise it will fail with
*** ERROR IN gerbil-load-expander! --
*** ERROR IN ? [Error]: runtime has not been initialized
But I still getting an error:
*** ERROR IN "xxx.ss"@1.10-1.11 -- Unbound variable: x
--- continuation backtrace:
[0] ##primordial-exception-handler-hook
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ xxx.ss ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1┃(display x)
2┃(display "\n")
Yes, gerbil-load-expander! needs to be called from main or childten.
Regarding the unbound variable;
x
is defined in your main module, so it is not visible in your top lexical context!
You need to extern declare it for your actual namespace. Alternatively, you can export it in your main module and import that, but it requires your module's ssi to be visible to the binary.
So, i recommend the extern approach.
In the included filr, add something like this:
(extern (x your/package/main-module#x))
Or:
(extern namespace: your/package/main-module x ;; and more symbols )
Now it is working!
Full code for history:
yyy.ss
(import :gerbil/expander)
(export main)
(def x 1)
(def file-path "xxx.ss")
(def (main . args)
(gerbil-load-expander!)
(eval `(include ,file-path)))
xxx.ss
(extern (x schemered/yyy#x))
(display x)
(display "\n")
gerbil.pkg
(package: schemered)
I feel like I should document it somewhere... but not sure where... what do you think?
Agreed, it should be documented!
Not sure where to put it either, maybe somewhere in the guide?
We can also add a new page.