1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; UrForth level
1: self
-hosting
32-bit Forth compiler
3 ;; Copyright
(C
) 2020 Ketmar Dark
// Invisible Vector
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 ;; THIS IS NOT MULTITHREAD
-SAFE
!
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 [IFNDEF
] tty
" tty-low.f" tload
[ENDIF]
12 false constant
(ekey
-debug?
)
16 : (.keycode
) ( keycode
-- )
17 dup
33 127 within
if emit
18 else ." 0x" dup
0xffff u
> if .hex8
else .hex2
endif
22 : wait
-key
-dbg
( tout
-- keycode
)
24 endcr
." key: " dup
(.keycode
) cr
27 alias wait
-key wait
-key
-dbg
33 : (ekey
-esc
-read?
) ( key
-- key false
// 27 true
)
34 dup
0< over
27 = or dup
if 2drop
27 true
endif
37 : (ekey
-fix
-ctrl
-letter
) ( chcode
-- keycode
)
39 dup
9 = over
13 = or ifnot
40 [ [CHAR
] A
1- K
-CTRL
-MASK or
] literal
+
41 ;; xterm has it reversed
44 term
-type term
-xterm
= if
45 ;; xterm has it reversed
46 dup K
-BACKSPACE
= if drop K
-^H exit
endif
47 dup K
-^H
= if drop K
-BACKSPACE exit
endif
52 0 var
(ekey
-csi
-count
)
53 0 var
(ekey
-csi
-array
) 2 cells allot
55 0x1000 constant
(ekey
-csi
-flag
-mouse
)
56 0x2000 constant
(ekey
-csi
-flag
-linux
)
57 0 var
(ekey
-csi
-endchar
) ;; with flags
59 : (ekey
-parse
-csi
-init
) ( -- )
60 (ekey
-csi
-count
) 0! (ekey
-csi
-endchar
) 0! (ekey
-csi
-array
) 3 cells erase
63 ;; "false" means
"stop parsing"
64 : (ekey
-parse
-csi
-firstchar
) ( -- ch true
// ch false
)
66 esc
-timeout wait
-key
-dbg
(ekey
-esc
-read?
) if false exit
endif
68 [char
] I of K
-FOCUS
-IN false exit endof
69 [char
] O of K
-FOCUS
-OUT false exit endof
70 [char
] < of
(ekey
-csi
-flag
-mouse
) (ekey
-csi
-endchar
) ! -1 endof
71 [char
] [ of
(ekey
-csi
-flag
-linux
) (ekey
-csi
-endchar
) ! -1 endof
72 otherwise
;; keep the code
74 dup
-if drop esc
-timeout wait
-key
-dbg
(ekey
-esc
-read?
) if false exit
endif endif
78 ;; "false" means
"we're done"
79 : (ekey
-parse
-csi
-check
-firstchar
) ( char
-- char true
// false
)
80 ;; if it is not a digit and not a semi
, we have no args
82 dup
[char
] ; = ifnot
(ekey
-csi
-endchar
) or
! false exit
endif
87 : (ekey
-parse
-csi
-with
-args
) ( char
-- true
// keycode false
)
92 (ekey
-csi
-count
) @ dup
3 < if
93 (ekey
-csi
-array
) cells^
94 dup @
10 * rot
+ 32767 min swap
!
100 dup
[char
] ; = if drop
101 (ekey
-csi
-count
) @
16 > if K
-UNKNOWN false exit
endif
104 (ekey
-csi
-endchar
) or
!
109 esc
-timeout wait
-key
-dbg
(ekey
-esc
-read?
) if false exit
endif
113 : (ekey
-parse
-csi
) ( -- true
// keycode false
)
114 (ekey
-parse
-csi
-init
)
115 (ekey
-parse
-csi
-firstchar
) ifnot false exit
endif
116 (ekey
-parse
-csi
-check
-firstchar
) ifnot true exit
endif
117 (ekey
-parse
-csi
-with
-args
)
119 endcr
." CSI: n=" (ekey
-csi
-count
) @
.
120 ." n0=" (ekey
-csi
-array
) @
.
121 ." n1=" (ekey
-csi
-array
) cell
+ @
.
122 ." n2=" (ekey
-csi
-array
) 2 +cells @
.
123 ." endchar=" (ekey
-csi
-endchar
) @
(.keycode
)
124 ." xterm-mods=" (ekey
-csi
-array
) cell
+ @
(ekey
-xterm
-mods
) .hex8
130 : (ekey
-xterm
-mods
) ( csicode
-- modflags
)
132 2 of K
-SHIFT
-MASK endof
133 3 of K
-ALT
-MASK endof
134 4 of
[ K
-ALT
-MASK K
-SHIFT
-MASK or
] literal endof
135 5 of K
-CTRL
-MASK endof
136 6 of
[ K
-CTRL
-MASK K
-SHIFT
-MASK or
] literal endof
137 7 of
[ K
-CTRL
-MASK K
-ALT
-MASK or
] literal endof
138 8 of
[ K
-CTRL
-MASK K
-ALT
-MASK or K
-SHIFT
-MASK or
] literal endof
143 : (ekey
-xterm
-special
) ( upcase
-letter
-- keycode
)
145 [char
] A of K
-UP endof
146 [char
] B of K
-DOWN endof
147 [char
] C of K
-RIGHT endof
148 [char
] D of K
-LEFT endof
149 [char
] E of K
-PAD5 endof
150 [char
] H of K
-HOME endof
151 [char
] F of K
-END endof
152 [char
] P of K
-F1 endof
153 [char
] Q of K
-F2 endof
154 [char
] R of K
-F3 endof
155 [char
] S of K
-F4 endof
156 [char
] Z of K
-F1 K
-SHIFT
-MASK or endof
157 otherwise drop K
-UNKNOWN
162 : (ekey
-csi
-linux
-special
) ( chcode
-- keycode
)
164 [char
] A of K
-F1 endof
165 [char
] B of K
-F1 endof
166 [char
] C of K
-F2 endof
167 [char
] D of K
-F3 endof
168 otherwise drop K
-UNKNOWN
172 : (ekey
-csi
-xterm
-special
) ( chcode
-- keycode
)
176 : (ekey
-csi
-special
) ( csiarg0
-- keycode
)
178 1 of K
-HOME endof
;; xterm
182 5 of K
-PRIOR endof
;; pageup
183 6 of K
-NEXT endof
;; pagedown
184 7 of K
-HOME endof
;; rxvt
186 [ 1 10 + ] literal of K
-F1 endof
187 [ 2 10 + ] literal of K
-F2 endof
188 [ 3 10 + ] literal of K
-F3 endof
189 [ 4 10 + ] literal of K
-F4 endof
190 [ 5 10 + ] literal of K
-F5 endof
191 [ 6 11 + ] literal of K
-F6 endof
192 [ 7 11 + ] literal of K
-F7 endof
193 [ 8 11 + ] literal of K
-F8 endof
194 [ 9 11 + ] literal of K
-F9 endof
195 [ 10 11 + ] literal of K
-F10 endof
196 [ 11 12 + ] literal of K
-F11 endof
197 [ 12 12 + ] literal of K
-F12 endof
198 otherwise drop K
-UNKNOWN
202 : (ekey
-csi
-args
-0) ( -- chcode
)
203 (ekey
-csi
-endchar
) @ dup
0xff and swap
(ekey
-csi
-flag
-linux
) and
204 if (ekey
-csi
-linux
-special
) else (ekey
-csi
-xterm
-special
) endif
207 : (ekey
-csi
-args
-1-tilda
) ( -- chcode true
// false
)
208 (ekey
-csi
-array
) @ case
209 23 of
[ K
-SHIFT
-MASK K
-F1 or
] literal true endof
210 24 of
[ K
-SHIFT
-MASK K
-F2 or
] literal true endof
211 25 of
[ K
-SHIFT
-MASK K
-F3 or
] literal true endof
212 26 of
[ K
-SHIFT
-MASK K
-F4 or
] literal true endof
213 28 of
[ K
-SHIFT
-MASK K
-F5 or
] literal true endof
214 29 of
[ K
-SHIFT
-MASK K
-F6 or
] literal true endof
215 31 of
[ K
-SHIFT
-MASK K
-F7 or
] literal true endof
216 32 of
[ K
-SHIFT
-MASK K
-F8 or
] literal true endof
217 33 of
[ K
-SHIFT
-MASK K
-F9 or
] literal true endof
218 34 of
[ K
-SHIFT
-MASK K
-F10 or
] literal true endof
219 200 of K
-PASTE
-START true endof
220 201 of K
-PASTE
-END true endof
225 : (ekey
-csi
-args
-1-xterm
) ( chcode
-- chcode
)
226 (ekey
-csi
-array
) @
(ekey
-xterm
-mods
) swap
(ekey
-xterm
-special
)
227 dup K
-UNKNOWN
<> if or
else drop
endif ;; apply mask
230 : (ekey
-csi
-args
-1-mask
) ( chcode
-- mask true
// false
)
232 [char
] ^ of K
-CTRL
-MASK true endof
233 [char
] $ of K
-SHIFT
-MASK true endof
234 [char
] @ of
[ K
-CTRL
-MASK K
-SHIFT
-MASK or
] literal true endof
239 : (ekey
-csi
-args
-1) ( -- chcode
)
240 (ekey
-csi
-endchar
) @ dup
0xff and
[char
] ~
= if
241 drop
(ekey
-csi
-args
-1-tilda
) if exit
endif
244 dup
[char
] A
[char
] Z bounds?
if (ekey
-csi
-args
-1-xterm
) exit
endif
245 (ekey
-csi
-args
-1-mask
) ifnot K
-UNKNOWN exit
endif
248 (ekey
-csi
-array
) @
(ekey
-csi
-special
)
249 dup K
-UNKNOWN
<> if or
else drop
endif ;; apply mask
252 : (ekey
-csi
-args
-2) ( -- chcode
)
253 (ekey
-csi
-array
) cell
+ @
(ekey
-xterm
-mods
) ?dup ifnot K
-UNKNOWN exit
endif
254 (ekey
-csi
-endchar
) @
0xff and
255 (ekey
-csi
-array
) @
1 = if (ekey
-xterm
-special
)
256 else [char
] ~
= if (ekey
-csi
-array
) @
(ekey
-csi
-special
)
259 dup K
-UNKNOWN
<> if or
else drop
endif ;; apply mask
262 : (ekey
-csi
) ( -- keycode
)
263 (ekey
-parse
-csi
) ifnot exit
endif
264 ;; this seems
to be a csi
; check
for valid argcount
265 (ekey
-csi
-count
) @
2 > if K
-UNKNOWN exit
endif
266 ;; mouse events are not here yet
-- {\e
}[<0;58;32M
(button
;x
;y
;[Mm
])
267 (ekey
-csi
-endchar
) @
(ekey
-csi
-flag
-mouse
) and
if K
-UNKNOWN exit
endif
269 (ekey
-csi
-count
) @ case
270 0 of
(ekey
-csi
-args
-0) endof
271 1 of
(ekey
-csi
-args
-1) endof
272 2 of
(ekey
-csi
-args
-2) endof
273 otherwise drop K
-UNKNOWN
277 : (ekey
-rxvt
-keypad
) ( char
-- newchar true
// oldchar false
)
279 [char
] j of drop
[char
] * true endof
280 [char
] k of drop
[char
] + true endof
281 [char
] m of drop
[char
] - true endof
282 [char
] n of drop K
-DELETE true endof
283 [char
] o of drop
[char
] / true endof
284 [char
] p of drop K
-INSERT true endof
285 [char
] q of drop K
-END true endof
286 [char
] r of drop K
-DOWN true endof
287 [char
] s of drop K
-PRIOR true endof
288 [char
] t of drop K
-LEFT true endof
289 [char
] u of drop K
-PAD5 true endof
290 [char
] v of drop K
-RIGHT true endof
291 [char
] w of drop K
-HOME true endof
292 [char
] x of drop K
-UP true endof
293 [char
] y of drop K
-NEXT true endof
294 [char
] M of drop K
-ENTER true endof
300 ;; to: -1 is infinite
; 0 is no wait
301 : wait
-ekey
( mstimeout
-- key
// -1 )
302 get
-winch
if drop K
-WINCH exit
endif
303 wait
-key
-dbg dup
27 = ifnot
(ekey
-fix
-ctrl
-letter
) exit
endif
305 drop esc
-timeout wait
-key
-dbg
(ekey
-esc
-read?
) if exit
endif
308 drop esc
-timeout wait
-key
-dbg dup
0> if
309 (ekey
-esc
-read?
) if exit
endif
310 (ekey
-rxvt
-keypad
) ifnot
311 (* dup upcase
-char
(ekey
-xterm
-special
)
312 swap dup upcase
-char
<> if K
-SHIFT
-MASK or
endif *)
316 else drop
[char
] O
endif
319 dup
[char
] [ = if drop
(ekey
-csi
)
321 ;; ctrl mask
for non
-control keys
322 dup
[char
] A
>= over
[char
] Z
<= and
if K
-SHIFT
-MASK or
else upcase
-char
(ekey
-fix
-ctrl
-letter
) endif
327 : ekey?
( -- flag
) 0 wait
-key?
;
330 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331 : ekey
>fkey
( keycode
-- keycode ekeyflag
)
332 dup bl
< over
127 = or over
255 > or
335 : ekey
>char
( keycode
-- keycode false
// char true
)