Everyone, It’s been a couple of decades coming, but Avail now supports macros. In fact, anything bigger than a token in Avail is now defined solely in terms of macros. Declarations, variable uses, assignments, supercasts, functions, and statements are all just macros. The “core” syntax has been reduced to under a dozen pragma definitions in the Avail/Foundation/Origin module (generated from Preamble_en.properties), indicating both the macro names and the primitives that implement them. There’s nothing forcing these macros (and prefix functions, used to process declaration and scope) to be primitives, other than the fact that they occur before any other methods and macros are defined. It would be impossible to write the equivalent non-primitive macros without having a syntax!
There were some tweaks to the method name metacharacters along the way; here’s
an excerpt from MessageSplitter#messageParts’s comment:
• Alphanumerics are in runs, separated from other alphanumerics by a
single space.
• Operator characters are never beside spaces, and are always parsed as
individual tokens.
• Open guillemet («), double dagger (‡), and close guillemet (») are
used to indicate repeated or optional substructures.
• The characters octothorp (#) and question mark (?) modify the output
of repeated substructures to produce either a count of the repetitions or a
boolean indicating whether an optional subexpression (expecting no arguments)
was present.
• Placing a question mark (?) after a group containing arguments but no
double-dagger (‡) will limit the repetitions of the group to at most one.
Although limiting the method definitions to only accept 0..1 occurrences would
accomplish the same grammatical narrowing, the parser might still attempt to
parse more than one occurrence, leading to unnecessarily confusing diagnostics.
• An exclamation mark (!) can follow a group of alternations to produce
the 1-based index of the alternative that actually occurred.
• An underscore (_) indicates where an argument occurs.
• A single dagger (†) may occur immediately after an underscore to
cause the argument expression to be evaluated in the static scope during
compilation. This is applicable to both methods and macros.
• An up-arrow (↑) after an underscore indicates an in-scope variable
name is to be parsed. The subexpression causes the variable itself to be
provided, rather than its value.
• An exclamation mark (!) may occur after the underscore instead, to
indicate the argument expression may be ⊤-valued or ⊥-valued. Since a function
(and therefore a method definition) cannot accept a ⊤-valued argument, this
mechanism only makes sense for macros, since macros bodies are passed phrases,
which may be typed as yielding a top-valued result.
• An ellipsis (…) matches a single keyword token.
• An exclamation mark (!) after an ellipsis indicates any token will be
accepted at that position.
• An octothorp (#) after an ellipsis indicates only a literal token
will be accepted.
• The Nth section sign (§) in a message name indicates where a macro's
Nth prefix function should be invoked with the current parse stack up to that
point.
• A backquote (`) can precede any operator character, such as
guillemets or double dagger, to ensure it is not used in a special way. A
backquote may also operate on another backquote (to indicate that an actual
backquote token will appear in a call).
The comment does not yet reflect a change we made tonight, wherein the “_†”
notation (use option-t on Mac) is now restricted to expressions that yield a
type.
A formal announcement will be made on the web site in the next few days, as
this was the key remaining piece to revolutionize DSL creation – the ability to
disinherit the core Avail syntax.
Any feedback about parsing issues, inadequate diagnostic information, etc.
would be greatly appreciated. Even though the whole library parses correctly,
we still need to ensure we are providing sufficient stability, parallelism,
performance, diagnostic feedback, and comprehensibility.
ENJOY!
signature.asc
Description: Message signed with OpenPGP using GPGMail
