From 83a2bff4bb04b0189d17419baf8ca520992d5033 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 23 Nov 2025 15:57:44 -0500 Subject: Added Metadata section for files instead of _HELP and _USAGE --- src/parse/expressions.c | 2 +- src/parse/files.c | 41 +++++++++++++++++++++++++++++++++++++---- src/parse/text.c | 12 +++++++----- src/parse/text.h | 4 +++- 4 files changed, 48 insertions(+), 11 deletions(-) (limited to 'src/parse') diff --git a/src/parse/expressions.c b/src/parse/expressions.c index b43e4f3a..d031c49f 100644 --- a/src/parse/expressions.c +++ b/src/parse/expressions.c @@ -168,7 +168,7 @@ ast_t *parse_term_no_suffix(parse_ctx_t *ctx, const char *pos) { (void)(false || (term = parse_none(ctx, pos)) || (term = parse_num(ctx, pos)) // Must come before int || (term = parse_int(ctx, pos)) || (term = parse_negative(ctx, pos)) // Must come after num/int || (term = parse_heap_alloc(ctx, pos)) || (term = parse_stack_reference(ctx, pos)) - || (term = parse_bool(ctx, pos)) || (term = parse_text(ctx, pos)) || (term = parse_path(ctx, pos)) + || (term = parse_bool(ctx, pos)) || (term = parse_text(ctx, pos, true)) || (term = parse_path(ctx, pos)) || (term = parse_lambda(ctx, pos)) || (term = parse_parens(ctx, pos)) || (term = parse_table(ctx, pos)) || (term = parse_var(ctx, pos)) || (term = parse_list(ctx, pos)) || (term = parse_reduction(ctx, pos)) || (term = parse_pass(ctx, pos)) || (term = parse_defer(ctx, pos)) || (term = parse_skip(ctx, pos)) diff --git a/src/parse/files.c b/src/parse/files.c index 23e940e9..f5d9554a 100644 --- a/src/parse/files.c +++ b/src/parse/files.c @@ -7,8 +7,11 @@ #include #include "../ast.h" +#include "../stdlib/datatypes.h" +#include "../stdlib/paths.h" #include "../stdlib/stdlib.h" #include "../stdlib/tables.h" +#include "../stdlib/text.h" #include "../stdlib/util.h" #include "context.h" #include "errors.h" @@ -31,6 +34,35 @@ static ast_t *parse_top_declaration(parse_ctx_t *ctx, const char *pos) { return declaration; } +static ast_t *parse_metadata(parse_ctx_t *ctx, const char *pos) { + const char *start = pos; + const char *key = get_id(&pos); + if (!key) return NULL; + spaces(&pos); + if (!match(&pos, ":")) return NULL; + spaces(&pos); + ast_t *value = parse_text(ctx, pos, false); + Text_t value_text = EMPTY_TEXT; + if (value) { + for (ast_list_t *child = Match(value, TextJoin)->children; child; child = child->next) { + if (child->ast->tag != TextLiteral) + parser_err(ctx, child->ast->start, child->ast->end, "Text interpolations are not allowed in metadata"); + value_text = Texts(value_text, Match(child->ast, TextLiteral)->text); + } + } else { + value = parse_path(ctx, pos); + if (!value) return NULL; + Path_t path = Path$from_str(Match(value, Path)->path); + path = Path$resolved(path, Path$parent(Path$from_str(ctx->file->filename))); + OptionalText_t contents = Path$read(path); + if (contents.tag == TEXT_NONE) parser_err(ctx, value->start, value->end, "File not found: ", path); + value_text = Text$trim(contents, Text("\r\n\t "), true, true); + } + pos = value->end; + + return NewAST(ctx->file, start, pos, Metadata, .key = Text$from_str(key), .value = value_text); +} + ast_t *parse_file_body(parse_ctx_t *ctx, const char *pos) { const char *start = pos; whitespace(ctx, &pos); @@ -40,10 +72,11 @@ ast_t *parse_file_body(parse_ctx_t *ctx, const char *pos) { whitespace(ctx, &next); if (get_indent(ctx, next) != 0) break; ast_t *stmt; - if ((stmt = optional(ctx, &pos, parse_struct_def)) || (stmt = optional(ctx, &pos, parse_func_def)) - || (stmt = optional(ctx, &pos, parse_enum_def)) || (stmt = optional(ctx, &pos, parse_lang_def)) - || (stmt = optional(ctx, &pos, parse_convert_def)) || (stmt = optional(ctx, &pos, parse_use)) - || (stmt = optional(ctx, &pos, parse_inline_c)) || (stmt = optional(ctx, &pos, parse_top_declaration))) { + if ((stmt = optional(ctx, &pos, parse_metadata)) || (stmt = optional(ctx, &pos, parse_struct_def)) + || (stmt = optional(ctx, &pos, parse_func_def)) || (stmt = optional(ctx, &pos, parse_enum_def)) + || (stmt = optional(ctx, &pos, parse_lang_def)) || (stmt = optional(ctx, &pos, parse_convert_def)) + || (stmt = optional(ctx, &pos, parse_use)) || (stmt = optional(ctx, &pos, parse_inline_c)) + || (stmt = optional(ctx, &pos, parse_top_declaration))) { statements = new (ast_list_t, .ast = stmt, .next = statements); pos = stmt->end; whitespace(ctx, &pos); // TODO: check for newline diff --git a/src/parse/text.c b/src/parse/text.c index 7650955c..e23b8417 100644 --- a/src/parse/text.c +++ b/src/parse/text.c @@ -17,7 +17,7 @@ #include "types.h" #include "utils.h" -static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos) { +static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, bool allow_interps) { const char *pos = *out_pos; int64_t starting_indent = get_indent(ctx, pos); @@ -41,6 +41,8 @@ static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos) { parser_err(ctx, pos, pos, "I expected a valid text here"); } + if (!allow_interps) interp = NULL; + ast_list_t *chunks = NULL; Text_t chunk = EMPTY_TEXT; const char *chunk_start = pos; @@ -123,9 +125,9 @@ static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos) { return chunks; } -ast_t *parse_text(parse_ctx_t *ctx, const char *pos) { +ast_t *parse_text(parse_ctx_t *ctx, const char *pos, bool allow_interps) { // ('"' ... '"' / "'" ... "'" / "`" ... "`") - // "$" [name] [interp-char] quote-char ... close-quote + // "$" [name] quote-char ... close-quote const char *start = pos; const char *lang = NULL; @@ -136,7 +138,7 @@ ast_t *parse_text(parse_ctx_t *ctx, const char *pos) { if (!(*pos == '"' || *pos == '\'' || *pos == '`')) return NULL; - ast_list_t *chunks = _parse_text_helper(ctx, &pos); + ast_list_t *chunks = _parse_text_helper(ctx, &pos, allow_interps); bool colorize = match(&pos, "~") && match_word(&pos, "colorized"); return NewAST(ctx->file, start, pos, TextJoin, .lang = lang, .children = chunks, .colorize = colorize); } @@ -157,7 +159,7 @@ ast_t *parse_inline_c(parse_ctx_t *ctx, const char *pos) { parser_err(ctx, pos, pos + 1, "This is not a valid string quotation character. Valid characters are: \"'`|/;([{<"); - ast_list_t *chunks = _parse_text_helper(ctx, &pos); + ast_list_t *chunks = _parse_text_helper(ctx, &pos, true); return NewAST(ctx->file, start, pos, InlineCCode, .chunks = chunks, .type_ast = type); } diff --git a/src/parse/text.h b/src/parse/text.h index 6ab3cab2..865bc5a4 100644 --- a/src/parse/text.h +++ b/src/parse/text.h @@ -1,9 +1,11 @@ // Logic for parsing text literals #pragma once +#include + #include "../ast.h" #include "context.h" -ast_t *parse_text(parse_ctx_t *ctx, const char *pos); +ast_t *parse_text(parse_ctx_t *ctx, const char *pos, bool allow_interps); ast_t *parse_inline_c(parse_ctx_t *ctx, const char *pos); ast_t *parse_path(parse_ctx_t *ctx, const char *pos); -- cgit v1.2.3