486a50cf14db0a3c1e4c3e6dea169fbe99226873
2 let txtdiv
= document
.createElement("div")
3 document
.body
.appendChild(txtdiv
)
5 print
: (string
) => txtdiv
.textContent
+= string
12 document
.addEventListener('keydown', (event
) => {
13 console
.log(`keydown: ${event.key}`)
14 if (event
.key
!= "F5") {
15 event
.preventDefault()
16 event
.stopPropagation()
19 txtdiv
= document
.createElement("div")
20 document
.body
.appendChild(txtdiv
)
23 txtdiv
= document
.createElement("div")
24 document
.body
.appendChild(txtdiv
)
27 stdin
= stdin
.substring(0, stdin
.length
- 1)
28 txtdiv
.textContent
= txtdiv
.textContent
.substring(0, txtdiv
.textContent
.length
- 1)
31 if (event
.key
.length
== 1) {
33 output
.print(event
.key
)
41 read
: (writeAddr
, maxBytes
) => {
42 const maxChars
= maxBytes
>> 1
43 const bufView
= new Uint16Array(wasmMem
.buffer
, writeAddr
, maxChars
)
45 for (i
= 0; i
< maxChars
&& i
< stdin
.length
; i
++)
46 bufView
[i
] = stdin
.charCodeAt(i
)
47 stdin
= stdin
.substring(maxChars
)
50 write
: (readAddr
, maxBytes
) =>
51 output
.print(String
.fromCharCode
.apply(
53 new Uint16Array(wasmMem
.buffer
, readAddr
, maxBytes
)
97 pop
: () => simstack
.pop(),
98 push
: (val
) => simstack
.push(val
),
99 rinit
: () => rstack
.length
= 0,
100 rpop
: () => rstack
.pop(),
101 rpush
: (val
) => rstack
.push(val
),
102 sys_write
: (channel
, fromBuffer
) => {
103 if (channels
[channel
] === undefined)
105 const maxBytes
= new DataView(
110 console
.log(`write ch:${channel} addr:${fromBuffer} len:${maxBytes}`)
111 channels
[channel
].write(fromBuffer
+ 4, maxBytes
)
113 sys_read
: (channel
, toBuffer
) => {
114 console
.log(`read ch:${channel} buf:${toBuffer} current: ${stdin}`)
115 const lenView
= new DataView(wasmMem
.buffer
, toBuffer
, 8)
116 const maxBytes
= lenView
.getUint32(0,true)
117 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`)
118 /* If the channel is undefined, or if there isn't enough room in
119 * toBuffer for even one character, then, if there is enough
120 * room for an int write a zero, exit */
121 if (channels
[channel
] === undefined || maxBytes
< 6) {
123 lenView
.setUint32(4,0,true)
125 const numBytes
= channels
[channel
].read(toBuffer
+ 8, maxBytes
- 4)
126 lenView
.setUint32(4,numBytes
,true);
127 console
.log(`read wrote ${lenView.getUint32(4,true)} bytes, remainder: ${stdin}`)
128 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`) },
129 sys_listen
: (reqAddr
, cbAddr
) => {
130 //TODO: call into the module to wasm fn "event" to push an event
131 //to forth, which pushes esi to the return stack and queues the
132 //callback function provided from listen. reqaddr could be
133 //"fetch", in which case no channel is used. otherwise very
134 //similar to sys_fetch.
136 sys_fetch
: (channel
, reqAddr
) => {
137 //TODO: map to fetch promise, write to channel buffer,
138 //javascript "fetch" as fallback, explicit handles for
139 //"textEntry" or any third party protocols like activitypub
140 console
.log(`fetch ${channel} ${reqAddr}`)
142 sys_echo
: (val
) => output
.print(`${val} `),
143 sys_echochar
: (val
) => output
.print(String
.fromCharCode(val
)),
144 sys_reflect
: (addr
) => {
145 console
.log(`reflect: ${addr}: ${
146 new DataView(wasmMem.buffer, addr, 4)
150 vocab_get
: (addr
) => {
151 const bytes
= new DataView(
156 const word
= String
.fromCharCode
.apply(
158 new Uint16Array(wasmMem
.buffer
, addr
+ 4, bytes
>> 1)
160 const answer
= dictionary
[word
.toUpperCase()]
161 console
.log(`vocab_get ${word}: ${answer}`)
162 if (answer
=== undefined)
166 vocab_set
: (addr
, num
) => {
167 const bytes
= new DataView(
172 const word
= String
.fromCharCode
.apply(
174 new Uint16Array(wasmMem
.buffer
, addr
+ 4, bytes
>> 1)
176 console
.log(`vocab_set ${word}: ${num}`)
177 dictionary
[word
.toUpperCase()] = num
180 is_whitespace
: (key
) => /\s/.test(String
.fromCharCode(key
)),
181 sys_stack
: () => console
.log(`[${simstack}]`),
182 sys_parsenum
: (addr
, base
) => {
183 const byteV
= new DataView(
188 const word
= String
.fromCharCode
.apply(
190 new Uint16Array(wasmMem
.buffer
, addr
+ 4, byteV
.getUint32(0,true) >> 1)
192 const answer
= Number
.parseInt(word
, base
)
193 byteV
.setUint32(0,Number
.isNaN(answer
),true)
197 output
.print(Object
.getOwnPropertyNames(dictionary
).toString().split(',').join(' '))
203 .then(re
=> re
.arrayBuffer())
204 .then(buf
=> WebAssembly
.instantiate(buf
, wasmImport
))
206 wasmMem
= result
.instance
.exports
.memory
207 forth
= result
.instance
.exports
.main
208 console
.log('wasm loaded');