Skip to content

Commit

Permalink
Add rubyish example
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
dwarring authored and moritz committed Oct 14, 2013
1 parent 246aaae commit 3c7ac10
Show file tree
Hide file tree
Showing 18 changed files with 1,184 additions and 0 deletions.
80 changes: 80 additions & 0 deletions examples/rubyish/README.md
@@ -0,0 +1,80 @@
nqp-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 # repl mode
> puts 37 + 5
```
Features:
- simple strings 'Hello World!' %q{...}
- interpolating strings: "number #{37+5}" %Q{Hello #{planet}!}
- quoted words: `%w[aa bb cc]`
- scoping, including $globals, @class_instance and @@package variables
- conditional blocks: if ... then ... elsif ... else ... endif
- begin .. end blocks
- nqp opcode calls
- a few built-ins: abort, print, puts, sleep
- infixish assigments: += -= *= ...
- very simple classes and objects with attributes. no inheritence yet
- while and until loops
- statement modifiers `if` `unless`, `while`, `until` e.g.: `puts 42 if `
- 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)

Notes:

Handy Options:

% nqp rubyish.nqp --target=parse -e'puts "Hello World!"' # dump parse
% nqp rubyish.nqp --target=ast -e'puts "Hello World!"' # dump ast

To run tests:
```
% prove -v -e'nqp rubyish.nqp' t
```

Expressions are Perlish rather than Rubyish:

- `+` always does addition (doesn't concatenate strings)
- `~` has been introduced as the concatenation operator
- `>`, `==`, `<=` ... only do arithmetic comparisons
- `gt`, `eq`, `le` ... do string comparisions
- 0, '0', '' are false in a boolean context.
- hash dereferencing is via angle braces: `price = fruit<apples>` or
curly brackets `puts fruit{'bannanas'}`

- nqp op-codes can be called like regular functions. E.g.
```
puts nqp::if(2+2 == 4, 'yup', 'nope' )
```
- this includes nqp control-flow functions:
```
n = 99
nqp::while n > 0, begin
puts "#{n} green bottles standing on the wall"
puts "#{n} green bottles standing on the wall"
puts "and if one green bottle should accidently fall..."
nqp::sleep 1
n -= 1
puts "there'd be #{n} green bottles standing on the wall"
nqp::sleep 2
end
```
There's some context sensitive parsing to distinguish functions and
expressions, E.g.
```
yy = 37
puts yy -5 # parsed as an expression; output is 32
def xx(n) ; 37 - n; end
puts xx -5 # parsed as a method call; output is 42
```

31 changes: 31 additions & 0 deletions examples/rubyish/rubyish-examples/green-bottles.rbi
@@ -0,0 +1,31 @@
# eRubyish templating - see http://en.wikipedia.org/wiki/ERuby
# There are only three directives:
# <%rbi> - Header; remainder of the source file is the template body
# <% ... %> - rubyish statements
# #{ ... } - inserted content

# 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>'

<%rbi>
<html>
<body>
<h1>Green Bottles...</h1>
<%n = 12 %>
<%while n > 0 %>
<blockquote>
<em>#{n}</em> green bottles standing on the wall,
<em>#{n}</em> green bottles standing on the wall
<br/>
<%# -- gratuitous use of puts ------------------------------ %>
<%puts %q{and if one green bottle should accidently fall...} %>
<br/>
<%n -= 1 %>
there'd be <em> #{if n then n else 'no' end} </em> green bottles standing on the wall
</blockquote>
<%end%>
</body>
</html>

23 changes: 23 additions & 0 deletions examples/rubyish/rubyish-examples/pi.rbi
@@ -0,0 +1,23 @@
# naive approximation: pi = 4 * (1 - /1/3 + 1/5 ...)

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

n = 1;
pi_over_4 = 0.0

print 'hang on a few moments...'
start_time = time()

while n < limit do

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

end

puts "(completed #{limit} iterations in #{time() - start_time} sec )"

pi = pi_over_4 * 4
puts pi

0 comments on commit 3c7ac10

Please sign in to comment.