root/t/macros/macro_code_test.t

Revision 21763, 4.6 kB (checked in by lwall, 5 months ago)

s/q:code/quasi/ plus various t/ buglets

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
1use v6;
2use Test;
3
4
5plan 3;
6# Avoiding accidental multiple execution
7# as occurs in C's defines and lisp macros
8# This can also ensure a correct order of evaluation
9
10# This needs to be decided
11# is CST (Concrete)
12# is Thunk
13# is Proxy
14# is Reduced
15# is Bound
16# is Once
17# is Evaluated
18# is EvaluatedOnce
19# is Eager
20macro max ($x is CST, $y is CST) {
21    return quasi { ($x > $y) ?? $x !! $y };
22}
23
24# Alternatively, the default could be eval once and the special name
25# is for the CallByName version
26
27my ($x, $y) = (1,2);
28
29my $got = max($x++, $y++);
30
31# say qc'$x = {$x} $y = {$y}';
32
33is($x,   2, '$x incremented once', :todo<unspecced>);
34is($y,   3, '$x incremented once', :todo<unspecced>);
35is($got, 3, '$got incremented max', :todo<unspecced>);
36
37=begin pod
38
39=head1 quasi & AST splicing options
40
41=head2 Splicing Problem
42
43The contents of quasi blocks need to be able to refer to values
44as any other closure does, but also define graft points for
45other asts.
46
47=head2 Solution Space
48
49First principle, adding quasi before a block doesn't change things
50  - it's still a closure
51  - if you mention $var it means the $var in the surrounding lexical scope
52    (mentioning new vars may bind at the macro use)
53  - subs continue to be bound to the local definitions
54  - macros continue to be expanded at parse time (quasi parse time)
55
56Second principle, to do something special, say something special.
57
58Differences: possible variable/sub not defined errors may bind at macro uses
59or are delayed.
60
61macro parameters may be ASTs, strings, or possibly a singly-evaluated-ASTs,
62the point is to wrap or warp them into the returned AST|string.
63We want an easy way to splice the input AST into the output AST
64The output AST is usually a quasi block somehow using the macro arg asts:
65
66  quasi { my $x; $x; $input_ast; $captured_var; $var_at_call }
67
68=head2 Some Suggested Solutions
69
70 * Roles, anything that does QuasiQuote is spliced including ASTs,
71   ThunkishASTS and certain strings
72   literal($ast) macro to talk about an ast as a value
73 
74 * signature such as quasi ($ast) { $var; $ast }
75   (idea--: duplicates macro's param list, violates sig -> application w/ args
76    expectation with subs)
77 
78 * twigil used for interpolating AST/strings
79
80 * escape meta-syntax (lisp's solution) 
81    quasi { say "Exp (\qq[~$package]) = ", \qq[$package] }
82 
83 * set of escape macros which only apply in quasi blocks glue($ast)
84
85More complex restructuring of the input AST would require walking
86the AST (or munging the string).  Nothing spec'd for that yet.
87We would likw to ensure only valid ASTs can be produced.
88
89Perl's rules may be able to scan the tree with L<S05/"Matching against non-strings">
90and just s:g/// to produce the output ast. 
91
92If a tree grammar tool reaches the Perl 6 user space then that can be used
93
94=head2 Current Solution
95
96quasi { } is the quoter and {{{ }}} is the default antiquote
97(the rule is actually the delimiter repeated thrice).
98The use of {{{ ... }}} in a quasi is just like an inline macro.
99Pretending that the body of you program is within a quasi{ }
100then {{{ }}} can be used for inline macros, compile time
101generation of ASTs which are spliced immediately.
102
103=head1 Recursive Macros
104
105We started thinking about these, but then realized we'd need to
106know how they work, so we started thinking about these, ...
107
108These are banned in C but permitted in Lisp (and a source of
109infinite loops during compilation).  We could adopt either method
110or try to reduce the likely pain.  Lisp allows a recursive expander
111function, but not a recursive expansion.
112
113It seems impossible to parse beyond a recursive macro call,
114so we can ask Turing's oracle or give up.
115
116One remaining possibility to add the macro expansion to a todo list that
117is run after the macro definition is completed.  The effects of the
118macro may then be different from the non-recursive case.
119It is different to a mere sub call however, as it happens immediately
120after the definition.
121
122Finally, a recursive call could merely be a subroutine call, allowing
123recursion at runtime (which is compile time as far as the macro's caller
124is concerned).  This is perhaps close to C++ template expansion games.
125
126Recursive macros seem to be an unneeded feature, ast's equivalent
127to those from a recursive macro can be contructed using normal runtime tools,
128including subroutine recursion.
129
130=head2 Run Defined Macros Only
131
132Macros are only macros once
133
134
135=head1 Quoting Declarations
136
137Can declarations and pragmas be quoted?
138$Larry "I don't see why not"
139
140 quasi { sub x { ... }; macro y { ... }; use force; }
141
142The AST needs to be rescanned anyway, so perform the appropriate
143actions at that time in the correct scope.
144
145=end pod
146# vim: syntax=perl6:
Note: See TracBrowser for help on using the browser.