Comments (7)
I think starting with schemeFromJs
is a good starting point. You'll basically want to write the inverse of jsFromScheme
.
You might also look at apply-representation
, which is the part where Schism actually converts all the data into tagged pointers.
As far as data goes, everything is a tagged pointer packed into an i32
. The high 29 bits are the actual value, and the low three bits are the tag. There are tags for numbers, constants, pairs, characters, strings, symbols, and closures so far. For numbers, constants and characters, there is no in-memory part; the data is completely stored in the pointer. The value part of pairs point to two consecutive words in memory, which themselves are each tagged pointers. Strings are just lists of characters, but instead of having a pair tag, they have a string tag. If you find the implementation of string->list
and list->string
, you'll notice all those do is change the tag.
Symbols are a little trickier. There's a linked list that keeps track of all the symbols. Things tagged with symbol point into this list. Each entry either has a string, if it's a normal symbol, or #f
if it was a gensym. This means we can compare equality of two symbols just by comparing their pointers, we can convert between strings and symbols, but gensyms are all distinct from all other symbols.
For how the compiler works, it is a set of passes that start with Scheme source code and then transform it into lower level representations until finally we can generate WebAssembly from it. A lot of Scheme's higher level features get eliminated pretty early in the compiler. This means the backend can be simpler because the language is much smaller at that point. You can see the passes and what order they are called in by looking at the compile-library
function.
I realize the documentation could be a lot better, but hopefully this is enough to point you in the right direction. Feel free to keep asking questions!
from schism.
Everything in Schism should be a ptr
. These are basically tagged values. Numbers carry the tag 0 in their low three bits, and the higher bits are the actual numbers. For pairs, they have a tag and then the higher bits are a pointer into linear memory where you can find two ptr
s representing the car and cdr of the pair.
So what should happen is that instead of calling instance.exports.add(1,2)
, you should call instance.exports.add(schemeFromJs(1), schemeFromJs(2))
, except that schemeFromJs
doesn't exist yet.
The reason your example is working is basically that the +
operation doesn't do any type checking. Numbers have the tag 0 so they can be added without any wrapping and unwrapping. So, your add
function just blindly adds its two values together. The raw value 1 is the constant #f
(it has the tag 1 for "constant" and the value 0 for "#f
", see the tag definitions), and the raw value 2 is a pair at location 0 in linear memory (this is actually where the allocation pointer and symbol table live). Add should complain that you are trying to add #f
to a pair, but instead it just does the addition, creating the null character (tag 3 and value 0).
So I think there are two bugs here. One is that we need a way to convert integers from JavaScript into tagged integers that Schism needs. The second is that +
should verify that it's actually adding two numbers together.
from schism.
Perfect
I think it would be good to have a way in the runtime to create a wrapper for an instance (maybe in Module?) so you can call into schism with JS values and get JS values back out. Maybe I'll create a new issue to discuss what that should look like.
from schism.
from schism.
First I might try and implement schemeFromJs
to get a better understanding for how parameters are handled and just how the compiler works in general. Do you have any pointers (pun intended) for where to get started?
from schism.
I can't thank you enough for taking your time to teach me about all of this, it helps tremendously.
As far as testing the interop is concerned, it looks like all of the current tests just test for truthy return values. What I'm thinking of doing is following your naming convention and adding in a JavaScript module that can do the testing. Maybe something like:
add-nums.ss
(library
(trivial)
(export do-test)
(import (rnrs))
(define (do-test)
(+ 1 2)))
add-nums.mjs
export function test(wasm, engine, assert) {
// ... do testing here
};
Not sure exactly what it will look like, but something like that.
from schism.
So the idea would be that the JS test
function would verify that the Scheme do-test
returns 3?
That seems like a good idea. Most of the tests so far are self-testing, which generally gives good compiler coverage but can miss some cases where the compiler generates incorrect code but just happens to work.
I think more extensive testing of JS/Scheme integration is a great idea!
from schism.
Related Issues (20)
- Do we want a SchismValue or similar class?
- Bootstrapping from guile fails: "Unbound variable: %file-exists?" HOT 6
- master playground doesn't work HOT 2
- equal? should handle cyclic structures
- bug related to tail-call-indirect
- Allow multiple tests per test file
- test/list-find.ss fails HOT 1
- Guile bootstrap seems to be broken again? HOT 3
- Add macro expander
- Try Β΅Kanren as a test case
- Add support for failure tests
- Add file input ports
- First class procedures HOT 5
- Add a command to compile a file to .wasm HOT 3
- Question: What is the difference between the schism-stageN.wasm HOT 4
- Pass options to Schism.Engine as a dictionary HOT 1
- Remove `list-all-eq?` HOT 6
- README.md review: What does Schism do? HOT 2
- Add test case for string `eq?` behavior HOT 5
- Add some kind of `include-data` macro HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from schism.