perl11 / cperl

A perl5 with classes, types, compilable, company friendly, security
http://perl11.org/
Other
142 stars 17 forks source link

Add S06 macros #261

Open rurban opened 7 years ago

rurban commented 7 years ago

Use the existing perl6 S06 synopsis and testcases. "In the absence of a signature to the contrary, a macro is called as if it were a method on the current match object returned from the grammar rule being reduced; that is, all the current parse information is available by treating $self as if it were a $/ object. Macros may return either a string to be reparsed, or a syntax tree that needs no further parsing."

Change the syntax a little bit to harmonize with perl5:

{{{ }}} => `` for unquote splicing.

Expand the ast inside the backticks at compile-time as a subprocess would be expanded with its result. Use qx() for subprocesses instead.

macro infix:<name> () => macro 'name' :infix ()

I.e. Allow optional single-quoted names for non-identifiers, such as '!!' :postfix. Use perl5 attributes as perl6 operator overloaders to tell macros if they have non-standard position: infix, prefix, postfix, circumfix, postcircumfix.

Don't support the quasi attributes :ast/:lang/:unquote, other than :COMPILING. Support the COMPILING:: pseudo-package for namespace clarification, but not the import syntax COMPILING<$x>. The fullname is good and magic enough.

See the feature/gh261-macros branch.

vendethiel commented 7 years ago

There are a lot of questions stemming from this document. How do you do hygiene? I seem to remember you're a CL enthusiast(?) so you might not bother, but CL needs to execute code to know even how to parse what's coming next. I'm interested in your take on this.

Stuff like macro f() { quasi { my $c = 1; } }; f(); say $c; (or really, adding anything to the scope) is something @masak and everyone else working on 007 have talked a lot about, often in the #6macros freenode channel.

rurban commented 7 years ago

Hygiene is hard with this non-hygienic syntax. For proper hygiene you would need pattern matching as in scheme. But the existing tests should pass. I'll push the branch soon.

vendethiel commented 7 years ago

Okay, so I'm even more interested to see how you'd generate identifiers. Waiting for the branch push. Thanks.

rurban commented 7 years ago

Just the tests yet, to get the syntax right. Lexicals are hygienic as they are referred to by index, not by name. So they don't need gensym.

vendethiel commented 7 years ago

Okay, so you don't plan to make possible to break hygiene, or do you intend to make COMPILING work for this purpose? (it seems the test file is still somewhat rough, since #todo rakudo are still present)

rurban commented 7 years ago

COMPILING sounds easiest. But I'll wait for the perl6 decisions. I just want to implement the already working parts, sans the generally unliked {{{ syntax. Hygiene is relative with such lexicals as looking up the variable by name will not really work. Similar to the inliner, which needs to create copies with the same name. GCC adds hidden .1 suffices to such copies. Basically macro is very similar to inlining. I'll use the inlining functions in the compiler.

rurban commented 7 years ago

re compile-time `` syntax vs '{{{ }}}': I prefer this syntax and proposed it to Larry some years ago.

vendethiel commented 7 years ago

That's down to bikeshedding, but we sometimes ago talked about ` being somewhat a sigil, so quasi { `{$ast} } would be used. It's backwards with lisp's quote, and I don't think perl 5/6 needs multi-level unquotes (as opposed to Lisp's infamous `(fn1 `(fn2 ,',var)))

rurban commented 7 years ago

yes, it's pure bikeshedding. multi-level quote/unquote is still possible though. question is who wants to write such unreadable code. we will see. (Note to myself: eventually track parser/compiler recursion depth, max 500) object systems need hygienic macros desperately.