lib/kaiser_ruby/rockstar_transform.rb in kaiser-ruby-0.3.0 vs lib/kaiser_ruby/rockstar_transform.rb in kaiser-ruby-0.4.0
- old
+ new
@@ -1,24 +1,45 @@
require 'pry'
module KaiserRuby
class RockstarTransform < Parslet::Transform
- rule(variable_name: simple(:str)) { |c| parameterize(c[:str]) }
+ @@last_variable = nil
+ @@indent = 0
+ class << self
+ def last_variable=(value)
+ @@last_variable = value
+ end
+
+ def up_indent
+ @@indent += 2
+ end
+
+ def down_indent
+ @@indent -= 2
+ end
+ end
+
+ rule(variable_name: simple(:str)) do |context|
+ self.last_variable = parameterize(context[:str])
+ parameterize(context[:str])
+ end
+ rule(pronoun: simple(:_)) { @@last_variable }
+
rule(mysterious_value: simple(:_)) { 'nil' }
rule(null_value: simple(:_)) { '0' }
rule(true_value: simple(:_)) { 'true' }
rule(false_value: simple(:_)) { 'false' }
rule(string_value: simple(:str)) { str }
rule(numeric_value: simple(:num)) { num }
rule(unquoted_string: simple(:str)) { "\"#{str}\"" }
- rule(string_as_number: simple(:str)) do |c|
- if c[:str].to_s.include?('.')
- c[:str].to_s.gsub(/[^A-Za-z\s\.]/, '').split('.').map do |sub|
+ rule(string_as_number: simple(:str)) do |context|
+ if context[:str].to_s.include?('.')
+ context[:str].to_s.gsub(/[^A-Za-z\s\.]/, '').split('.').map do |sub|
str_to_num(sub)
end.join('.').to_f
else
- str_to_num(c[:str])
+ str_to_num(context[:str])
end
end
rule(assignment: { left: simple(:left), right: simple(:right) }) { "#{left} = #{right}" }
rule(increment: simple(:str)) { "#{str} += 1" }
@@ -29,10 +50,11 @@
rule(division: { left: simple(:left), right: simple(:right) }) { "#{left} / #{right}" }
rule(print: { output: simple(:output) }) { "puts #{output}" }
rule(continue: simple(:_)) { "next" }
rule(break: simple(:_)) { "break" }
+ rule(input_variable: simple(:var)) { "print '> '\n#{var} = STDIN.gets.chomp" }
rule(equals: { left: simple(:left), right: simple(:right) }) { "#{left} == #{right}" }
rule(not_equals: { left: simple(:left), right: simple(:right) }) { "#{left} != #{right}" }
rule(gt: { left: simple(:left), right: simple(:right) }) { "#{left} > #{right}" }
rule(gte: { left: simple(:left), right: simple(:right) }) { "#{left} >= #{right}" }
@@ -41,129 +63,129 @@
rule(if: {
if_condition: simple(:if_condition),
if_block: sequence(:if_block_lines),
endif: simple(:_)
- } ) do
- output = "#{' ' * KaiserRuby.indent}if #{if_condition}\n"
- KaiserRuby.up_indent
- output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endif"
+ } ) do |context|
+ output = "#{' ' * @@indent}if #{context[:if_condition]}\n"
+ self.up_indent
+ output += context[:if_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endif"
output
end
rule(if: {
if_condition: simple(:if_condition),
and_or: simple(:and_or),
second_condition: simple(:second_condition),
if_block: sequence(:if_block_lines),
endif: simple(:_)
- } ) do
- proper_and_or = and_or == 'and' ? '&&' : '||'
- output = "#{' ' * KaiserRuby.indent}if #{if_condition} #{proper_and_or} #{second_condition}\n"
- KaiserRuby.up_indent
- output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endif"
+ } ) do |context|
+ proper_and_or = context[:and_or] == 'and' ? '&&' : '||'
+ output = "#{' ' * @@indent}if #{context[:if_condition]} #{proper_and_or} #{context[:second_condition]}\n"
+ self.up_indent
+ output += context[:if_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endif"
output
end
rule(if_else: {
if_condition: simple(:if_condition),
if_block: sequence(:if_block_lines),
else_block: sequence(:else_block_lines),
endif: simple(:_)
- } ) do
- output = "#{' ' * KaiserRuby.indent}if #{if_condition}\n"
- KaiserRuby.up_indent
- output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}else\n"
- KaiserRuby.up_indent
- output += else_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endifelse"
+ } ) do |context|
+ output = "#{' ' * @@indent}if #{context[:if_condition]}\n"
+ self.up_indent
+ output += context[:if_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}else\n"
+ self.up_indent
+ output += context[:else_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endifelse"
output
end
rule(if_else: {
if_condition: simple(:if_condition),
and_or: simple(:and_or),
second_condition: simple(:second_condition),
if_block: sequence(:if_block_lines),
else_block: sequence(:else_block_lines),
endif: simple(:_)
- } ) do
- proper_and_or = and_or == 'and' ? '&&' : '||'
- output = "#{' ' * KaiserRuby.indent}if #{if_condition} #{proper_and_or} #{second_condition}\n"
- KaiserRuby.up_indent
- output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}else\n"
- KaiserRuby.up_indent
- output += else_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endifelse"
+ } ) do |context|
+ proper_and_or = context[:and_or] == 'and' ? '&&' : '||'
+ output = "#{' ' * @@indent}if #{context[:if_condition]} #{proper_and_or} #{context[:second_condition]}\n"
+ self.up_indent
+ output += context[:if_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}else\n"
+ self.up_indent
+ output += context[:else_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endifelse"
output
end
rule(while: {
while_condition: simple(:while_condition),
while_block: sequence(:while_block_lines),
endwhile: simple(:_)
- } ) do
- output = "#{' ' * KaiserRuby.indent}while #{while_condition}\n"
- KaiserRuby.up_indent
- output += while_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endwhile"
+ } ) do |context|
+ output = "#{' ' * @@indent}while #{context[:while_condition]}\n"
+ self.up_indent
+ output += context[:while_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endwhile"
output
end
rule(while: {
while_condition: simple(:while_condition),
and_or: simple(:and_or),
second_condition: simple(:second_condition),
while_block: sequence(:while_block_lines),
endwhile: simple(:_)
- } ) do
- proper_and_or = and_or == 'and' ? '&&' : '||'
- output = "#{' ' * KaiserRuby.indent}while #{while_condition} #{proper_and_or} #{second_condition}\n"
- KaiserRuby.up_indent
- output += while_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # endwhile"
+ } ) do |context|
+ proper_and_or = context[:and_or] == 'and' ? '&&' : '||'
+ output = "#{' ' * @@indent}while #{context[:while_condition]} #{proper_and_or} #{context[:second_condition]}\n"
+ self.up_indent
+ output += context[:while_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # endwhile"
output
end
rule(until: {
until_condition: simple(:until_condition),
until_block: sequence(:until_block_lines),
enduntil: simple(:_)
- } ) do
- output = "#{' ' * KaiserRuby.indent}until #{until_condition}\n"
- KaiserRuby.up_indent
- output += until_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # enduntil"
+ } ) do |context|
+ output = "#{' ' * @@indent}until #{context[:until_condition]}\n"
+ self.up_indent
+ output += context[:until_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # enduntil"
output
end
rule(until: {
until_condition: simple(:until_condition),
and_or: simple(:and_or),
second_condition: simple(:second_condition),
until_block: sequence(:until_block_lines),
enduntil: simple(:_)
- } ) do
- proper_and_or = and_or == 'and' ? '&&' : '||'
- output = "#{' ' * KaiserRuby.indent}until #{until_condition} #{proper_and_or} #{second_condition}\n"
- KaiserRuby.up_indent
- output += until_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # enduntil"
+ } ) do |context|
+ proper_and_or = context[:and_or] == 'and' ? '&&' : '||'
+ output = "#{' ' * @@indent}until #{context[:until_condition]} #{proper_and_or} #{context[:second_condition]}\n"
+ self.up_indent
+ output += context[:until_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # enduntil"
output
end
rule(argument_name: simple(:str)) { str }
rule(return_value: simple(:value)) { "return #{value}" }
@@ -171,16 +193,16 @@
rule(function_definition: {
function_name: simple(:function_name),
arguments: sequence(:arguments),
function_block: sequence(:function_block_lines),
enddef: simple(:_)
- } ) do
- output = "#{' ' * KaiserRuby.indent}def #{function_name}(#{arguments.join(', ')})\n"
- KaiserRuby.up_indent
- output += function_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
- KaiserRuby.down_indent
- output += "#{' ' * KaiserRuby.indent}end # enddef"
+ } ) do |context|
+ output = "#{' ' * @@indent}def #{context[:function_name]}(#{context[:arguments].join(', ')})\n"
+ self.up_indent
+ output += context[:function_block_lines].map { |l| "#{' ' * @@indent}#{l}\n" }.join
+ self.down_indent
+ output += "#{' ' * @@indent}end # enddef"
output
end
rule(function_call: {
function_name: simple(:function_name),
@@ -198,6 +220,6 @@
def self.str_to_num(string)
string.to_s.split(/\s+/).map { |e| e.length % 10 }.join.to_i
end
end
-end
\ No newline at end of file
+end