diff --git a/languages/lolcode/config/makefiles/root.in b/languages/lolcode/config/makefiles/root.in index da8848d..2b5e48a 100644 --- a/languages/lolcode/config/makefiles/root.in +++ b/languages/lolcode/config/makefiles/root.in @@ -40,6 +40,7 @@ SOURCES = lolcode.pir \ BUILTINS_PIR = \ src/builtins/say.pir \ src/builtins/math.pir \ + src/builtins/expr.pir \ src/builtins/var_or_function.pir # PMCS = lolcode diff --git a/languages/lolcode/src/parser/actions.pm b/languages/lolcode/src/parser/actions.pm index 031e4d8..505ce3f 100644 --- a/languages/lolcode/src/parser/actions.pm +++ b/languages/lolcode/src/parser/actions.pm @@ -14,6 +14,7 @@ line containing C<{*}> also has a C<#= key> comment, then the value of the comment is passed as the second argument to the method. =end comments +=cut class lolcode::Grammar::Actions; @@ -127,14 +128,16 @@ method value($/, $key) { make $( $/{$key} ); } -method expression($/, $key) { - if ($key eq 'var_or_function') { - my $past := PAST::Op.new( :name('var_or_function'), :pasttype('call'), :node( $/ ) ); - $past.push( $( $ ) ); - make $past; - } else { - make $( $/{$key} ); +method expression($/) { + my $past := PAST::Op.new( :name('expr_parse'), :pasttype('call'), :node( $/ ) ); + for $ { + $past.push( $( $_ ) ); } + make $past; +} + +method expr_word($/, $key) { + make $( $/{ $key } ); } method integer($/) { @@ -154,7 +157,7 @@ method boolean($/) { } method quote($/) { - make PAST::Val.new( :value( $($) ), :node($/) ); + make PAST::Val.new( :value( $($) ), :returns('String'), :node($/) ); } method math($/) { @@ -180,6 +183,14 @@ method variable ($/) { } } +method operator ($/) { + make PAST::Var.new( :name( ~$ ), + :scope('lexical'), + :viviself('Undef'), + :node( $/ ) + ); +} + # Local Variables: # mode: cperl diff --git a/languages/lolcode/src/parser/grammar.pg b/languages/lolcode/src/parser/grammar.pg index f277bb2..4f85b85 100644 --- a/languages/lolcode/src/parser/grammar.pg +++ b/languages/lolcode/src/parser/grammar.pg @@ -9,9 +9,9 @@ This is the grammar for lolcode written as a sequence of Perl 6 rules. grammar lolcode::Grammar is PCT::Grammar; rule TOP { - 'HAI' + 'HAI' <.statement_terminator> - 'KTHXBYE' + 'KTHXBYE' <.statement_terminator> [ $ || ] {*} } @@ -44,23 +44,23 @@ rule assign { } rule function { - 'HOW' 'DUZ' 'I' + 'HOW' 'DUZ' 'I' <.statement_terminator> 'IF' 'U' 'SAY' 'SO' {*} } rule ifthen { - - 'O' 'RLY?' - 'YA' 'RLY' + <.statement_terminator> + 'O' 'RLY?' <.statement_terminator> + 'YA' 'RLY' <.statement_terminator> [ - 'MEBBE' + 'MEBBE' <.statement_terminator> ]* [ - 'NO' 'WAI' + 'NO' 'WAI' <.statement_terminator> $= ]? 'OIC' @@ -68,21 +68,21 @@ rule ifthen { } rule switch { - - 'WTF?' + <.statement_terminator> + 'WTF?' <.statement_terminator> [ - 'OMG' + 'OMG' <.statement_terminator> ]+ [ - 'OMGWTF' + 'OMGWTF' <.statement_terminator> ]? 'OIC' } rule block { - [ ]* {*} + [ <.statement_terminator>]* {*} } rule parameters { @@ -90,12 +90,20 @@ rule parameters { } rule expression { - | {*} #= var_or_function + $=[ | + | 'AN' + | 'MKAY' + ]+ {*} +} + +rule expr_word { + | {*} #= operator + | {*} #= variable | {*} #= value } rule value { - | {*} #= math + #| {*} #= math | {*} #= float | {*} #= integer | {*} #= boolean @@ -104,16 +112,18 @@ rule value { rule variable { {*} } +rule operator { 'OF' {*} } + token identifier { $=( <[a..zA..Z]> \w* ) {*} } # Because PGE doesn't yet know how to do longest token matching, # order all tokens in reverse alpha order to avoid a parsing bug. token keyword { - [ 'YR' | 'YA' | 'WTF?' | 'WIN' | 'WAI' | 'VISIBLE' | 'U' | 'SUM' | 'SO' - | 'SMALLR' | 'SAY' | 'RLY?' | 'RLY' | 'R' | 'QUOSHUNT' | 'PRODUKT' - | 'OMGWTF' | 'OMG' | 'OIC' | 'O' | 'NO' | 'MOD' | 'MEBBE' | 'KTHXBYE' + [ 'YR' | 'YA' | 'WTF?' | 'WIN' | 'WAI' | 'VISIBLE' | 'U' | 'SO' + | 'SAY' | 'RLY?' | 'RLY' | 'R' + | 'OMGWTF' | 'OMG' | 'OIC' | 'O' | 'NO' | 'MEBBE' | 'KTHXBYE' | 'ITZ' | 'IF' | 'I' | 'HOW' | 'HAS' | 'GTFO' | 'FOUND' | 'FAIL' | 'DIFF' - | 'BIGGR' | 'AN' | 'A' ] >> + | 'AN' | 'A' ] >> } rule integer { '-'? \d+ {*} }