summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-06-29 05:35:30 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-06-29 05:35:30 +0200
commit2b064f4a5f68e65e7f10abbb00ad7fef2f287463 (patch)
tree41c81c5c4a8a4fe6364ec4b433889581a17a8999
parent51faedabdf9745951392e629112048ba99224986 (diff)
Minor parser changes.
-rw-r--r--doc/0/1-parse.md68
-rw-r--r--src/zisp/io/Parser.zig16
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);