aboutsummaryrefslogtreecommitdiff
path: root/src/z/parser/js/grammar/literal.zig
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2026-08-04 22:28:25 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2026-08-04 22:28:25 +0200
commit356c2bc0ccb1794b5ec219079d8c5b85ddcc4c87 (patch)
treedefa9a0e3c46af6e59e3be3d3ac1482c8fad24c8 /src/z/parser/js/grammar/literal.zig
parent06d1607aabad0a967c0500efe305de3fa732f8d3 (diff)
add templates to tokenizer
Diffstat (limited to 'src/z/parser/js/grammar/literal.zig')
-rw-r--r--src/z/parser/js/grammar/literal.zig63
1 files changed, 56 insertions, 7 deletions
diff --git a/src/z/parser/js/grammar/literal.zig b/src/z/parser/js/grammar/literal.zig
index 6a91291..039ebf4 100644
--- a/src/z/parser/js/grammar/literal.zig
+++ b/src/z/parser/js/grammar/literal.zig
@@ -4,11 +4,17 @@ const root = @import("root.zig");
const Lexer = root.Lexer;
const Token = root.Token;
-pub const Literal = enum {
+pub const Literal = union(enum) {
// NOTE: currently only decimal literals are tokenized
- numeric,
- bigint,
- string,
+ numeric: void,
+ bigint: void,
+ string: void,
+ template: enum {
+ whole,
+ start,
+ middle,
+ end,
+ },
const digits = "_0123456789abcdef";
@@ -60,9 +66,52 @@ pub const Literal = enum {
},
'\'', '"' => |quote| {
token.kind.literal = .string;
- while (try lexer.consume() != quote) {
- if (quote == '\\') {
- try lexer.consume();
+ while (true) {
+ switch (try lexer.consume()) {
+ quote => break,
+ '\\' => try lexer.consume(),
+ else => {},
+ }
+ }
+ },
+ '`' => {
+ token.kind.literal = .{ .template = undefined };
+
+ while (true) {
+ switch (try lexer.consume()) {
+ '`' => {
+ token.kind.literal.template = .whole;
+ break;
+ },
+ '\\' => try lexer.consume(),
+ '$' => if (lexer.peekChar() == '{') {
+ lexer.skip() catch unreachable;
+ lexer.context.template_nesting += 1;
+ token.kind.literal.template = .start;
+ break;
+ },
+ else => {},
+ }
+ }
+ },
+ '}' => if (lexer.context.template_nesting > 0) {
+ lexer.context.template_nesting -= 1;
+ token.kind.literal = .{ .template = undefined };
+
+ while (true) {
+ switch (try lexer.consume()) {
+ '`' => {
+ token.kind.literal.template = .end;
+ break;
+ },
+ '\\' => try lexer.consume(),
+ '$' => if (lexer.peekChar() == '{') {
+ lexer.skip() catch unreachable;
+ lexer.context.template_nesting += 1;
+ token.kind.literal.template = .middle;
+ break;
+ },
+ else => {},
}
}
},