Changeset 21763
- Timestamp:
- 08/04/08 10:39:26 (4 months ago)
- Files:
-
- 9 modified
-
src/Pugs/Eval.hs (modified) (1 diff)
-
src/Pugs/Parser.hs (modified) (1 diff)
-
src/perl6/Cursor.pmc (modified) (1 diff)
-
src/perl6/STD.pm (modified) (9 diffs)
-
t/examples/99problems/problem91.t (modified) (3 diffs)
-
t/examples/all_parse.t (modified) (1 diff)
-
t/macros/caller.t (modified) (1 diff)
-
t/macros/macro_code_test.t (modified) (8 diffs)
-
t/macros/opaque_ast_macros.t (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Eval.hs
r21673 r21763 899 899 evalExp $ Syn "=" [Val lhs, App (_Var op) Nothing [Val val, rhsExp]] 900 900 901 reduceSyn "q :code" [ body ] = expToEvalVal body901 reduceSyn "quasi" [ body ] = expToEvalVal body 902 902 903 903 reduceSyn "CCallDyn" (Val (VStr quant):methExp:invExp:args) = do -
src/Pugs/Parser.hs
r21673 r21763 984 984 _ -> fail "no caller env to install pragma in" 985 985 986 {-| Match a @q :code{ ... }@ quotation -}986 {-| Match a @quasi { ... }@ quotation -} 987 987 ruleCodeQuotation :: RuleParser Exp 988 988 ruleCodeQuotation = rule "code quotation" $ do 989 989 -- XXX - This is entirely kluge; it drops traits in the body too 990 symbol "q :code" >> optional (symbol "(:COMPILING)")990 symbol "quasi" >> optional (symbol ":COMPILING") 991 991 block <- ruleBlockBody 992 return (Syn "q :code" [bi_body block])992 return (Syn "quasi" [bi_body block]) 993 993 994 994 -- | If we've executed code like @BEGIN { exit }@, we've to run all @\@*END@ -
src/perl6/Cursor.pmc
r21743 r21763 202 202 return { PATS => ['(?#::)'] }; # (but if we advanced just assume a :: here) 203 203 } 204 $key = 'termish' if $key eq 'EXPR'; 204 205 return $self->lexers->{$key} = $self->_AUTOLEXgen($key, $retree); 205 206 } -
src/perl6/STD.pm
r21749 r21763 1757 1757 } 1758 1758 1759 token quasiquibble ($l) { 1760 :my $lang = $l; 1761 :my $start; 1762 :my $stop; 1763 1764 <.ws> 1765 [ <quotepair> <.ws> 1766 { 1767 my $kv = $<quotepair>[*-1]; 1768 $lang = $lang.tweak($kv.<k>, $kv.<v>) 1769 or self.panic("Unrecognized adverb :" ~ $kv.<k> ~ '(' ~ $kv.<v> ~ ')'); 1770 } 1771 ]* 1772 1773 { 1774 ($start,$stop) = $¢.peek_delimiters(); 1775 $lang = $start ne $stop ?? $lang.balanced($start,$stop) 1776 !! $lang.unbalanced($stop); 1777 } 1778 1779 [ 1780 || <?{ $start eq '{' }> [ :lang($lang) <block> ] 1781 || $start [ :lang($lang) <statementlist> ] $stop 1782 ] 1783 } 1784 1759 1785 # note: polymorphic over many quote languages, we hope 1760 1786 token nibbler { … … 1863 1889 token quote:tr { 1864 1890 <sym> » <!before '('> <pat=tribble( $¢.cursor_fresh( ::STD::Q ).tweak(:q))> 1891 } 1892 1893 token quote:quasi { 1894 <sym> » <!before '('> <pat=quasiquibble($¢.cursor_fresh( ::STD::Quasi ))> 1865 1895 } 1866 1896 … … 2224 2254 } 2225 2255 2226 multi method tweak (:$code) {2227 return ::RegexCode;2228 }2229 2230 2256 multi method tweak (*%x) { 2231 2257 my @k = keys(%x); … … 2235 2261 2236 2262 2263 } # end grammar 2264 2265 grammar Quasi is STD { 2266 token term:unquote { 2267 <starter><starter><starter> :: <statementlist> <stopper><stopper><stopper> 2268 } 2237 2269 } # end grammar 2238 2270 … … 2381 2413 [ 2382 2414 # Is it a longname declaration? 2383 || <?{ $<sigil> eq '&' }> <?ident> ::2415 || <?{ $<sigil>.text eq '&' }> <?ident> :: 2384 2416 <ident=sublongname> 2385 2417 2386 2418 || # Is it a shaped array or hash declaration? 2387 <?{ $<sigil> eq '@' || $<sigil>eq '%' }>2419 <?{ $<sigil>.text eq '@' || $<sigil>.text eq '%' }> 2388 2420 <ident>? 2389 2421 <.ws> … … 2905 2937 { <sym> } 2906 2938 2907 token term:sym<...> ( --> List_prefix)2939 token prefix:sym<...> ( --> List_prefix) 2908 2940 { 2909 2941 '...' 2910 2942 } 2911 2943 2912 token term:sym<???> ( --> List_prefix)2944 token prefix:sym<???> ( --> List_prefix) 2913 2945 { 2914 2946 '???' 2915 2947 } 2916 2948 2917 token term:sym<!!!> ( --> List_prefix)2949 token prefix:sym<!!!> ( --> List_prefix) 2918 2950 { 2919 2951 '!!!' … … 2929 2961 # { <typename> <?spacey> <arglist> { $<sym> = $<typename>.item; } } 2930 2962 2931 # unrecognized identifiers are assumed to be post-declared listops.2963 # force ident(), ident.(), etc. to be a function call always 2932 2964 token term:ident ( --> Term ) 2933 2965 { 2934 2966 <ident> 2935 2967 [ 2936 | '.(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2937 | '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2938 | <.unsp> '.'? '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2939 ] 2940 } 2941 2968 | '.(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2969 | '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2970 | <.unsp> '.'? '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2971 ] 2972 2973 [ 2974 || ':' <?before \s> <arglist> # either switch to listopiness 2975 || {{ $+prevop = $<O> = {}; }} # or allow adverbs 2976 ] 2977 } 2978 2979 # names containing :: may or may not be function calls 2980 # bare ident without parens also handled here if no other rule parses it 2942 2981 token term:name ( --> Term) 2943 2982 { … … 2945 2984 [ 2946 2985 || <?{ 2947 $¢.is_type($<longname>.text) 2986 $¢.is_type($<longname>.text) or substr($<longname>.text,0,2) eq '::' 2948 2987 }> :: 2949 2988 # parametric type? … … 2955 2994 ]? 2956 2995 {*} #= typename 2996 2997 # unrecognized names are assumed to be post-declared listops. 2998 || <?before \s> <arglist> 2999 {*} #= listop args 2957 3000 || 2958 3001 [ 2959 | '.(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2960 | '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2961 | <?before \s> <?{ substr($<longname>.text,0,2) ne '::' }> <arglist> {*} #= listop args 2962 | <.unsp> '.'? '(' <in: ')', 'semilist', 'argument list'> {*} #= func args 2963 | :: {*} #= listop noarg 3002 | '.(' <in: ')', 'semilist', 'argument list'> 3003 {*} #= func args 3004 3005 | '(' <in: ')', 'semilist', 'argument list'> 3006 {*} #= func args 3007 3008 | <.unsp> '.'? '(' <in: ')', 'semilist', 'argument list'> 3009 {*} #= func args 3010 3011 3012 | :: {*} #= listop noarg 3013 ] 3014 3015 [ 3016 || ':' <?before \s> <arglist> # either switch to listopiness 3017 || {{ $+prevop = $<O> = {}; }} # or allow adverbs 2964 3018 ] 2965 3019 ] -
t/examples/99problems/problem91.t
r20490 r21763 36 36 } 37 37 38 method toStr() {38 method Str() { 39 39 $.x ~ "/" ~ $.y; 40 40 } 41 41 } 42 43 # Stringify a case44 multi sub *prefix:<~> (Case $c) { $c.toStr }45 42 46 43 # All the moves a Knight can do … … 110 107 } 111 108 my Bool @chessboard[$n][$n]; 112 for ( 0..$n-1 )-> $i {109 for 0..$n-1 -> $i { 113 110 @chessboard[$i] = [True xx $n]; 114 111 } … … 120 117 my $n = 8; 121 118 my @result = searchFrom( Case.new(:x(0),:y(0)), $n ); 122 # @result.map:{. toStr}.join(", ").say;119 # @result.map:{.Str}.join(", ").say; 123 120 ok check_tour($n, @result), "This knight's tour is valid."; -
t/examples/all_parse.t
r21719 r21763 49 49 # $! instead of this yucky workaround 50 50 for sort(@files) -> $ex { 51 my $out = `$*EXECUTABLE_NAME -c -Iblib6/lib $ex`;51 my $out = qqx[$*EXECUTABLE_NAME -c -Iblib6/lib $ex]; 52 52 53 53 if $out ~~ m:P5/syntax OK\s*$/ { -
t/macros/caller.t
r21719 r21763 19 19 20 20 macro ast_compiling_current_line () { 21 return q :code(:COMPILING){ current_line() };21 return quasi :COMPILING { current_line() }; 22 22 } 23 23 24 24 macro ast_current_line () { 25 return q :code{ current_line() };25 return quasi { current_line() }; 26 26 } 27 27 -
t/macros/macro_code_test.t
r21719 r21763 19 19 # is Eager 20 20 macro max ($x is CST, $y is CST) { 21 return q :code{ ($x > $y) ?? $x !! $y };21 return quasi { ($x > $y) ?? $x !! $y }; 22 22 } 23 23 … … 37 37 =begin pod 38 38 39 =head1 q :code& AST splicing options39 =head1 quasi & AST splicing options 40 40 41 41 =head2 Splicing Problem 42 42 43 The contents of q :codeblocks need to be able to refer to values43 The contents of quasi blocks need to be able to refer to values 44 44 as any other closure does, but also define graft points for 45 45 other asts. … … 47 47 =head2 Solution Space 48 48 49 First principle, adding q :codebefore a block doesn't change things49 First principle, adding quasi before a block doesn't change things 50 50 - it's still a closure 51 51 - if you mention $var it means the $var in the surrounding lexical scope 52 52 (mentioning new vars may bind at the macro use) 53 53 - subs continue to be bound to the local definitions 54 - macros continue to be expanded at parse time (q :codeparse time)54 - macros continue to be expanded at parse time (quasi parse time) 55 55 56 56 Second principle, to do something special, say something special. … … 62 62 the point is to wrap or warp them into the returned AST|string. 63 63 We want an easy way to splice the input AST into the output AST 64 The output AST is usually a q :codeblock somehow using the macro arg asts:64 The output AST is usually a quasi block somehow using the macro arg asts: 65 65 66 q :code{ my $x; $x; $input_ast; $captured_var; $var_at_call }66 quasi { my $x; $x; $input_ast; $captured_var; $var_at_call } 67 67 68 68 =head2 Some Suggested Solutions … … 72 72 literal($ast) macro to talk about an ast as a value 73 73 74 * signature such as q :code($ast) { $var; $ast }74 * signature such as quasi ($ast) { $var; $ast } 75 75 (idea--: duplicates macro's param list, violates sig -> application w/ args 76 76 expectation with subs) … … 79 79 80 80 * escape meta-syntax (lisp's solution) 81 q :code{ say "Exp (\qq[~$package]) = ", \qq[$package] }81 quasi { say "Exp (\qq[~$package]) = ", \qq[$package] } 82 82 83 * set of escape macros which only apply in q :codeblocks glue($ast)83 * set of escape macros which only apply in quasi blocks glue($ast) 84 84 85 85 More complex restructuring of the input AST would require walking … … 94 94 =head2 Current Solution 95 95 96 q :code{ } is the quoter and {{{ }}} is the default antiquote96 quasi { } is the quoter and {{{ }}} is the default antiquote 97 97 (the rule is actually the delimiter repeated thrice). 98 The use of {{{ ... }}} in a q :codeis just like an inline macro.99 Pretending that the body of you program is within a q :code{ }98 The use of {{{ ... }}} in a quasi is just like an inline macro. 99 Pretending that the body of you program is within a quasi{ } 100 100 then {{{ }}} can be used for inline macros, compile time 101 101 generation of ASTs which are spliced immediately. … … 138 138 $Larry "I don't see why not" 139 139 140 q :code{ sub x { ... }; macro y { ... }; use force; }140 quasi { sub x { ... }; macro y { ... }; use force; } 141 141 142 142 The AST needs to be rescanned anyway, so perform the appropriate -
t/macros/opaque_ast_macros.t
r21719 r21763 6 6 =head1 DESCRIPTION 7 7 8 Tests for macros which return q :codebut do not do splicing8 Tests for macros which return quasi but do not do splicing 9 9 10 10 See L<S06/"Macros">. … … 15 15 16 16 # L<S06/Macros> 17 macro four () { q :code{ 2+2 } }17 macro four () { quasi { 2+2 } } 18 18 19 is(four, 4, "macro returning q :code");19 is(four, 4, "macro returning quasi"); 20 20 21 macro hi () { q :code(:COMPILING){ "hello $s" } }21 macro hi () { quasi :COMPILING { "hello $s" } } 22 22 23 23 macro hey () { ({ "hello $^s" }.body) } … … 31 31 32 32 my $x; 33 macro noop () { $x = "Nothing happened"; q :code{ } }33 macro noop () { $x = "Nothing happened"; quasi { } } 34 34 noop(); 35 35 #macro noop2 () { $x ~= ", twice"; return } # unspecced
