From 47f160868587129fb752a13f9df335854950c115 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sat, 10 May 2014 19:02:51 +0300 Subject: [PATCH] start to add while loop --- lib/ast/conditional_expression.rb | 5 ++++- lib/ast/expression.rb | 3 ++- lib/ast/while_expression.rb | 16 ++++++++++++++++ lib/parser/conditional.rb | 5 +++++ lib/parser/keywords.rb | 3 +++ lib/parser/transform.rb | 5 +++++ test/parser/test_conditional.rb | 20 +++++++++++++++++++- test/parser/test_function_definition.rb | 23 ++++++++++++++++++++++- test/runners/fibo_while.rb | 13 +++++++++++++ 9 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 lib/ast/while_expression.rb create mode 100644 test/runners/fibo_while.rb diff --git a/lib/ast/conditional_expression.rb b/lib/ast/conditional_expression.rb index ce609cf9..9891ab7e 100644 --- a/lib/ast/conditional_expression.rb +++ b/lib/ast/conditional_expression.rb @@ -4,7 +4,10 @@ module Ast def initialize cond, if_true, if_false @cond, @if_true, @if_false = cond, if_true, if_false end - + def inspect + self.class.name + ".new(" + cond.inspect + ", "+ + if_true.inspect + "," + if_false.inspect + " )" + end def attributes [:cond, :if_true, :if_false] end diff --git a/lib/ast/expression.rb b/lib/ast/expression.rb index 88ad6c7d..282b5d58 100644 --- a/lib/ast/expression.rb +++ b/lib/ast/expression.rb @@ -37,5 +37,6 @@ end require_relative "basic_expressions" require_relative "conditional_expression" +require_relative "while_expression" require_relative "function_expression" -require_relative "operator_expressions" \ No newline at end of file +require_relative "operator_expressions" diff --git a/lib/ast/while_expression.rb b/lib/ast/while_expression.rb new file mode 100644 index 00000000..c78953f1 --- /dev/null +++ b/lib/ast/while_expression.rb @@ -0,0 +1,16 @@ +module Ast + class WhileExpression < Expression + attr_reader :condition, :body + def initialize condition, body + @condition , @body = condition , body + end + def inspect + self.class.name + ".new(" + condition.inspect + ", " + body.inspect + " )" + end + def attributes + [:condition, :body] + end + end + + +end \ No newline at end of file diff --git a/lib/parser/conditional.rb b/lib/parser/conditional.rb index 55220a9b..0a73184d 100644 --- a/lib/parser/conditional.rb +++ b/lib/parser/conditional.rb @@ -6,5 +6,10 @@ module Parser delimited_expressions(keyword_else).as(:if_true) >> delimited_expressions(keyword_end).as(:if_false) } + + rule(:while) { + keyword_while >> expression.as(:while_cond) >> keyword_do >> newline >> + delimited_expressions(keyword_end).as(:body) + } end end diff --git a/lib/parser/keywords.rb b/lib/parser/keywords.rb index 10ea6ff6..8cccf8d2 100644 --- a/lib/parser/keywords.rb +++ b/lib/parser/keywords.rb @@ -8,5 +8,8 @@ module Parser rule(:keyword_true) { str('true').as(:true) >> space?} rule(:keyword_false){ str('false').as(:false) >> space?} rule(:keyword_nil) { str('null').as(:nil) >> space?} + rule(:keyword_while) { str('while').as(:while) >> space?} + rule(:keyword_do) { str('do').as(:do) >> space?} + rule(:keyword_begin) { str('begin').as(:begin) >> space?} end end \ No newline at end of file diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index 144d530a..df198cb8 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -24,6 +24,11 @@ module Parser Ast::ConditionalExpression.new(conditional, if_true, if_false) end + rule(:while => simple(:while), :while_cond => simple(:while_cond) , :do => simple(:do), + :body => {:expressions => sequence(:body)}) do + Ast::WhileExpression.new(while_cond, body) + end + rule(:parmeter => simple(:parmeter)) { parmeter } rule(:parmeter_list => sequence(:parmeter_list)) { parmeter_list } diff --git a/test/parser/test_conditional.rb b/test/parser/test_conditional.rb index 1a502d7f..aced6e20 100644 --- a/test/parser/test_conditional.rb +++ b/test/parser/test_conditional.rb @@ -20,5 +20,23 @@ HERE @parser = @parser.conditional end - + + def test_while + @string_input = <"while", :while_cond=>{:integer=>"1"}, :do=>"do", :body=>{:expressions=>[{:asignee=>{:name=>"tmp"}, :asigned=>{:name=>"a"}}, {:asignee=>{:name=>"a"}, :asigned=>{:name=>"b"}}]}} + @transform_output = Ast::WhileExpression.new( + Ast::IntegerExpression.new(1), + [Ast::AssignmentExpression.new("tmp", Ast::NameExpression.new("a")), Ast::AssignmentExpression.new("a", Ast::NameExpression.new("b"))] ) + @parser = @parser.while + end end \ No newline at end of file diff --git a/test/parser/test_function_definition.rb b/test/parser/test_function_definition.rb index 393d8b07..77d876bc 100644 --- a/test/parser/test_function_definition.rb +++ b/test/parser/test_function_definition.rb @@ -34,5 +34,26 @@ HERE @parser = @parser.function_definition end - + def test_function_while + @string_input = < 1 do + tmp = a + a = b + b = tmp + b + puts b + n = n - 1 + end +end +HERE + @parse_output = { :function_definition => { :name => "foo" } , + :parmeter_list => [{ :parmeter => { :name => "x" } }], + :expressions => [ { :asignee => { :name => "abba" }, :asigned => { :integer => "5" } } ] + } + @transform_output = Ast::FunctionExpression.new( "foo", [Ast::NameExpression.new("x")], + [Ast::AssignmentExpression.new( "abba", Ast::IntegerExpression.new(5) ) ]) + @parser = @parser.function_definition + end end \ No newline at end of file diff --git a/test/runners/fibo_while.rb b/test/runners/fibo_while.rb new file mode 100644 index 00000000..fc491e88 --- /dev/null +++ b/test/runners/fibo_while.rb @@ -0,0 +1,13 @@ +def fibonaccit(n) + a = 0 + b = 1 + while n > 1 do + tmp = a + a = b + b = tmp + b + puts b + n = n - 1 + end +end + +fibonaccit( 10 )