summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-05-31 20:58:42 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-05-31 20:58:42 +0200
commit37ff7af18cd2e896506e6d228058204525b4a6eb (patch)
treeb45e29afac99b8e6eb21f5eaf040f640221220e8 /src
parent6794e27eac3e866aa2b24999e2027b301a52ebf2 (diff)
More proper shebang line parsing.
Diffstat (limited to 'src')
-rw-r--r--src/zisp/io/Parser.zig45
1 files changed, 40 insertions, 5 deletions
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index 8e2908d..e29868a 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -620,11 +620,46 @@ fn endRuneDatum(p: *Parser) !void {
}
fn parseHashBang(p: *Parser, next: Fn) !void {
- while (try p.readNoEof2("hash-bang")) |c| {
- if (c == ' ' or c == '\t') continue;
- const s = try p.getBareString(c);
- return p.jump(next, p.cons(SHBANG, s));
- }
+ const val = try p.getHashBangValue();
+ return p.jump(next, p.cons(SHBANG, val));
+}
+
+fn getHashBangValue(p: *Parser) !Value {
+ while (try p.readNoEof2("hash-bang")) |c| switch (c) {
+ ' ', '\t' => continue,
+ '\n' => return p.err(.InvalidCharacter, "hash-bang"),
+ else => {
+ try p.addChar(c);
+ while (try p.read()) |c2| switch (c2) {
+ '\n' => return p.getCharsAsString(),
+ ' ', '\t' => break,
+ else => try p.addChar(c2),
+ };
+ const interp = try p.getCharsAsString();
+ if (try p.getHashBangArgLine()) |arg_line| {
+ return p.cons(interp, arg_line);
+ } else {
+ return interp;
+ }
+ },
+ };
+ unreachable;
+}
+
+fn getHashBangArgLine(p: *Parser) !?Value {
+ while (try p.read()) |c| switch (c) {
+ ' ', '\t' => continue,
+ '\n' => return null,
+ else => {
+ try p.addChar(c);
+ while (try p.read()) |c2| {
+ if (c2 == '\n') break;
+ try p.addChar(c2);
+ }
+ return try p.getCharsAsString();
+ },
+ };
+ return null;
}
fn parseLabel(p: *Parser, next: Fn) !void {