boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs

commit 09299304297f9244d866289eafc912422be489e7
parent dca693c3073799b8d46cc9f6479839ea4c8d913d
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 23 Apr 2026 17:05:40 -0700

m1pp: allow paren-less invocation of 0-arg macros

Diffstat:
Mm1pp/m1pp.c | 28+++++++++++++++++-----------
Atests/m1pp/13-parenless-control.M1pp | 30++++++++++++++++++++++++++++++
Atests/m1pp/13-parenless-control.expected | 27+++++++++++++++++++++++++++
Atests/m1pp/13-parenless.M1pp | 32++++++++++++++++++++++++++++++++
Atests/m1pp/13-parenless.expected | 29+++++++++++++++++++++++++++++
5 files changed, 135 insertions(+), 11 deletions(-)

diff --git a/m1pp/m1pp.c b/m1pp/m1pp.c @@ -675,16 +675,20 @@ static int expand_macro_tokens(struct Token *call_tok, struct Token *limit, struct Token *end_pos; int mark; - if (call_tok + 1 >= limit || (call_tok + 1)->kind != TOK_LPAREN) { + if (call_tok + 1 < limit && (call_tok + 1)->kind == TOK_LPAREN) { + if (!parse_args(call_tok + 1, limit)) { + return 0; + } + if (arg_count != m->param_count) { + return fail("wrong arg count"); + } + end_pos = call_end_pos; + } else if (m->param_count == 0) { + arg_count = 0; + end_pos = call_tok + 1; + } else { return fail("bad macro call"); } - if (!parse_args(call_tok + 1, limit)) { - return 0; - } - if (arg_count != m->param_count) { - return fail("wrong arg count"); - } - end_pos = call_end_pos; mark = pool_used; for (body_tok = m->body_start; body_tok < m->body_end; body_tok++) { @@ -949,7 +953,9 @@ static int eval_expr_atom(struct Token *tok, struct Token *limit, int mark; macro = find_macro(tok); - if (macro != NULL && tok + 1 < limit && (tok + 1)->kind == TOK_LPAREN) { + if (macro != NULL && + ((tok + 1 < limit && (tok + 1)->kind == TOK_LPAREN) || + macro->param_count == 0)) { if (!expand_macro_tokens(tok, limit, macro, &after, &mark)) { return 0; } @@ -1229,8 +1235,8 @@ static int process_tokens(void) macro = find_macro(tok); if (macro != NULL && - tok + 1 < s->end && - (tok + 1)->kind == TOK_LPAREN) { + ((tok + 1 < s->end && (tok + 1)->kind == TOK_LPAREN) || + macro->param_count == 0)) { if (!expand_call(s, macro)) { return 0; } diff --git a/tests/m1pp/13-parenless-control.M1pp b/tests/m1pp/13-parenless-control.M1pp @@ -0,0 +1,30 @@ +# Control fixture for 13-parenless: same macros and test points, but every +# 0-arg call uses the explicit () form. The output from the two test points +# where 13-parenless uses paren-less calls must be byte-identical here, +# proving paren-less is semantically equivalent to paren-ful for 0-arg macros. + +%macro FRAME_BASE() +16 +%endm + +%macro add1(x) +%((+ x 1)) +%endm + +# Top-level: both forms yield `16`. +%FRAME_BASE() +%FRAME_BASE() + +# Expression atom: both yield 4-byte LE hex for 24 (16 + 8). +%((+ %FRAME_BASE() 8)) +%((+ %FRAME_BASE() 8)) + +# Undefined %foo passes through unchanged. +%foo + +# Param-ful macro without parens does NOT match โ€” literal text flows through. +%add1 + +# Param-ful macro with proper call still works (sanity). +%add1(41) +END diff --git a/tests/m1pp/13-parenless-control.expected b/tests/m1pp/13-parenless-control.expected @@ -0,0 +1,27 @@ + + + + + + + + +16 + +16 + + + +'18000000' +'18000000' + + +%foo + + +%add1 + + +'2A000000' + +END diff --git a/tests/m1pp/13-parenless.M1pp b/tests/m1pp/13-parenless.M1pp @@ -0,0 +1,32 @@ +# Paren-less 0-arg macro calls (M1PP-EXT ยง4): +# - a zero-param macro invoked without trailing () expands the same as with () +# - applies at top level and as an atom inside %(...) expressions +# - non-zero-param macros still require their (arg, ...) syntax โ€” %add1 +# without parens must pass through unchanged +# - a %foo where foo is not a macro still passes through unchanged + +%macro FRAME_BASE() +16 +%endm + +%macro add1(x) +%((+ x 1)) +%endm + +# Top-level: both forms yield `16`. +%FRAME_BASE +%FRAME_BASE() + +# Expression atom: both yield 4-byte LE hex for 24 (16 + 8). +%((+ %FRAME_BASE 8)) +%((+ %FRAME_BASE() 8)) + +# Undefined %foo passes through unchanged. +%foo + +# Param-ful macro without parens does NOT match โ€” literal text flows through. +%add1 + +# Param-ful macro with proper call still works (sanity). +%add1(41) +END diff --git a/tests/m1pp/13-parenless.expected b/tests/m1pp/13-parenless.expected @@ -0,0 +1,29 @@ + + + + + + + + + + +16 + +16 + + + +'18000000' +'18000000' + + +%foo + + +%add1 + + +'2A000000' + +END