aboutsummaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-09-09 02:02:08 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-09-09 02:02:08 -0400
commit1fbe2cb5dd1aa4b20411ee0c3b00310677373a55 (patch)
tree5362da93fdf255fd08b748e9a72b7179a719f4e0 /parse.c
parent6752c60f32d0e154e54f30fd2b3e22904e56ea64 (diff)
For parsing paths, use nested parens: (./foo), also add some methods
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/parse.c b/parse.c
index a3f8149b..eee8401e 100644
--- a/parse.c
+++ b/parse.c
@@ -1297,22 +1297,21 @@ PARSER(parse_text) {
}
PARSER(parse_path) {
- // ("~/" / "./" / "../" / "/") *([^ \t\r\n\\;] / "\" .)
+ // "(" ("~/" / "./" / "../" / "/") ... ")"
const char *start = pos;
- if (!(match(&pos, "~/")
- || match(&pos, "./")
- || match(&pos, "../")
- || match(&pos, "/")))
+ if (!(match(&pos, "(~/")
+ || match(&pos, "(./")
+ || match(&pos, "(../")
+ || match(&pos, "(/")))
return NULL;
- const char *chunk_start = start;
+ const char *chunk_start = start + 1;
ast_list_t *chunks = NULL;
CORD chunk_text = CORD_EMPTY;
- int depths[] = {[(int)'('] = 0, [(int)'{'] = 0, [(int)'['] = 0};
+ int paren_depth = 1;
while (pos < ctx->file->text + ctx->file->len) {
switch (*pos) {
- case '\r': case '\n': case ';': case ':': goto end_of_path;
case '\\': {
++pos;
chunk_text = CORD_asprintf("%r%.*s%c", chunk_text, (size_t)(pos - chunk_start), chunk_start, *pos);
@@ -1338,15 +1337,15 @@ PARSER(parse_path) {
chunk_start = pos;
continue;
}
- case ')': case '}': case ']': {
- if (depths[(int)*pos] <= 0)
- goto end_of_path;
- depths[(int)*pos] -= 1;
+ case '(': {
+ paren_depth += 1;
++pos;
continue;
}
- case '(': case '{': case '[': {
- depths[(int)*pos] += 1;
+ case ')': {
+ paren_depth -= 1;
+ if (paren_depth == 0)
+ goto end_of_path;
++pos;
continue;
}
@@ -1363,7 +1362,7 @@ PARSER(parse_path) {
chunks = new(ast_list_t, .ast=literal, .next=chunks);
}
- match(&pos, ";"); // optional trailing semicolon
+ expect_closing(ctx, &pos, ")", "I was expecting a ')' to finish this path");
REVERSE_LIST(chunks);
return NewAST(ctx->file, start, pos, TextJoin, .lang="Path", .children=chunks);