duskos

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

commit aba729fb99abadc1f34cc47d13f9a8c5d1caac10
parent e110728166b2ee1bba827fb55f0abc43232c1de0
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri,  9 Sep 2022 15:56:14 -0400

Add \n \r and \0 escapes in string literals

See doc/usage.

Diffstat:
Mfs/cc/tok.fs | 2+-
Mfs/doc/dict.txt | 3+++
Mfs/doc/usage.txt | 16++++++++++++++++
Mfs/sys/rdln.fs | 2+-
Mfs/xcomp/bootlo.fs | 2+-
Mfs/xcomp/i386.fs | 29++++++++++++++++++++++++++---
Mfs/xcomp/init.fs | 2+-
Mposix/vm.c | 48++++++++++++++++++++++++++++++++++--------------
8 files changed, 83 insertions(+), 21 deletions(-)

diff --git a/fs/cc/tok.fs b/fs/cc/tok.fs @@ -24,7 +24,7 @@ \ with a symbol that is also a 1 char symbol and all 3 chars symbols begin with \ 2 chars that are also a 2 chars symbol. \ list of 1 char symbols -create symbols1 ," +-*/~&<>=[](){}.%^?:;,|^#" '"' c, +create symbols1 ," +-*/~&<>=[](){}.%^?:;,|^#\"" : isSym1? ( c -- f ) symbols1 26 [c]? 0>= ; diff --git a/fs/doc/dict.txt b/fs/doc/dict.txt @@ -308,11 +308,14 @@ rebind 'data 'bind -- key -- c Read next character from system interactive input source. in< -- c Read next character from system input source. +"< -- c Read from in< and apply literal escapes. c=-1 when " is + read (end of string). emit c -- Emit character to system output destination. nl> -- Emit CR then LF. spc> -- Emit SPC. rtype a u -- Emit characters in range [a, a+u]. stype s -- Emit all characters in s. +," x" -- Read from in< until " is reached and write it to here. ." x" -- *IC* Emit string x. abort" x" -- *IC* Emit string x then abort. maybeword -- s-or-0 Try to read word from system input source and yield it as diff --git a/fs/doc/usage.txt b/fs/doc/usage.txt @@ -3,6 +3,22 @@ NOTE: this document isn't complete. I'm only writing a few notes that will end up being in the usage guide once it's done. +# String literals + +When a string literal word such as S" ." or ," is used, the following content +is parsed in an almost verbatim manner until the closing " is reached. We say +almost verbatim because we can write special characters with the '\' escape +character: + +\n: newline ($0a) +\r: carriage return ($0d) +\0: 0 +\\: '\' character +\": '"' character + +Any other character following the '\' results in that character being parsed as- +is, the preceding '\' being ignored. + # "to" semantics Values and aliases are very similar to cells: they're a piece of memory attached 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" stype nl> + in( LNSZ SPC fill S" ok\n" stype 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/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -161,7 +161,7 @@ $20 const SPC $0d const CR $0a const LF $08 const BS here 1 allot here ," here -^ ( 'len len ) swap c! ; immediate : ." compiling if [compile] S" compile stype else - begin in< dup '"' = not while emit repeat drop then ; immediate + begin "< dup 0>= while emit repeat drop then ; immediate : abort" [compile] ." compile abort ; immediate \ Return whether strings s1 and s2 are equal diff --git a/fs/xcomp/i386.fs b/fs/xcomp/i386.fs @@ -864,11 +864,34 @@ xcode parse ( str -- n? f ) bp CELLSZ d) neg, ret, -xcode ," +pc 7 nc, 'n' LF 'r' CR '0' 0 0 +xcode "< lblin< m) call, - AX pspop, - al '"' i) cmp, + [ebp] '"' i) cmp, + forward jnz, + [ebp] -1 i) mov, + ret, + forward! + [ebp] '\' i) cmp, + lblret abs>rel jnz, + ps-, + lblin< m) call, + si ( pc ) i) mov, +pc + lodsb, + al al test, lblret abs>rel jz, + [ebp] al cmp, + lodsb, + ( pc ) abs>rel jnz, + [ebp] al mov, + ret, + +xcode ," + wcall, "< + AX pspop, + ax ax test, + lblret abs>rel js, xwordlbl ," i) push, lblcwrite abs>rel jmp, diff --git a/fs/xcomp/init.fs b/fs/xcomp/init.fs @@ -6,5 +6,5 @@ f<< lib/diag.fs f<< sys/xhere.fs f<< sys/rdln.fs f<< lib/btrace.fs -: init S" Dusk OS" stype nl> .free rdln$ btrace$ ( unwind the boot RS ) quit ; +: init S" Dusk OS\n" stype .free rdln$ btrace$ ( unwind the boot RS ) quit ; init diff --git a/posix/vm.c b/posix/vm.c @@ -419,6 +419,36 @@ static void WRITE() { // op: 30 ISTOREADD(); } +#define ESCAPECNT 3 +static char escapes[ESCAPECNT][2] = {{'n', '\n'}, {'r', '\r'}, {'0', 0}}; +static void SRD() { // op: 31 + dword c; + callword(gd(INRD)); + c = ppop(); + if (c == '"') { + c = 0xffffffff; + } else if (c == '\\') { + callword(gd(INRD)); + c = ppop(); + for (int i=0; i<ESCAPECNT; i++) { + if ((dword)escapes[i][0] == c) { + c = escapes[i][1]; + } + } + } + ppush(c); +} + +static void SWR() { // op: 32 + dword c; + while (1) { + SRD(); + c = ppop(); + if (c==0xffffffff) return; + cwrite(c); + } +} + static void SETBW() { // op: 34 vm.bwidth = ppop(); } @@ -668,16 +698,6 @@ static void COMPILING() { // op: 57 ppush(vm.compiling); } -static void SWR() { // op: 58 - dword c; - while (1) { - callword(gd(INRD)); - c = ppop(); - if (c == '"') return; - cwrite(c); - } -} - static void STARTCOMP() { // op: 59 vm.compiling = 1; } @@ -948,12 +968,12 @@ static void (*ops[OPCNT])() = { DUP, CDUP, SWAP, OVER, ROT, ROTR, NIP, TUCK, RSADD, RSADDWR, RSADDR, RSADDRWR, SCNT, RCNT, SET16B, SET8B, FETCH, STORE, ADDSTORE, FETCHSTORE, FETCHADD, STOREADD, IFETCHADD, ISTOREADD, - WRITE, NULL, NULL, NULL, SETBW, NULL, NULL, NULL, + WRITE, SRD, SWR, NULL, SETBW, NULL, NULL, NULL, INC, DEC, ADD, SUB, MUL, DIVMOD, AND, NULL, OR, XOR, BOOL, NOT, LT, SHLC, SHRC, LSHIFT, RSHIFT, LITN, EXECUTEWR, EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD, PARSE, REQ, FIND, APOS, COMPILING, - SWR, STARTCOMP, STOPCOMP, COMPWORD, RUNWORD, NULL, NULL, NULL, + NULL, STARTCOMP, STOPCOMP, COMPWORD, RUNWORD, NULL, NULL, NULL, FCHILD, FOPEN, FREADBUF, FCLOSE, FINFO, FITER, NULL, NULL, MOUNTDRV, DRVRD, DRVWR}; @@ -964,12 +984,12 @@ static char *opnames[OPCNT] = { "dup", "?dup", "swap", "over", "rot", "rot>", "nip", "tuck", NULL, "r+,", NULL, "r',", "scnt", "rcnt", "16b", "8b", "@", "!", "+!", "@!", "@+", "!+", "@@+", "@!+", - ",", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + ",", "\"<", ",\"", NULL, NULL, NULL, NULL, NULL, "1+", "1-", "+", "-", "*", "/mod", "and", NULL, "or", "xor", "bool", "not", "<", "<<c", ">>c", "lshift", "rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word", "parse", "[]=", "find", "'", "compiling", - ",\"", "]", "[", "compword", "runword", NULL, NULL, NULL, + NULL, "]", "[", "compword", "runword", NULL, NULL, NULL, "_fchild", "_fopen", "_freadbuf", "_fclose", "_finfo", "_fiter", NULL, NULL, "_mountdrv", "_drv@", "_drv!"};