Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
rubyish - style, use of '(' ~ ')' constructs, etc
  • Loading branch information
dwarring committed Oct 16, 2013
1 parent dc9d7ff commit 45b52fd
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 57 deletions.
10 changes: 5 additions & 5 deletions examples/rubyish/README.md
@@ -1,13 +1,13 @@
nqp-rubyish
===========
nqp/examples/rubyish
====================

Ruby subset extended from the `rubyish-4` example, as introduced in the Edument
[Rakudo and NQP internals course](https://github.com/edumentab/rakudo-and-nqp-internals-course).

Example usage:
```
% nqp rubyish.nqp -e'puts "Hello World!"'
% nqp rubyish.nqp rubyish-examples/green-bottles.rbi
% nqp rubyish.nqp rubyish-examples/template.rbi
% nqp rubyish.nqp # repl mode
> puts 37 + 5
```
Expand All @@ -27,7 +27,7 @@ Features:
- basic arrays and hashes
- for loops on arrays: `for val in [10,20,30] do puts val end`
- for loops on hash keys: `h = {'a'=>10, 'b'=>20}; for k in h do puts h{k} end`
- lightweight eRuby like templating, see [green-bottles.rbi](rubyish-examples/green-bottles.rbi)
- lightweight eRuby like templating, see [template.rbi](rubyish-examples/template.rbi)

Notes:

Expand All @@ -53,7 +53,7 @@ curly brackets `puts fruit{'bannanas'}`

- nqp op-codes can be called like regular functions. E.g.
```
puts nqp::if(2+2 == 4, 'yup', 'nope' )
puts nqp:if(2+2 == 4, 'yup', 'nope' )
```
- this includes nqp control-flow functions:
```
Expand Down
7 changes: 5 additions & 2 deletions examples/rubyish/rubyish-examples/fractal-tree.rbi
@@ -1,6 +1,9 @@
<?rbi?>
<%# Fractal tree example #%>
<%# % nqp rubyish.nqp rubyish-examples/fractal-tree.rbi > fractal.svg #%>
<%#
# Fractal tree rubyish example. Usage:
# % nqp rubyish.nqp rubyish-examples/fractal-tree.rbi > fractal.svg
#
%>
<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
Expand Down
8 changes: 4 additions & 4 deletions examples/rubyish/rubyish-examples/pi.rbi
@@ -1,7 +1,7 @@
# naive approximation: pi = 4 * (1 - /1/3 + 1/5 ...)

limit = 2500000
def time ; nqp::time_i() ; end
def time ; nqp:time_i() ; end

n = 1;
pi_over_4 = 0.0
Expand All @@ -11,9 +11,9 @@ start_time = time()

while n < limit do

m = 4.0*n - 1.0
pi_over_4 += 1/(m - 2) - 1/m
n += 1
m = 4.0*n - 1.0
pi_over_4 += 1/(m - 2) - 1/m
n += 1

end

Expand Down
Expand Up @@ -7,7 +7,7 @@
# Any arbritrary code can appear before the template. Output to stdout
# is appended to the template, both before and within the template body

puts '<?xml version='1.0' encoding='utf-8'?>'
puts "<?xml version='1.0' encoding='utf-8'?>"

<?rbi?>
<html>
Expand Down
72 changes: 36 additions & 36 deletions examples/rubyish/rubyish.nqp
Expand Up @@ -24,6 +24,7 @@ class RubyishClassHOW {
}

grammar Rubyish::Grammar is HLL::Grammar {

token TOP {
:my $*CUR_BLOCK := QAST::Block.new(QAST::Stmts.new());
:my $*TOP_BLOCK := $*CUR_BLOCK;
Expand All @@ -35,23 +36,23 @@ grammar Rubyish::Grammar is HLL::Grammar {
|| <.panic('Syntax error')>
}

token continuation { \\ \n }
rule separator { ';' | \n <!after continuation> }
token template { [<tmpl-unesc>|<tmpl-hdr>] <text=.template-content>* [<tmpl-esc>|$] }
proto token template-content {*}
token template-content:sym<interp> { <interp> }
token template-content:sym<plain-text> { [<!before [<tmpl-esc>|'#{'|$]> .]+ }
token continuation { \\ \n }
rule separator { ';' | \n <!after continuation> }
token template-chunk { [<tmpl-unesc>|<tmpl-hdr>] ~ [<tmpl-esc>|$] <template-nibble>* }
proto token template-nibble {*}
token template-nibble:sym<interp> { <interp> }
token template-nibble:sym<plain-text> { [<!before [<tmpl-esc>|'#{'|$]> .]+ }

token tmpl-hdr {'<?rbi?>' \h* \n? <?{$*IN_TEMPLATE := 1}>}
token tmpl-esc {\h* '<%'
[<?{$*IN_TEMPLATE}> || <.panic('Template directive precedes "<?rbi?>"')>]
[<?{$*IN_TEMPLATE}> || <.panic('Template directive precedes "<?rbi?>"')>]
}
token tmpl-unesc { '%>' \h* \n?
[<?{$*IN_TEMPLATE}> || <.panic('Template directive precedes "<?rbi?>"')>]
[<?{$*IN_TEMPLATE}> || <.panic('Template directive precedes "<?rbi?>"')>]
}

rule stmtlist {
[ <stmt=.stmtish>? ] *%% [<.separator>|<stmt=.template>]
[ <stmt=.stmtish>? ] *%% [<.separator>|<stmt=.template-chunk>]
}

token stmtish {
Expand Down Expand Up @@ -180,7 +181,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
}

proto token comment {*}
token comment:sym<line> { '#' [<?{!$*IN_TEMPLATE}> \N* || [<!before '%>'>\N]*] }
token comment:sym<line> { '#' [<?{!$*IN_TEMPLATE}> \N* || [<!before <tmpl-unesc>>\N]*] }
token comment:sym<podish> {[^^'=begin'\n] ~ [^^'=end'\n ] .*?}
token ws { <!ww>[\h | <.comment> | <.continuation> | <?{$*LINE_SPAN}> \n]* }

Expand Down Expand Up @@ -264,23 +265,23 @@ grammar Rubyish::Grammar is HLL::Grammar {
}

token stmt:sym<if> {
if :s <xblock> [<else=.elsif>|<else>]? end
if ~ 'end' [ :s <xblock> [<else=.elsif>|<else>]? ]
}

token elsif {
'elsif' <xblock> [<else=.elsif>|<else>]?
'elsif' ~ [<else=.elsif>|<else>]? <xblock>
}

token else {
'else' <stmtlist>
}

token stmt:sym<do> {
<modifier> :s <EXPR> :s <do> <stmtlist> 'end'
<modifier> :s <EXPR> :s <do> ~ 'end' <stmtlist>
}

token stmt:sym<for> {
<sym> :s <ident> :s 'in' <EXPR> <do> <stmtlist> 'end'
<sym> :s <ident> :s 'in' <EXPR> <do> ~ 'end' <stmtlist>
}

token do { <separator> [:s 'do']? | 'do' | <?before <tmpl-unesc>>}
Expand Down Expand Up @@ -315,6 +316,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
}

class Rubyish::Actions is HLL::Actions {

method TOP($/) {
$*CUR_BLOCK.push($<stmtlist>.ast);
make $*CUR_BLOCK;
Expand All @@ -331,26 +333,27 @@ class Rubyish::Actions is HLL::Actions {
make $stmts;
}

method template($/) {
method template-chunk($/) {
my $text := QAST::Stmts.new( :node($/) );
$text.push( QAST::Op.new( :op<print>, $_.ast ) )
for $<text>;
for $<template-nibble>;

make $text;
}

method template-content:sym<interp>($/) {
method template-nibble:sym<interp>($/) {
make $<interp>.ast
}

method template-content:sym<plain-text>($/) {
method template-nibble:sym<plain-text>($/) {
make QAST::SVal.new( :value(~$/) );
}

method stmtish($/) {
return make $<stmt>.ast unless ~$<modifier>;

make QAST::Op.new( $<EXPR>.ast, $<stmt>.ast, :op(~$<modifier>), :node($/) );
make $<modifier>
?? QAST::Op.new( $<EXPR>.ast, $<stmt>.ast,
:op(~$<modifier>), :node($/) )
!! $<stmt>.ast;
}

method term:sym<value>($/) { make $<value>.ast; }
Expand All @@ -359,10 +362,10 @@ class Rubyish::Actions is HLL::Actions {
my %builtins;

method term:sym<call>($/) {
my $name := ~$<operation>;
%builtins := Rubyish::Grammar.builtin-init()
my $name := ~$<operation>;
%builtins := Rubyish::Grammar.builtin-init()
unless %builtins<puts>;
my $op := %builtins{$name};
my $op := %builtins{$name};

my $call := $op
?? QAST::Op.new( :op($op) )
Expand All @@ -389,13 +392,13 @@ class Rubyish::Actions is HLL::Actions {
}

method call-args($/) {
my $args := [];
$args.push($_.ast) for $<EXPR>;
make $args;
my @args;
@args.push($_.ast) for $<EXPR>;
make @args;
}

method paren-args($/) {
make $<call-args>.ast;
make $<call-args>.ast;
}

my $tmpsym := 0;
Expand Down Expand Up @@ -578,12 +581,9 @@ class Rubyish::Actions is HLL::Actions {
}

method strings($/) {
if $<strings> {
make QAST::Op.new( :op('concat'), $<string>.ast, $<strings>.ast)
}
else {
make $<string>.ast;
}
make $<strings>
?? QAST::Op.new( :op('concat'), $<string>.ast, $<strings>.ast)
!! $<string>.ast;
}

method string($/) {
Expand All @@ -608,7 +608,7 @@ class Rubyish::Actions is HLL::Actions {

method value:sym<array>($/) {
my $array := QAST::Op.new( :op<list> );
$array.push($_) for $<paren-list>.ast;
$array.push($_) for $<paren-list>.ast;
make $array;
}

Expand All @@ -618,7 +618,7 @@ class Rubyish::Actions is HLL::Actions {

method value:sym<hash>($/) {
my $hash := QAST::Op.new( :op<hash> );
$hash.push($_) for $<paren-list>.ast;
$hash.push($_) for $<paren-list>.ast;
make $hash;
}
method value:sym<nil>($/) {
Expand Down
6 changes: 4 additions & 2 deletions examples/rubyish/t/arrays.t
Expand Up @@ -6,9 +6,11 @@ puts "#{a[1] == 20? 'ok' : 'nok'} 2 - a[1]"
puts "#{a['2'] == 30? 'ok' : 'nok'} 3 - a['2']"
puts "#{a[1+2] == 40? 'ok' : 'nok'} 4 - a[1+2]"

n=0
for val in a do
puts "ok #{ val / 10 + 4 } - array iteration (#{val})"
idx = val / 10 + 4
n += 1
puts "ok #{idx} - array iteration #{n}"
end

puts "#{%w{nok ok nok}[1]} 9 - quote words"

2 changes: 1 addition & 1 deletion examples/rubyish/t/hashs.t 100644 → 100755
Expand Up @@ -9,4 +9,4 @@ puts "#{h{'d'} == 40? 'ok' : 'nok'} 4 - h{'d'}"

for key in h do
puts "ok #{ h{key} / 10 + 4 } - hash key iteration (#{key})"
end
end
7 changes: 5 additions & 2 deletions examples/rubyish/t/line-spanning.t
@@ -1,4 +1,4 @@
puts "1..4"
puts "1..5"

a=[10,
20]
Expand All @@ -22,7 +22,7 @@ puts "#{h<c>? 'ok' : 'nok'} 3 - hash spanning lines"

def tricky(k,
n)
puts "#{k} - #{n} - multi-line signatures and calls"
puts "#{k} #{n} - multi-line signatures and calls"
end

tricky(
Expand All @@ -31,3 +31,6 @@ tricky(
4

)

puts \
"ok 5 - \\ line continuation"
8 changes: 4 additions & 4 deletions examples/rubyish/t/template.t
Expand Up @@ -10,11 +10,11 @@ ok 2 - initial template text
<%end%>
ok 5 - text between statements
<%if n == 5 %>ok 6 - if block (true)
<%else %>nok 6 - if block (true)
<%else %>nok 6 - else block (true)
<%end%>
<%if n == 1234 %>nok 7 - if block (false)
<%elsif n == 20 %>nok 7 - if block (false)
<%else %>ok 7 - if block (false)
<%if n == 1234 %>nok 7 - if block (false)
<%elsif n == 20 %>nok 7 - elsif block (false)
<%else %>ok 7 - else block (false)
<% end %>
<%for test in [8, 9] do %>ok #{test} - for loop test
<%end%>
Expand Down

0 comments on commit 45b52fd

Please sign in to comment.