diff options
| -rw-r--r-- | doc/0/1-parse.md | 68 | ||||
| -rw-r--r-- | src/zisp/io/Parser.zig | 16 |
2 files changed, 42 insertions, 42 deletions
diff --git a/doc/0/1-parse.md b/doc/0/1-parse.md index 91407da..95a22bb 100644 --- a/doc/0/1-parse.md +++ b/doc/0/1-parse.md @@ -5,11 +5,11 @@ Zisp s-expressions represent an extremely minimal set of data types; only that which is necessary to strategically construct more complex values: - +---------+--------+--------+ - | String | List | Rune | - +---------+--------+--------+ - | foobar | (...) | #name | - +---------+--------+--------+ + +--------+---------+--------+ + | List | String | Rune | + +--------+---------+--------+ + | (...) | foobar | #name | + +--------+---------+--------+ The parser recognizes various *syntax sugar* which abbreviates verbose syntax, and may result in special data structures (typically, a list with a rune in its @@ -159,6 +159,26 @@ These are in fact value types, though the term "data type" is often used due to familiarity. A Zisp value that is a member of one of the following value types is only a *datum* if it adheres to additional constraints as explained below. +### List + +A list is a sequence of values with a fixed length. + +A unique, contiguous array of values is allocated in program memory for each +list of non-zero length, and the list as a value is then represented by the +memory address of the array. The empty list is represented by a distinct +canonical bit pattern. + +Lists are valid as a datum if one of the following holds true: + +* The list encodes a quoted string, datum label, or shebang line. + +* All values in the list are a valid datum, or it is empty. + +Further, a structure of nested list values may not contain cyclic references +back up in the structure (which would make the above definition diverge into +infinity). Such cycles must be broken up with datum labels, or else the list +cannot be considered a datum, since it cannot be printed or parsed. + ### String Strings can appear *bare* or be quoted in various ways. A quoted string is in @@ -199,26 +219,6 @@ contain NUL bytes, in which case this optimization isn't used.) Longer strings may be *interned* which is a feature explained further below. Otherwise, each string is allocated separately, and represented by its unique memory address. -### List - -A list is a sequence of values with a fixed length. - -A unique, contiguous array of values is allocated in program memory for each -list of non-zero length, and the list as a value is then represented by the -memory address of the array. The empty list is represented by a distinct -canonical bit pattern. - -Lists are valid as a datum if one of the following holds true: - -* The list encodes a quoted string, datum label, or shebang line. - -* All values in the list are a valid datum, or it is empty. - -Further, a structure of nested list values may not contain cyclic references -back up in the structure (which would make the above definition diverge into -infinity). Such cycles must be broken up with datum labels, or else the list -cannot be considered a datum, since it cannot be printed or parsed. - ### Rune A rune is represented by an ASCII character sequence of 1 to 6 bytes, that must @@ -490,15 +490,15 @@ need to use it. The following table summarizes commonly useful syntax abbreviations: - [...] -> (#SQUARE ...) #datum -> (#HASH datum) + [...] -> (#SQBRAC ...) #<datum> -> (#HASH <datum>) - {...} -> (#BRACE ...) #rune(...) -> (#rune ...) + {...} -> (#CRBRAC ...) #rune<datum> -> (#rune <datum>) - 'datum -> (#QUOTE datum) dat1dat2 -> (#JOIN dat1 dat2) + '<datum> -> (#QUOTE <datum>) <dat1><dat2> -> (#JOIN <dat1> <dat2>) - `datum -> (#GRAVE datum) dat1.dat2 -> (#DOT dat1 dat2) + `<datum> -> (#GRAVE <datum>) <dat1>.<dat2> -> (#JDOT <dat1> <dat2>) - ,datum -> (#COMMA datum) dat1:dat2 -> (#COLON dat1 dat2) + ,<datum> -> (#COMMA <datum>) <dat1>:<dat2> -> (#JCOL <dat1> <dat2>) Notes: @@ -533,15 +533,15 @@ Notes: or may not actually have a meaning in code; some might simply end up producing an error during decoding, or later execution, of code. - #{...} -> (#HASH (#BRACE ...)) + #{...} -> (#HASH (#CRBRAC ...)) #'foo -> (#HASH (#QUOTE foo)) - ##'[...] -> (#HASH (#HASH (#QUOTE (#SQUARE ...)))) + ##'[...] -> (#HASH (#HASH (#QUOTE (#SQBRAC ...)))) - {x y}[i j] -> (#JOIN (#BRACE x y) (#SQUARE i j)) + {x y}[i j] -> (#JOIN (#CRBRAC x y) (#SQBRAC i j)) - foo.bar.baz{x y} -> (#JOIN (#DOT (#DOT foo bar) baz) (#BRACE x y)) + foo.bar.baz{x y} -> (#JOIN (#JDOT (#JDOT foo bar) baz) (#CRBRAC x y)) * Those used to thinking in Lisp and Scheme may think that `(#QUOTE ...)` halts further decoding of enclosed data. This is not so, since quoting is related diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index 6dcfe42..b1db437 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -57,8 +57,8 @@ const is_debug = builtin.mode == .Debug; const detailed_debug = false; // zig fmt: off -pub const DOT = value.rune.pack("DOT"); -pub const COLON = value.rune.pack("COLON"); +pub const JDOT = value.rune.pack("JDOT"); +pub const JCOL = value.rune.pack("JCOL"); pub const JOIN = value.rune.pack("JOIN"); pub const SHBANG = value.rune.pack("SHBANG"); pub const LABEL = value.rune.pack("LABEL"); @@ -69,8 +69,8 @@ pub const ATSTR = value.rune.pack("ATSTR"); pub const QUOTE = value.rune.pack("QUOTE"); pub const GRAVE = value.rune.pack("GRAVE"); pub const COMMA = value.rune.pack("COMMA"); -pub const SQUARE = value.rune.pack("SQUARE"); -pub const BRACE = value.rune.pack("BRACE"); +pub const SQBRAC = value.rune.pack("SQBRAC"); +pub const CRBRAC = value.rune.pack("CRBRAC"); // zig fmt: on pub const Error = enum { @@ -483,8 +483,8 @@ fn endJoinDatum(p: *Parser) !void { } const rune = switch (join) { 0 => JOIN, - '.' => DOT, - ':' => COLON, + '.' => JDOT, + ':' => JCOL, else => unreachable, }; const joined = try p.makeList(&.{ rune, prev, p.result }); @@ -802,8 +802,8 @@ fn parseList(p: *Parser, open: u8, next: Fn) !void { p.context.list_start = p.list_elts.items.len; switch (open) { '(' => {}, - '[' => try p.addListElt(SQUARE), - '{' => try p.addListElt(BRACE), + '[' => try p.addListElt(SQBRAC), + '{' => try p.addListElt(CRBRAC), else => unreachable, } return p.subr(.parseUnit, .continueList); |
