flan/test/programs/pkg-macro.flan
Joseph Ferano 69646e534e A macro's parameter list, and one grammar for it
(defmacro do-grid [[r rows c cols] & body] ...) — positional names, a [ ]
pattern wherever an argument is a vector, and & for the tail. The reading of
the list lives in Expand, below both sides that need it: Parse turns it into
the bindings a macro body opens with, and Macro checks a call against the same
reading before expanding it, so arity and shape are refused with the call's own
location rather than with the Loc.from_macro stamp every node of an expansion
carries.

The breaking half: [args] used to bind the whole argument list and now binds
the first argument. The whole list is [& args], and every defmacro in the tree
— prelude, vendor, tests, the elisp fixtures — was migrated to it. One grammar,
not a legacy mode.
2026-09-20 18:18:24 +07:00

44 lines
1.8 KiB
Plaintext

;;;; A macro in an imported package.
;;;;
;;;; This used to be the refusal's test. The refusal said that collecting a
;;;; package's macros would need that package's imports resolved at the Form
;;;; level before [Load] ran -- a second import resolver. What it did not
;;;; notice is that the *file being compiled* is parsed before [Load] runs too,
;;;; so no shape of the feature could have left import resolution where it was.
;;;; [Load.program] takes forms now: it reads the import forms, resolves them
;;;; with the one resolver it always had, and parses the file with the
;;;; packages' macros in front of it.
;;;;
;;;; The rule is the one every other declaration follows. (mac/twice 4) is a
;;;; call and (twice 4) is an unknown name -- see the refusal beside this one
;;;; in test_acceptance.ml.
(import mac "pkgs/mac")
;; A macro of the program's own, coexisting with the package's.
(defmacro tenfold [& args]
`(* ~(at args 0) 10))
;; The same macro again, written with a parameter list instead of by hand.
;; Nothing calls it: it is here for the equivalence case in test_session, which
;; expands (tenfold 7) and (tenfold-listed 7) and requires the same text out of
;; both. [& args] and [n] are one grammar, and this is where that is asserted
;; rather than assumed.
(defmacro tenfold-listed [n]
`(* ~n 10))
(defn show [n i32] () (print n) (println ""))
(defn main [] i32
(show (mac/twice 4)) ; 8
(show (mac/quad 3)) ; 12
(show (mac/doubled 5)) ; 10
(show (mac/also-twice 6)) ; 12
(show (mac/shadowed 9)) ; 10
(show (mac/quadruple 2)) ; 8
(show (tenfold 7)) ; 70
;; The program's macro over the package's, and the package's over a prelude
;; one: all three sets are in the same module and the walk is bottom up.
(show (tenfold (mac/twice 3))) ; 60
0)