ffe8044d68d08d38ba2953f1bda66dcfaed99d39
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
)
98 'EXECUTE-MODE': 16680,
104 pop
: () => simstack
.pop(),
105 push
: (val
) => simstack
.push(val
),
106 rinit
: () => rstack
.length
= 0,
107 rpop
: () => rstack
.pop(),
108 rpush
: (val
) => rstack
.push(val
),
109 sys_write
: (channel
, fromBuffer
) => {
110 if (channels
[channel
] === undefined)
112 const maxBytes
= new DataView(
117 console
.log(`write ch:${channel} addr:${fromBuffer} len:${maxBytes}`)
118 channels
[channel
].write(fromBuffer
+ 4, maxBytes
)
120 sys_read
: (channel
, toBuffer
) => {
121 console
.log(`read ch:${channel} buf:${toBuffer} current: ${stdin}`)
122 const lenView
= new DataView(wasmMem
.buffer
, toBuffer
, 8)
123 const maxBytes
= lenView
.getUint32(0,true)
124 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`)
125 /* If the channel is undefined, or if there isn't enough room in
126 * toBuffer for even one character, then, if there is enough
127 * room for an int write a zero, exit */
128 if (channels
[channel
] === undefined || maxBytes
< 6) {
130 lenView
.setUint32(4,0,true)
132 const numBytes
= channels
[channel
].read(toBuffer
+ 8, maxBytes
- 4)
133 lenView
.setUint32(4,numBytes
,true);
134 console
.log(`read wrote ${lenView.getUint32(4,true)} bytes, remainder: ${stdin}`)
135 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`) },
136 sys_listen
: (reqAddr
, cbAddr
) => {
137 //TODO: call into the module to wasm fn "event" to push an event
138 //to forth, which pushes esi to the return stack and queues the
139 //callback function provided from listen. reqaddr could be
140 //"fetch", in which case no channel is used. otherwise very
141 //similar to sys_fetch.
143 sys_fetch
: (channel
, reqAddr
) => {
144 //TODO: map to fetch promise, write to channel buffer,
145 //javascript "fetch" as fallback, explicit handles for
146 //"textEntry" or any third party protocols like activitypub
147 console
.log(`fetch ${channel} ${reqAddr}`)
149 sys_echo
: (val
) => output
.print(`${val} `),
150 sys_echochar
: (val
) => output
.print(String
.fromCharCode(val
)),
151 sys_reflect
: (addr
) => {
152 console
.log(`reflect: ${addr}: ${
153 new DataView(wasmMem.buffer, addr, 4)
157 vocab_get
: (addr
, u
) => {
158 const word
= String
.fromCharCode
.apply(
160 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
162 const answer
= dictionary
[word
.toUpperCase()]
163 console
.log(`vocab_get ${word}: ${answer}`)
164 if (answer
=== undefined)
168 vocab_set
: (addr
, u
, num
) => {
169 console
.log(`vocab set ${addr} ${u} ${num}`)
170 const word
= String
.fromCharCode
.apply(
172 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
174 console
.log(`vocab_set ${word}: ${num}`)
175 dictionary
[word
.toUpperCase()] = num
178 is_whitespace
: (key
) => /\s/.test(String
.fromCharCode(key
)),
179 sys_stack
: () => console
.log(`[${simstack}]`),
180 sys_parsenum
: (addr
, u
, base
) => {
181 const word
= String
.fromCharCode
.apply(
183 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
185 const answer
= Number
.parseInt(word
, base
)
186 console
.log(`parsenum: ${addr} ${u} ${base}`)
187 console
.log(`parsenum: ${word} ${answer}`)
188 console
.log(`parsenum: ${Number.isNaN(answer)}`)
189 if (Number
.isNaN(answer
))
191 new DataView(wasmMem
.buffer
, addr
, 4).setUint32(0,answer
,true)
195 output
.print(Object
.getOwnPropertyNames(dictionary
).toString().split(',').join(' '))
200 fetch('forth.forth').then((re
) => re
.text()).then((txt
) => {
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');