duskos

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

commit 6247d39ddc67b255201353b96f047a3df6573d8f
parent 67a226bfd9ae2a03179f020c1bb7c50fb0f90e56
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed,  8 Jun 2022 08:37:27 -0400

Make the (s) literal return a string instead of a range

Diffstat:
Mboot.fs | 8+++++---
Mdusk.asm | 11+++++++++--
Mfs/cc/ast.fs | 10++++++----
Mfs/init.fs | 2+-
Mfs/lib/core.fs | 11+++++------
Mfs/lib/scratch.fs | 3+++
Mfs/str.fs | 21+++++++++------------
Mfs/sys/rdln.fs | 2+-
Mtests/testccast.fs | 4++--
Mtests/teststr.fs | 6+++---
10 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/boot.fs b/boot.fs @@ -37,14 +37,16 @@ create _ ')' c, : ( _ 1 waitw ; immediate ( hello, another comment! ) +: c@+ dup 1+ swap c@ ; +: c!+ tuck c! 1+ ; : fill ( a u b -- *A* ) rot> >r >A begin dup Ac!+ next drop ; : allot0 ( n -- ) here over 0 fill allot ; \ transform a fstring into a null-terminated string. create _ $100 allot -: tocstr ( sa sl -- a ) >r _ r@ move 0 _ r> + c! _ ; +: tocstr ( str -- a ) c@+ >r _ r@ move 0 _ r> + c! _ ; : fclose ( fd -- ) 6 ( close ) swap 0 0 ( close fd 0 0 ) lnxcall drop ; create _ 'C' c, 'a' c, 'n' c, ''' c, 't' c, $20 c, 'o' c, 'p' c, 'e' c, 'n' c, -: fopen ( sa sl -- fd ) +: fopen ( fname -- fd ) tocstr 5 ( open ) swap 0 0 ( open cstr noflag O_RDONLY ) lnxcall dup 0< if _ 10 rtype abort then ; create _ 1 allot @@ -58,5 +60,5 @@ _fds value 'curfd : f< ( -- c-or-0 ) fd@ fread ; : fin< f< ?dup not if ( EOF ) fd~ fd@ not if ['] iin< to in< then $20 then ; -: f<< word fopen >fd ['] fin< to in< ; +: f<< word 2drop 'curword fopen >fd ['] fin< to in< ; f<< init.fs diff --git a/dusk.asm b/dusk.asm @@ -156,12 +156,14 @@ defword '(alias)', 7, word_aliasroutine jnz to_is_set jmp [eax] +; String literal. What follows it is a byte with the length of the string. +; What we do here is to push the address of that string to PS, and then read +; that length byte, then skip that many bytes and jump there. defword '(s)', 3, word_strlit pop esi ; addr of str + pspush esi mov eax, 0 lodsb ; len - pspush esi ; addr of first char - pspush eax ; len add esi, eax ; ret to PC right after str jmp esi @@ -589,6 +591,11 @@ defword 'stack?', 6, word_stackcond call _rtype_loop jmp word_abort +; ( -- str ) +defword "'curword", 8, word_curwordaddr + pspush curword + ret + ; ( -- sa sl ) defword 'curword', 7, word_curword xor eax, eax diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -34,7 +34,7 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c, 3 c, 3 c, 4 c, 4 c, : bopid ( ta tl -- opid? f ) - >s BOPTlist sfind dup 0< if drop 0 else 1 then ; + r>str BOPTlist sfind dup 0< if drop 0 else 1 then ; : bopprec ( opid -- precedence ) BOPSCNT min bopsprectbl + c@ ; : boptoken ( opid -- ta tl ) BOPSCNT min ?dup if ( opid ) @@ -127,7 +127,7 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) \ Takes a token and returns the corresponding typedef (not AST type). \ For now, we always return 1 on "int". -: isType? ( ta tl -- typeid? f ) S" int" R= dup if 1 swap then ; +: isType? ( ta tl -- typeid? f ) S" int" c@+ R= dup if 1 swap then ; : expectConst ( ta tl -- n ) 2dup parse if rot> 2drop else _err then ; : expectIdent ( ta tl -- ta tl ) A>r 2dup >r >A begin Ac@+ identifier? _assert next r>A ; @@ -136,7 +136,9 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) \ Search the given token in a string list. if found, run the corresponding word \ in optbl. Otherwise, parse error. : tokenfromlist ( ta tl list optbl -- ) - >r rot> >s ( list R:optbl ) sfind dup 0< if s> _err then r> swap wexec ; + >r rot> r>str ( list tok R:optbl ) + dup rot sfind ( tok idx ) dup 0< if c@+ _err then ( tok idx ) + nip r> swap wexec ; \ The binopswap operation is funky. It happens when we want to add a binop that \ "eats up" the preceding node. There are 3 scenarios. @@ -178,7 +180,7 @@ ASTIDCNT wordtbl astparsetbl :w ( Statements ) StatementsTList StatementsOps tokenfromlist ; :w ( Arguments ) ')' expectChar SeqClose ; :w ( Expression ) - 2dup S" ;" R= if 2drop SeqClose exit then + 2dup S" ;" c@+ R= if 2drop SeqClose exit then activeempty? if 2dup uopid if UnaryOp 2drop exit then then 2dup bopid if ( ta tl binopid ) rot> 2drop ( bopid ) diff --git a/fs/init.fs b/fs/init.fs @@ -1,5 +1,5 @@ \ Initialization layer. Called at the end of boot.fs f<< lib/core.fs f<< sys/rdln.fs -: init S" Dusk OS" rtype rdln$ ; +: init S" Dusk OS" stype rdln$ ; init diff --git a/fs/lib/core.fs b/fs/lib/core.fs @@ -8,12 +8,11 @@ $08 value BS $04 value EOF : <> ( n n -- l h ) 2dup > if swap then ; : min <> drop ; : max <> nip ; -: c@+ dup 1+ swap c@ ; -: c!+ tuck c! 1+ ; - +\ emit all chars of "str" +: stype ( str -- ) c@+ rtype ; : ," begin in< dup '"' = if drop exit then c, again ; : S" compile (s) here 1 allot here ," here -^ ( 'len len ) swap c! ; immediate -: ." [compile] S" compile rtype ; immediate +: ." [compile] S" compile stype ; immediate : abort" [compile] ." compile abort ; immediate : [c]? ( c a u -- i ) @@ -31,5 +30,5 @@ create _ ," 0123456789abcdef" scnt >A begin dup .x spc> >r scnt not until begin r> scnt A> = until ; : .S ( -- ) - S" SP " rtype scnt .x1 spc> S" RS " rtype rcnt .x1 spc> - S" -- " rtype stack? psdump ; + S" SP " stype scnt .x1 spc> S" RS " stype rcnt .x1 spc> + S" -- " stype stack? psdump ; diff --git a/fs/lib/scratch.fs b/fs/lib/scratch.fs @@ -15,4 +15,7 @@ scratch( value scratch> : scratchallot ( n -- a ) scratch> over + scratch) >= if scratch( to scratch> then scratch> tuck + to scratch> ( a ) ; +\ push a range to the scratchpad as a string +: r>str ( a u -- str ) + dup 1+ scratchallot ( src u dst-1 ) >r dup r@ c!+ swap ( src dst u ) move r> ; diff --git a/fs/str.fs b/fs/str.fs @@ -1,24 +1,21 @@ \ String utilities -\ All string utilies operate on an "active string", which we set with ">s" $100 value STR_MAXSZ \ maximum size of strings (including size byte) -0 value sa -0 value sl - -: >s ( sa sl -- ) to sl to sa ; -: s> ( -- sa sl ) sa sl ; +\ is c a whitespace? : ws? ( c -- f ) SPC <= ; -: stype ( str -- ) c@+ rtype ; +\ Return whether s1 and s2 are equal +: s= ( s1 s2 -- f ) over c@ 1+ []= ; +\ "skip" str, that is, return the address following its last char +: s) ( str -- a ) c@+ + ; \ find active string in "list" and return its index, -1 if not found. \ A list is a simple sequence of strings (length byte, then contents, then \ another one...) ended by a 0 length -: sfind ( list -- idx ) -1 swap begin ( idx a ) - swap 1+ swap c@+ ( idx sa sl ) - ?dup not if 2drop -1 exit then ( idx sa sl ) - 2dup + rot> ( idx nexta sa sl ) s> R= until ( idx a ) - drop ( a ) ; +: sfind ( str list -- idx ) -1 rot> begin ( idx s a ) + rot 1+ rot> ( idx s a ) + 2dup s= if ( found ) 2drop exit then + s) dup c@ not until ( idx s a ) 2drop drop -1 ; \ trim whitespaces from the right of string : rtrim ( sa sl -- sa sl ) 1+ begin 1- 2dup + 1- c@ ws? not until ; diff --git a/fs/sys/rdln.fs b/fs/sys/rdln.fs @@ -13,7 +13,7 @@ in) value in> dup emitv dup rot c!+ ( c ptr+1 ) dup in) = rot SPC < or ( ptr+1 f ) then ; : rdln - in( LNSZ SPC fill S" ok" rtype nl> + in( LNSZ SPC fill S" ok" stype nl> in( begin key lntype until drop nl> ; : rdln<? ( -- c-or-0 ) in> in) < if in> c@+ swap to in> else 0 then ; diff --git a/tests/testccast.fs b/tests/testccast.fs @@ -6,8 +6,8 @@ opentestc parseast curunit firstchild dup astid AST_FUNCTION #eq ( fnode ) -: s S" retconst"; -dup 'data c@+ s R= # +: s S" retconst" ; +dup 'data s s= # firstchild nextsibling dup astid AST_STATEMENTS #eq ( snode ) firstchild dup astid AST_RETURN #eq ( rnode ) firstchild ( expr ) firstchild ( factor ) diff --git a/tests/teststr.fs b/tests/teststr.fs @@ -7,6 +7,6 @@ create list 3 c, ," bar" 0 c, -: _ S" foo" >s list sfind 1 #eq ; _ -: _ S" hello" >s list sfind 0 #eq ; _ -: _ S" baz" >s list sfind -1 #eq ; _ +: _ S" foo" list sfind 1 #eq ; _ +: _ S" hello" list sfind 0 #eq ; _ +: _ S" baz" list sfind -1 #eq ; _