diff --git a/lib/ast/basic_expressions.rb b/lib/ast/basic_expressions.rb index f7a8de0..05be240 100644 --- a/lib/ast/basic_expressions.rb +++ b/lib/ast/basic_expressions.rb @@ -18,6 +18,22 @@ module Ast end end + class TrueExpression < Expression + def to_s + "true" + end + end + class FalseExpression < Expression + def to_s + "false" + end + end + class NilExpression < Expression + def to_s + "nil" + end + end + class NameExpression < Expression attr_reader :name def initialize name diff --git a/lib/ast/expression.rb b/lib/ast/expression.rb index 4c33dcd..0ee862e 100644 --- a/lib/ast/expression.rb +++ b/lib/ast/expression.rb @@ -10,7 +10,10 @@ module Ast class Expression def attributes - raise "abstract #{self}" + [] + end + def inspect + self.class.name + ".new()" end def == other return false unless other.class == self.class diff --git a/lib/parser/basic_types.rb b/lib/parser/basic_types.rb index 1b83dfb..9821869 100644 --- a/lib/parser/basic_types.rb +++ b/lib/parser/basic_types.rb @@ -43,6 +43,7 @@ module Parser rule(:float) { integer >> dot >> integer >> (exponent >> sign.maybe >> digit.repeat(1,3)).maybe >> space?} - rule(:basic_type){ integer | name | string | float | instance_variable | module_name } + rule(:basic_type){ integer | name | string | float | instance_variable | module_name | + keyword_true | keyword_false | keyword_nil } end end \ No newline at end of file diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index 8c16f0c..3f13758 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -6,7 +6,10 @@ module Parser rule(:string => sequence(:chars)) { Ast::StringExpression.new chars.join } rule(:esc => simple(:esc)) { '\\' + esc } rule(char: simple(:char)) { char } - + + rule(:true => simple(:true)) { Ast::TrueExpression.new() } + rule(:false => simple(:false)) { Ast::FalseExpression.new() } + rule(:nil => simple(:nil)) { Ast::NilExpression.new() } rule(:integer => simple(:value)) { Ast::IntegerExpression.new(value.to_i) } rule(:name => simple(:name)) { Ast::NameExpression.new(name.to_s) } rule(:instance_variable => simple(:instance_variable)) { Ast::VariableExpression.new(instance_variable.name) } diff --git a/test/roots/test_compound.rb b/test/roots/test_compound.rb index 767fd89..5f78c6f 100644 --- a/test/roots/test_compound.rb +++ b/test/roots/test_compound.rb @@ -28,6 +28,12 @@ class RootTestCompound < MiniTest::Test @transform_output = Ast::ExpressionList.new( [Ast::HashExpression.new([Ast::AssociationExpression.new(Ast::NameExpression.new(:foo) , Ast::IntegerExpression.new(33))])]) end + def test_hash2 + @string_input = '{ foo => true }' + @parse_output = {:expression_list=>[{:hash_constant=>[{:hash_pair=>{:hash_key=>{:name=>"foo"}, :hash_value=>{:true=>"true"}}}]}]} + @transform_output = Ast::ExpressionList.new( [Ast::HashExpression.new([Ast::AssociationExpression.new(Ast::NameExpression.new(:foo) , Ast::TrueExpression.new())])]) + end + def test_hash_list @string_input = "{foo => 33 , bar => 42}" @parse_output = {:expression_list=>[{:hash_constant=>[{:hash_pair=>{:hash_key=>{:name=>"foo"}, :hash_value=>{:integer=>"33"}}}, {:hash_pair=>{:hash_key=>{:name=>"bar"}, :hash_value=>{:integer=>"42"}}}]}]} diff --git a/test/roots/test_operators.rb b/test/roots/test_operators.rb index d081add..f2b2aa6 100644 --- a/test/roots/test_operators.rb +++ b/test/roots/test_operators.rb @@ -47,6 +47,11 @@ class RootTestExpressions < MiniTest::Test @parse_output = {:expression_list=>[{:l=>{:name=>"a"}, :o=>"- ", :r=>{:string=>[{:char=>"s"}, {:char=>"t"}]}}]} @transform_output = Ast::ExpressionList.new( [Ast::OperatorExpression.new("-", Ast::NameExpression.new(:a),Ast::StringExpression.new("st"))]) end + def test_op_variable_true + @string_input = 'a == true' + @parse_output = {:expression_list=>[{:l=>{:name=>"a"}, :o=>"== ", :r=>{:true=>"true"}}]} + @transform_output = Ast::ExpressionList.new( [Ast::OperatorExpression.new("==", Ast::NameExpression.new(:a),Ast::TrueExpression.new())]) + end def test_two_same_ops @string_input = '2 + 3 + 4' @parse_output = {:expression_list=>[{:l=>{:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"3"}}, :o=>"+ ", :r=>{:integer=>"4"}}]} diff --git a/test/unit/test_basic.rb b/test/unit/test_basic.rb index ba0ebea..e780a1f 100644 --- a/test/unit/test_basic.rb +++ b/test/unit/test_basic.rb @@ -3,7 +3,26 @@ require_relative "../parser_helper" class TestBasic < MiniTest::Test # include the magic (setup and parse -> test method translation), see there include ParserHelper - + + def test_true + @string_input = 'true ' + @parse_output = {:true => 'true'} + @transform_output = Ast::TrueExpression.new() + @parser = @parser.basic_type + end + def test_false + @string_input = 'false ' + @parse_output = {:false => 'false'} + @transform_output = Ast::FalseExpression.new() + @parser = @parser.basic_type + end + def test_nil + @string_input = 'nil ' + @parse_output = {:nil => 'nil'} + @transform_output = Ast::NilExpression.new() + @parser = @parser.basic_type + end + def test_number @string_input = '42 ' @parse_output = {:integer => '42'} diff --git a/test/unit/test_compound.rb b/test/unit/test_compound.rb index 4c00e77..099c981 100644 --- a/test/unit/test_compound.rb +++ b/test/unit/test_compound.rb @@ -18,6 +18,13 @@ class TestCompound < MiniTest::Test @parser = @parser.array_constant end + def test_array_list2 + @string_input = '[42, nil]' + @parse_output = {:array_constant=>[{:array_element=>{:integer=>"42"}}, {:array_element=>{:nil=>"nil"}}]} + @transform_output = Ast::ArrayExpression.new([Ast::IntegerExpression.new(42), Ast::NilExpression.new()]) + @parser = @parser.array_constant + end + def test_array_ops @string_input = '[ 3 + 4 , foo(22) ]' @parse_output = {:array_constant=>[{:array_element=>{:l=>{:integer=>"3"}, :o=>"+ ", :r=>{:integer=>"4"}}}, {:array_element=>{:call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"22"}}]}}]} diff --git a/test/unit/test_conditional.rb b/test/unit/test_conditional.rb index c5798fc..99602e1 100644 --- a/test/unit/test_conditional.rb +++ b/test/unit/test_conditional.rb @@ -38,4 +38,18 @@ HERE @transform_output = Ast::IfExpression.new(Ast::OperatorExpression.new(">", Ast::IntegerExpression.new(3),Ast::NameExpression.new("var")), [Ast::CallSiteExpression.new(:initialize, [Ast::IntegerExpression.new(3)] ,Ast::ModuleName.new("Object"))],[Ast::CallSiteExpression.new(:new, [Ast::IntegerExpression.new(33)] ,Ast::NameExpression.new("var"))] ) @parser = @parser.conditional end + + def test_conditional_nil + @string_input = <"if", :conditional=>{:l=>{:integer=>"3"}, :o=>"== ", :r=>{:nil=>"nil"}}, :if_true=>{:expressions=>[{:integer=>"3"}], :else=>"else"}, :if_false=>{:expressions=>[{:integer=>"4"}], :end=>"end"}} + @transform_output = Ast::IfExpression.new(Ast::OperatorExpression.new("==", Ast::IntegerExpression.new(3),Ast::NilExpression.new()), [Ast::IntegerExpression.new(3)],[Ast::IntegerExpression.new(4)] ) + @parser = @parser.conditional + end end \ No newline at end of file diff --git a/test/unit/test_return.rb b/test/unit/test_return.rb index cbf8568..010351c 100644 --- a/test/unit/test_return.rb +++ b/test/unit/test_return.rb @@ -25,4 +25,11 @@ class TestReturn < MiniTest::Test @parser = @parser.simple_return end + def test_return_true + @string_input = 'return true' + @parse_output = {:return=>"return", :return_expression=>{:true=>"true"}} + @transform_output = Ast::ReturnExpression.new(Ast::TrueExpression.new() ) + @parser = @parser.simple_return + end + end \ No newline at end of file