duskos

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

commit 269aec12f9553fda9a261723fa5cff13f10a8718
parent a13b5d7b2f7af9fcca550f42525a42877299fee0
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Tue, 13 Sep 2022 14:32:34 -0400

cc/lib: implement fprintf, fputs, puts

Also, implement MemIO in sys/io.

Diffstat:
Mfs/app/cos/tools/blkpack.c | 21+++++++++++----------
Mfs/cc/lib.fs | 16++++++++++++----
Mfs/doc/io.txt | 17++++++++++++-----
Mfs/sys/io.fs | 25++++++++++++++++++++++---
Mfs/tests/cc/lib.fs | 11+++++++++++
5 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/fs/app/cos/tools/blkpack.c b/fs/app/cos/tools/blkpack.c @@ -1,7 +1,5 @@ // This doesn't actually work, I'm just drafting how it would look. -// TODO: string formatting // TODO: string scanning -// TODO: add \n in string literals // TODO: do multiple "return" paths work? // TODO: can we "return" early in a void function? // TODO: signed arithmetics @@ -35,7 +33,7 @@ unsigned int expectmarker(char *line) int blkid = getmarker(line); if (blkid < 0) { // could not scan fprintf( - stderr, "Error at line %d: expecting block marker\n", lineno); + lineno, "Error at line %d: expecting block marker\n", ConsoleOut()); abort(); } return blkid; @@ -51,7 +49,7 @@ extern void blkpack() { int cnt = strlen(line); lineno = 1; if (!cnt) { - fprintf(stderr, "No input\n"); + fprintf("No input\n", ConsoleOut()); abort(); } while (1) { @@ -59,15 +57,16 @@ extern void blkpack() { if ((blkid == 0) && (prevblkid >= 0)) { blkoff = (prevblkid / BUMP_GRANULARITY + 1) * BUMP_GRANULARITY; fprintf( - stderr, - "Block 0 encountered. Bumping current blkid to %d.\n", blkoff); + blkoff, + "Block 0 encountered. Bumping current blkid to %d.\n", + ConsoleOut()); } blkid += blkoff; if (blkid <= prevblkid) { fprintf( - stderr, + blkid, lineno, "Wrong blkid (%d) at line %d: blocks must be ordered\n", - blkid, lineno); + ConsoleOut()); abort(); } emptylines((blkid-prevblkid-1)*16); @@ -77,12 +76,14 @@ extern void blkpack() { cnt = strlen(line); if (cnt <= 0) break; // EOF if (cnt > 65) { - fprintf(stderr, "Line %d too long (blk %d)\n", lineno, blkid); + fprintf( + lineno, blkid, + "Line %d too long (blk %d)\n", ConsoleOut()); abort(); } if (getmarker(line) >= 0) break; // we have a marker early line[cnt-1] = '\0'; // remove newline - printf("%s", line); + puts(line); // pad line to 64 chars for (int i=cnt-1; i<64; i++) putchar(' '); } diff --git a/fs/cc/lib.fs b/fs/cc/lib.fs @@ -4,11 +4,19 @@ 0 const NULL : strlen c@ ; -: printf ( .. n1? n0? fmt ) - c@+ >r begin ( a ) \ V1=loopcnt +\ 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 ) + >r c@+ >r begin ( a ) \ V1=hdl V2=loopcnt c@+ dup '%' = if - -1 to+ V1 drop c@+ case ( n a ) + -1 to+ V2 drop c@+ case ( n a ) 'd' of = swap . endof abort" unsupported fmt argument" endcase - else stdout then next drop ; + else V1 IO :putc then next drop rdrop ; + +: printf ( .. n1? n0? fmt ) StdOut fprintf ; + +: fputs ( str io-hdl ) IO :puts ; +: puts ( str ) StdOut fputs ; diff --git a/fs/doc/io.txt b/fs/doc/io.txt @@ -59,13 +59,14 @@ convenience words: :putc ( c hdl -- ) Write 1 byte to hdl. Advance position by 1 byte. Aborts if unable to write. +:puts ( str hdl -- ) + Write str to hdl. + :putback ( c hdl -- ) Set the putback value to c. ## MemIO -(TODO: doesn't exist yet) - MemIO is a structure that extends IO and provides read/write capabilities to a memory buffer. It extends IO with those words: @@ -73,13 +74,19 @@ memory buffer. It extends IO with those words: Allocate a new buffer of size "sz" and return it. bufsz ( hdl -- sz ) - Size of the buffer + Size of the buffer. + +ptr ( hdl -- idx ) + Index of current position, relative to :buf(. :buf( ( hdl -- a ) - Address of the buffer + Address of the buffer. :)buf ( hdl -- a ) - Address following the last byte of the buffer + Address following the last byte of the buffer. + +:ptr ( hdl -- a ) + Address corresponding to current position. ## SystemIn and SystemOut diff --git a/fs/sys/io.fs b/fs/sys/io.fs @@ -5,15 +5,34 @@ here value _)buf struct+[ IO : :write ( a n self -- ) >r begin ( a n ) ?dup while - 2dup r@ :writebuf ?dup not if abort" error during write" then + 2dup r@ :writebuf ?dup not if _ioerr then ( a n written-n ) tuck - ( a written-n new-n ) rot> + swap repeat ( a ) drop rdrop ; : :putback ( c hdl ) to putback ; - : :putc ( c hdl -- ) swap _buf( c! _buf( 1 rot :writebuf ; + : :putc ( c hdl -- ) swap _buf( c! _buf( 1 rot :writebuf not if _ioerr then ; + : :puts ( str hdl -- ) swap c@+ rot :write ; +]struct + +extends IO struct[ MemIO + sfield bufsz \ size of buffer + sfield ptr \ starts at 0, stops at bufsz + SZ &+ :buf( + : :)buf dup :buf( swap bufsz + ; + : :ptr dup :buf( swap 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 ; + : _writebuf ( a n hdl -- written-n ) 'X' emit + >r V1 _maxn ( a write-n ) dup if ( a write-n ) + tuck V1 :ptr swap ( write-n a dst n ) move ( write-n ) dup V1 to+ ptr + else nip then rdrop ; + : :new ( sz -- hdl ) here swap ( hdl sz ) + 0 ( putback ) , ['] _readbuf , ['] _writebuf , ['] drop , ['] drop , + dup ( bufsz ) , 0 ( ptr ) , ( sz ) allot ; ]struct : stdin StdIn IO :getc ; -: stdout StdOut IO :putc not if _ioerr then ; +: stdout StdOut IO :putc ; : stdio$ ConsoleIn to StdIn ConsoleOut to StdOut ; \ TODO: move to IO struct diff --git a/fs/tests/cc/lib.fs b/fs/tests/cc/lib.fs @@ -8,4 +8,15 @@ foo 12 #eq :cfunc void foo(int n) { printf(n, "foo %d bar"); } 42 capture foo S" foo 42 bar" #s= + +:cfunc void foo() { puts("Hello World!"); } +capture foo S" Hello World!" #s= + +$20 MemIO :new const memio +S" What about this?" const s +\ TODO: allow memio() to be called inside fputs() parens. +:cfunc void foo() { int x; memio(); x = pspop(); fputs("What about this?", x); } +foo +memio MemIO ptr s strlen #eq +memio MemIO :buf( s c@+ []= # testend