a3920952a75ee86829620d4e84277b010ef1778a
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
>> 1)
99 'EXECUTE-MODE': 16680,
105 pop
: () => simstack
.pop(),
106 push
: (val
) => simstack
.push(val
),
107 rinit
: () => rstack
.length
= 0,
108 rpop
: () => rstack
.pop(),
109 rpush
: (val
) => rstack
.push(val
),
110 sys_write
: (channel
, addr
, u
) => {
111 if (channels
[channel
] === undefined)
113 console
.log(`write ch:${channel} addr:${addr} len:${u}`)
114 channels
[channel
].write(addr
, u
)
116 sys_read
: (channel
, toBuffer
) => {
117 console
.log(`read ch:${channel} buf:${toBuffer} current: ${stdin}`)
118 const lenView
= new DataView(wasmMem
.buffer
, toBuffer
, 8)
119 const maxBytes
= lenView
.getUint32(0,true)
120 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`)
121 /* If the channel is undefined, or if there isn't enough room in
122 * toBuffer for even one character, then, if there is enough
123 * room for an int write a zero, exit */
124 if (channels
[channel
] === undefined || maxBytes
< 6) {
126 lenView
.setUint32(4,0,true)
128 const numBytes
= channels
[channel
].read(toBuffer
+ 8, maxBytes
- 4)
129 lenView
.setUint32(4,numBytes
,true);
130 console
.log(`read wrote ${lenView.getUint32(4,true)} bytes, remainder: ${stdin}`)
131 console
.log(`read blen:${lenView.getUint32(0,true)} cstrlen:${lenView.getUint32(4,true)}`) },
132 sys_listen
: (reqAddr
, cbAddr
) => {
133 //TODO: call into the module to wasm fn "event" to push an event
134 //to forth, which pushes esi to the return stack and queues the
135 //callback function provided from listen. reqaddr could be
136 //"fetch", in which case no channel is used. otherwise very
137 //similar to sys_fetch.
139 sys_fetch
: (channel
, reqAddr
) => {
140 //TODO: map to fetch promise, write to channel buffer,
141 //javascript "fetch" as fallback, explicit handles for
142 //"textEntry" or any third party protocols like activitypub
143 console
.log(`fetch ${channel} ${reqAddr}`)
145 sys_echo
: (val
) => output
.print(`${val} `),
146 sys_echochar
: (val
) => output
.print(String
.fromCharCode(val
)),
147 sys_reflect
: (addr
) => {
148 console
.log(`reflect: ${addr}: ${
149 new DataView(wasmMem.buffer, addr, 4)
153 vocab_get
: (addr
, u
) => {
154 const word
= String
.fromCharCode
.apply(
156 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
158 const answer
= dictionary
[word
.toUpperCase()]
159 console
.log(`vocab_get ${word}: ${answer}`)
160 if (answer
=== undefined)
164 vocab_set
: (addr
, u
, num
) => {
165 console
.log(`vocab set ${addr} ${u} ${num}`)
166 const word
= String
.fromCharCode
.apply(
168 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
170 console
.log(`vocab_set ${word}: ${num}`)
171 dictionary
[word
.toUpperCase()] = num
174 is_whitespace
: (key
) => /\s/.test(String
.fromCharCode(key
)),
175 sys_stack
: () => console
.log(`[${simstack}]`),
176 sys_parsenum
: (addr
, u
, base
) => {
177 const word
= String
.fromCharCode
.apply(
179 new Uint16Array(wasmMem
.buffer
, addr
, u
>> 1)
181 const answer
= Number
.parseInt(word
, base
)
182 console
.log(`parsenum: ${addr} ${u} ${base}`)
183 console
.log(`parsenum: ${word} ${answer}`)
184 console
.log(`parsenum: ${Number.isNaN(answer)}`)
185 if (Number
.isNaN(answer
))
187 new DataView(wasmMem
.buffer
, addr
, 4).setUint32(0,answer
,true)
191 output
.print(Object
.getOwnPropertyNames(dictionary
).toString().split(',').join(' '))
196 fetch('forth.forth').then((re
) => re
.text()).then((txt
) => {
199 .then(re
=> re
.arrayBuffer())
200 .then(buf
=> WebAssembly
.instantiate(buf
, wasmImport
))
202 wasmMem
= result
.instance
.exports
.memory
203 forth
= result
.instance
.exports
.main
204 console
.log('wasm loaded');