diff --git a/main.wl b/main.wl index 5d360c1..6482ea8 100644 --- a/main.wl +++ b/main.wl @@ -1,5 +1,4 @@ - -title = "My Website"; +title = "My Website" posts = [ { @@ -18,29 +17,28 @@ posts = [ { author: "User 2", date: "2 Jan 2025", content: "Second comment" }, ] }, -]; +] fun render_comment(c)
- $c.author; ($c.date;) -

$c.content;

+ \{c.author} (\c.date) +

\c.content

- $ for child in c.children: - render_comment(child); + \for child in c.children: + render_comment(child)
-export + - $title; + \title - $ for post in posts: { + \for post in posts:
- $post.title; ($post.date;) - $ for comment in post.comments: - render_comment(comment); + \{post.title} (\post.date) + \for comment in post.comments: + render_comment(comment)
- } diff --git a/src/assemble.c b/src/assemble.c index f034ab7..ffda626 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -3,8 +3,10 @@ #include #include +#ifndef WL_AMALGAMATION #include "parse.h" #include "assemble.h" +#endif #define MAX_SCOPES 32 #define MAX_VARS 1024 diff --git a/src/basic.c b/src/basic.c index f8db531..5057ce8 100644 --- a/src/basic.c +++ b/src/basic.c @@ -1,7 +1,9 @@ #include #include +#ifndef WL_AMALGAMATION #include "basic.h" +#endif b32 is_space(char c) { diff --git a/src/eval.c b/src/eval.c index d6a34ba..f100b52 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,4 +1,7 @@ + +#ifndef WL_AMALGAMATION #include "eval.h" +#endif #define FRAME_LIMIT 128 #define EVAL_STACK_LIMIT 128 diff --git a/src/file.c b/src/file.c index 9901fe5..402272f 100644 --- a/src/file.c +++ b/src/file.c @@ -9,7 +9,9 @@ #include #endif +#ifndef WL_AMALGAMATION #include "file.h" +#endif int file_open(String path, File *handle, int *size) { diff --git a/src/file.h b/src/file.h index 5785bff..4b93b96 100644 --- a/src/file.h +++ b/src/file.h @@ -1,7 +1,9 @@ #ifndef WL_FILE_INCLUDED #define WL_FILE_INCLUDED +#ifndef WL_AMALGAMATION #include "basic.h" +#endif #if _WIN32 #define WIN32_LEAN_AND_MEAN diff --git a/src/main.c b/src/main.c index 43a40c3..6c92fb3 100644 --- a/src/main.c +++ b/src/main.c @@ -14,8 +14,8 @@ int main(void) } char err[1<<9]; - char mem[1<<14]; - Arena a = { mem, COUNT(mem), 0 }; + char *mem = malloc(1<<20); + Arena a = { mem, 1<<20, 0 }; ParseResult result = parse(src, &a, err, COUNT(err)); if (result.node == NULL) { @@ -27,5 +27,6 @@ int main(void) fflush(stdout); free(src.ptr); + free(mem); return 0; } diff --git a/src/parse.c b/src/parse.c index 15c1509..3001ff3 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2,7 +2,9 @@ #include #include +#ifndef WL_AMALGAMATION #include "parse.h" +#endif typedef struct { char *src; @@ -43,7 +45,7 @@ typedef enum { TOKEN_DOT, TOKEN_COMMA, TOKEN_COLON, - TOKEN_SEMICOLON, + TOKEN_NEWLINE, } TokType; typedef struct { @@ -149,7 +151,8 @@ String tok2str(Token token, char *buf, int max) case TOKEN_DOT: return S("."); case TOKEN_COMMA: return S(","); case TOKEN_COLON: return S(":"); - case TOKEN_SEMICOLON: return S(";"); + + case TOKEN_NEWLINE: return S("\\n"); } return S("???"); @@ -378,12 +381,25 @@ Token next_token(Parser *p) if (consume_str(&p->s, S("."))) return (Token) { .type=TOKEN_DOT }; if (consume_str(&p->s, S(","))) return (Token) { .type=TOKEN_COMMA }; if (consume_str(&p->s, S(":"))) return (Token) { .type=TOKEN_COLON }; - if (consume_str(&p->s, S(";"))) return (Token) { .type=TOKEN_SEMICOLON }; report(p, "Invalid character '%c'", c); return (Token) { .type=TOKEN_ERROR }; } +Token next_token_or_newline(Parser *p) +{ + int peek = p->s.cur; + while (peek < p->s.len && is_space(p->s.src[peek]) && p->s.src[peek] != '\n') + peek++; + + if (peek < p->s.len && p->s.src[peek] == '\n') { + p->s.cur = peek+1; + return (Token) { .type=TOKEN_NEWLINE }; + } + + return next_token(p); +} + enum { IGNORE_GRT = 1 << 0, IGNORE_LSS = 1 << 1, @@ -398,7 +414,9 @@ Node *parse_html(Parser *p) Token t = next_token(p); if (t.type != TOKEN_IDENT) { - report(p, "HTML tag doesn't start with a name"); + char buf[1<<8]; + String ts = tok2str(t, buf, COUNT(buf)); + report(p, "HTML tag doesn't start with a name (got '%.*s' instead)", ts.len, ts.ptr); return NULL; } String tagname = t.sval; @@ -455,7 +473,7 @@ Node *parse_html(Parser *p) for (;;) { int off = p->s.cur; - while (p->s.cur < p->s.len && p->s.src[p->s.cur] != '<' && p->s.src[p->s.cur] != '$') + while (p->s.cur < p->s.len && p->s.src[p->s.cur] != '<' && p->s.src[p->s.cur] != '\\') p->s.cur++; if (p->s.cur > off) { @@ -474,7 +492,7 @@ Node *parse_html(Parser *p) if (p->s.cur == p->s.len || p->s.src[p->s.cur] == '<') break; - p->s.cur++; // Consume $ + p->s.cur++; // Consume \ { Node *child = parse_stmt(p, IGNORE_LSS); @@ -950,7 +968,7 @@ Node *parse_expr_inner(Parser *p, Node *left, int min_prec, int flags) for (;;) { Scanner saved = p->s; - Token t1 = next_token(p); + Token t1 = next_token_or_newline(p); if (precedence(t1, flags) < min_prec) { p->s = saved; break; @@ -963,7 +981,7 @@ Node *parse_expr_inner(Parser *p, Node *left, int min_prec, int flags) for (;;) { saved = p->s; - Token t2 = next_token(p); + Token t2 = next_token_or_newline(p); int p1 = precedence(t1, flags); int p2 = precedence(t2, flags); p->s = saved; @@ -1023,14 +1041,6 @@ Node *parse_expr_stmt(Parser *p, int opflags) if (e == NULL) return NULL; - if (e->type != NODE_VALUE_HTML) { - Token t = next_token(p); - if (t.type != TOKEN_SEMICOLON) { - report(p, "Missing ';' after expression"); - return NULL; - } - } - return e; } @@ -1317,21 +1327,19 @@ Node *parse_var_decl(Parser *p, int opflags) } String name = t.sval; + Scanner saved = p->s; t = next_token(p); - Node *value = NULL; + Node *value; if (t.type == TOKEN_OPER_ASS) { value = parse_expr(p, opflags); if (value == NULL) return NULL; - t = next_token(p); - } - - if (t.type != TOKEN_SEMICOLON) { - report(p, "Missing ';' at the end of a variable declaration"); - return NULL; + } else { + p->s = saved; + value = NULL; } Node *parent = alloc_node(p); @@ -1630,8 +1638,8 @@ void print_node(Node *node) node->func_name.ptr); Node *arg = node->func_args; while (arg) { - arg = arg->next; print_node(arg); + arg = arg->next; if (arg) printf(", "); } diff --git a/src/parse.h b/src/parse.h index 1b566a3..52f454b 100644 --- a/src/parse.h +++ b/src/parse.h @@ -2,7 +2,10 @@ #define WL_PARSE_INCLUDED #include + +#ifndef WL_AMALGAMATION #include "basic.h" +#endif typedef enum { NODE_FUNC_DECL,