duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 296794bcb62bfc89167f02f23301698be41de294
parent dceccf2ca00c8133c7c60e3cd508bd203dc100ed
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed, 14 Sep 2022 12:53:11 -0400

cc/lib: implement sprintf fscanf scanf sscanf

Also, make lib/nfmt use stdout instead of emit and fix fprintf when io-hdl is
not ConsoleOut.

Diffstat:
Mfs/app/cos/tools/blkpack.c | 1-
Mfs/cc/lib.fs | 32+++++++++++++++++++++++++++++---
Mfs/lib/nfmt.fs | 10+++++-----
Mfs/sys/io.fs | 1+
Mfs/tests/cc/lib.fs | 12++++++++++++
5 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/fs/app/cos/tools/blkpack.c b/fs/app/cos/tools/blkpack.c @@ -1,5 +1,4 @@ // This doesn't actually work, I'm just drafting how it would look. -// TODO: string scanning #[ 10 const BUMP_GRANULARITY ]# diff --git a/fs/cc/lib.fs b/fs/cc/lib.fs @@ -1,5 +1,6 @@ \ C library \ Isn't needed by the compiler, so it can have C code. +?f<< /lib/str.fs 0 const NULL : strlen c@ ; @@ -7,16 +8,41 @@ \ TODO: write this in C. but for this, we need to have 8-bit operations on char \ arrays. As CC works now, we can't iterate through a "char*". -: fprintf ( .. n1? n0? fmt io-hdl ) +$100 MemIO :new const _sio + +: fprintf ( .. n1? n0? fmt io-hdl -- ) >r c@+ >r begin ( a ) \ V1=hdl V2=loopcnt c@+ dup '%' = if -1 to+ V2 drop c@+ case ( n a ) - 'd' of = swap . endof + 'd' of = swap V1 to@! StdOut swap . to StdOut endof abort" unsupported fmt argument" endcase else V1 IO :putc then next drop rdrop ; -: printf ( .. n1? n0? fmt ) StdOut fprintf ; +: printf ( .. n1? n0? fmt -- ) StdOut fprintf ; + +(S ... fmt -- str ) +: sprintf + 1 to _sio MemIO ptr _sio fprintf + _sio MemIO ptr 1- ( len ) _sio MemIO :buf( tuck c! ; : fputs ( str io-hdl ) IO :puts ; : puts ( str ) StdOut fputs ; + +: _err abort" scanf not matching" ; +: fscanf ( .. n1? n0? fmt io-hdl -- ) + >r c@+ >r begin ( a ) \ V1=hdl V2=loopcnt + c@+ dup '%' = if + -1 to+ V2 drop c@+ case ( dst a ) + 'd' of = + swap 0 ( a dst res ) V1 IO :getc dup 0< if _err then + ( a dst res c ) dup 0-9? not if _err then begin ( a dst res c ) + '0' - swap 10 * + V1 IO :getc dup 0-9? not until ( a dst res c ) + V1 IO :putback ( a dst res ) swap ! ( a ) endof + abort" unsupported fmt argument" + endcase + else ( a c ) V1 IO :getc <> if _err then then next drop rdrop ; + +: scanf ( .. n1? n0? fmt -- ) StdOut fscanf ; +: sscanf ( .. n1? n0? fmt str -- ) + _sio MemIO :rewind c@+ _sio IO :write _sio MemIO :rewind _sio fscanf ; diff --git a/fs/lib/nfmt.fs b/fs/lib/nfmt.fs @@ -1,7 +1,7 @@ \ Number formatting \ hexadecimal create _ ," 0123456789abcdef" -: .xh $f and _ + c@ emit ; +: .xh $f and _ + c@ stdout ; : .x1 dup 4 rshift .xh .xh ; : .x2 dup 8 rshift .x1 .x1 ; \\ print top of stack in hexadecimal @@ -10,11 +10,11 @@ create _ ," 0123456789abcdef" : .x? dup $ffff > if .x else dup $ff > if .x2 else .x1 then then ; \ decimal -: _ 10 /mod ( r q ) ?dup if _ then '0' + emit ; +: _ 10 /mod ( r q ) ?dup if _ then '0' + stdout ; : . ( n -- ) ?dup not if - '0' emit else - dup 0< if '-' emit 0 -^ _ else _ then + '0' stdout else + dup 0< if '-' stdout 0 -^ _ else _ then then ; \ size create _ ," KMG" @@ -22,5 +22,5 @@ create _ ," KMG" 0 begin ( sz lvl ) swap 1024 /mod ( lvl r q ) ?dup while nip swap 1+ repeat ( lvl sz ) - . ?dup if 1- _ + c@ emit then 'B' emit ; + . ?dup if 1- _ + c@ stdout then 'B' stdout ; diff --git a/fs/sys/io.fs b/fs/sys/io.fs @@ -19,6 +19,7 @@ extends IO struct[ MemIO SZ &+ :buf( : :)buf dup :buf( swap bufsz + ; : :ptr dup :buf( swap ptr + ; + : :rewind 0 swap to ptr ; : _maxn ( n hdl -- real-n ) >r V1 ptr + V1 bufsz min r> ptr - ; : _readbuf ( n hdl -- a? read-n ) >r V1 _maxn ( read-n ) dup if V1 :ptr swap dup V1 to+ ptr then rdrop ; diff --git a/fs/tests/cc/lib.fs b/fs/tests/cc/lib.fs @@ -9,6 +9,9 @@ foo 12 #eq :cfunc void foo(int n) { printf(n, "foo %d bar"); } 42 capture foo S" foo 42 bar" #s= +:cfunc char* foo(int n) { return sprintf(n, "foo %d bar"); } +54 foo S" foo 54 bar" #s= + :cfunc void foo() { puts("Hello World!"); } capture foo S" Hello World!" #s= @@ -18,4 +21,13 @@ S" What about this?" const s foo memio MemIO ptr s strlen #eq memio MemIO :buf( s c@+ []= # + +:cfunc int foo(char *s) { + int x; + sscanf(&x, "foo %d bar", s); + return x; +} + +S" foo 42 bar" foo 42 #eq + testend