1 ;; Native x86 GNU/Linux Forth System, Direct Threaded Code
3 ;; Copyright (C) 2020 Ketmar Dark // Invisible Vector
5 ;; This program is free software: you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, version 3 of the License ONLY.
9 ;; This program is distributed in the hope that it will be useful,
10 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ;; GNU General Public License for more details.
14 ;; You should have received a copy of the GNU General Public License
15 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 urword_code
"ZCOUNT",zcount
20 ;; ( addr -- addr count )
21 ;; length of asciiz string
40 urword_alias
"COUNT-ONLY",count_only
,peek
43 urword_code
"COUNT",count
44 ;; ( addr -- addr+4 count )
45 ;UF dup count_only swap cellinc swap exit
54 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 urword_code
"S=",strequ
56 ;; ( addr0 count0 addr1 count1 -- flag )
66 ; now EIP is saved on the stack
93 ; ascii case-insensitive compare
94 urword_code
"S=CI",strequ_ci
95 ;; ( addr0 count0 addr1 count1 -- flag )
105 ; now EIP is saved on the stack
156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
157 urword_code
"UPCASE-CHAR",upcase_char
169 urword_code
"UPCASE-STR",upcase_str
173 jr nz
,fword_upcase_str_done
175 jr z
,fword_upcase_str_done
176 fword_upcase_str_loop:
185 loop fword_upcase_str_loop
186 fword_upcase_str_done:
192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193 ;; converts some escape codes in-place
194 ;; used for `."` and `"`
195 ;; the resulting string is never bigger that the source one
196 ;; this will not preserve the trailing zero byte
197 urword_code
"STR-UNESCAPE",str_unescape
198 ;; ( addr count -- addr count )
209 ; edi is after backslash
210 ; ecx is number of chars left after backslash
211 ; found backslash, check next char
249 ; '\`'? (double quote)
275 ; save original string position
294 ; combine two hex digits
304 ; remove leftover chars
306 ; ESI: position after backslash
308 ; old ESI is on the stack
309 push esi ; to be restored in EDI
314 pop edi ; get back to backslash
315 pop esi ; restore old ESI
352 ; maybe its lowercase?
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 urword_code
"STR-TRIM-AFTER-LAST-CHAR",str_trim_after_last_char
372 ;; ( addr count char -- addr count )
373 ;; `count` will be 0 if there is no char
374 ;; `count` will include char
375 ;; `addr` is not changed in any case
376 ; i can do it faster, but meh...
398 urword_code
"STR-TRIM-AFTER-CHAR",str_trim_after_char
399 ;; ( addr count char -- addr count )
400 ;; `count` will be 0 if there is no char
401 ;; `count` will not include a colon
402 ;; `addr` is not changed in any case
403 ; i can do it faster, but meh...
427 urword_forth
"STR-SKIP-AFTER-LAST-CHAR",str_skip_after_last_char
428 ;; ( addr count char -- addr count )
429 ;; `count` will be 0 if there is no char (and `addr` will be unchanged)
430 ;; `addr` will not include char
431 UF rpush
2dup rpop str_trim_after_last_char
433 UF
- swap rpop
+ swap
436 urword_forth
"STR-SKIP-AFTER-CHAR",str_skip_after_char
437 ;; ( addr count char -- addr count )
438 ;; `count` will be 0 if there is no char (and `addr` will be unchanged)
439 ;; `addr` will not include char
440 UF rpush
2dup rpop str_trim_after_char
442 UF
- swap rpop
+ swap
446 urword_forth
"STR-TRIM-AT-LAST-CHAR",str_trim_at_last_char
447 ;; ( addr count char -- addr count )
448 ;; `count` will be 0 if there is no char
449 ;; `count` will not include char
450 ;; `addr` is not changed in any case
451 UF str_trim_after_last_char dup
457 urword_forth
"STR-TRIM-AT-CHAR",str_trim_at_char
458 ;; ( addr count char -- addr count )
459 ;; `count` will be 0 if there is no char
460 ;; `count` will not include char
461 ;; `addr` is not changed in any case
462 UF str_trim_after_char dup
469 urword_forth
"STR-SKIP-AT-LAST-CHAR",str_skip_at_last_char
470 ;; ( addr count char -- addr count )
471 ;; `count` will be 0 if there is no char (and `addr` will be unchanged)
472 ;; `addr` will not include char
473 UF rpush
2dup rpop str_trim_at_last_char
475 UF
- swap rpop
+ swap
478 urword_forth
"STR-SKIP-AT-CHAR",str_skip_at_char
479 ;; ( addr count char -- addr count )
480 ;; `count` will be 0 if there is no char (and `addr` will be unchanged)
481 ;; `addr` will not include char
482 UF rpush
2dup rpop str_trim_at_char
484 UF
- swap rpop
+ swap
488 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
489 urword_forth
"STR-EXTRACT-PATH",str_extract_path
490 ;; ( addr count -- addr count )
491 ;; count can be 0 if no path there
492 ;; trailing '/' is included
493 UF
47 str_trim_after_last_char
496 urword_forth
"STR-EXTRACT-NAME",str_extract_name
497 ;; ( addr count -- addr count )
498 ;; count can be 0 if no name there (and `addr` is not changed)
499 UF
47 str_skip_after_last_char
502 urword_forth
"STR-EXTRACT-EXT",str_extract_ext
503 ;; ( addr count -- addr count )
504 ;; count can be 0 if no extension there (and `addr` is not changed)
506 UF
2dup str_extract_name qdup
508 ;; ( addr count dummyaddr )
511 ;; ( addr count naddr ncount )
512 UF
46 str_skip_at_last_char qdup
514 ;; ( addr count dummyaddr )
517 ;; ( addr count extaddr extcount )
522 urword_forth
"STR-EXTRACT-BASE-NAME",str_extract_base_name
523 ;; ( addr count -- addr count )
524 ;; count can be 0 if no base name there (and `addr` is not changed)
526 UF
2dup str_extract_name qdup
528 ;; no file name, nothing to extract
532 ;; ( addr count nameaddr namecount )
533 UF
2dup
46 str_trim_at_last_char
534 ;; ( addr count nameaddr namecount bnaddr bncount )
537 ;; ( addr count nameaddr namecount dummyaddr )
538 UF drop
2rpush
2drop
2rpop exit
540 ;; ( addr count nameaddr namecount bnaddr bncount )
541 UF
2rpush
2drop
2drop
2rpop
545 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
546 urword_forth
"C4S-ZTERM",c4s_zterm
551 urword_forth
"C4S-COPY",c4s_copy
552 ;; ( addrsrc addrdest -- )
553 UF rpush dup count_only cellinc rpop swap cmove
556 urword_forth
"C4S-COPY-A-C",c4s_copy_ac
557 ;; ( addrsrc count addrdest -- )
559 UF cellinc swap cmove
561 urword_alias
"C4S-COPY-COUNTED",c4s_copy_counted
,c4s_copy_ac
563 urword_forth
"C4S-CAT-A-C",c4s_cat_ac
564 ;; ( addr count addrdest -- )
567 UF dup rpush count
+ swap dup rpush cmove
573 urword_alias
"C4S-CAT-COUNTED",c4s_cat_counted
,c4s_cat_ac