diff --git a/Gemfile b/Gemfile index 50d9a01..9c83ef4 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ gem "rake" gem "salama-reader" , :path => "." gem "citrus" , :github => "salama/citrus" , :branch => "gemspec-readme" +gem "ast" , :path => "../ast" # Add dependencies to develop your gem here. # Include everything needed to run rake, tests, features, etc. diff --git a/Gemfile.lock b/Gemfile.lock index fe0aa4a..00a40c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,6 +11,11 @@ PATH salama-reader (0.2.0) citrus (~> 3.0.3) +PATH + remote: ../ast + specs: + ast (2.1.0) + GEM remote: http://rubygems.org/ specs: @@ -31,9 +36,13 @@ PLATFORMS ruby DEPENDENCIES + ast! citrus! codeclimate-test-reporter minitest rake rubygems-tasks salama-reader! + +BUNDLED WITH + 1.10.5 diff --git a/lib/parser/bosl.citrus b/lib/parser/bosl.citrus index f0e2bf0..12564ea 100644 --- a/lib/parser/bosl.citrus +++ b/lib/parser/bosl.citrus @@ -20,11 +20,11 @@ grammar Bosl end rule name_expression - (name:([a-z_] [a-zA-Z0-9_]*) space*) { Ast::NameExpression.new(capture(:name).to_str)} + (name:([a-z_] [a-zA-Z0-9_]*) space*) { capture(:name).to_str} end - rule module_name_expression - (name:([A-Z] [a-zA-Z0-9_]*) space*) { Ast::ModuleName.new(capture(:name).to_str)} + rule aspect_name_expression + (name:([A-Z] [a-zA-Z0-9_]*) space*) { s(:aspect , capture(:name).to_str)} end rule digits @@ -32,17 +32,17 @@ grammar Bosl end rule integer_expression - (digits space*) { Ast::IntegerExpression.new(to_str.to_i) } + (digits space*) { s(:int , to_str.to_i) } end rule string_expression #"'" (/.*/ !"'") "'" - ('"' str:(!'"' .)* '"') {Ast::StringExpression.new(capture(:str).to_str) } + ('"' str:(!'"' .)* '"') {s(:string , capture(:str).to_str) } end rule basic_expression name_expression | integer_expression | - module_name_expression | string_expression + aspect_name_expression | string_expression end rule keyword_begin 'begin' space* end @@ -54,21 +54,20 @@ grammar Bosl rule keyword_if 'if' end rule keyword_rescue 'rescue' space* end rule keyword_return 'return' space* end - rule keyword_module 'module' space* end + rule keyword_aspect 'aspect' space* end rule keyword_unless 'unless' space* end - rule keyword_until 'until' space* end rule keyword_while 'while' space* end rule keyword_nil - ('nil' space* ){ Ast::NilExpression.new } + ('nil' space* ){ s(:nil) } end rule keyword_false - ('false' space*) { Ast::FalseExpression.new } + ('false' space*) { s(:false) } end rule keyword_true - ('true' space*) { Ast::TrueExpression.new } + ('true' space*) { s(:true) } end # this rule is just to make sure identifiers can't be keywords. Kind of duplication here, but we need the @@ -152,15 +151,14 @@ grammar Bosl rule call_site (field_expression argument_list space?) { - Ast::CallSiteExpression.new(capture(:field_expression).value , - capture(:argument_list).value ) + s(:call , capture(:field_expression).value , capture(:argument_list).value ) } end rule field_expression (basic_expression "." name_expression space?) { - Ast::FieldExpression.new(capture(:basic_expression).value , - capture(:name_expression).value.name ) + s(:field , capture(:basic_expression).value , + capture(:name_expression).value ) } end @@ -197,21 +195,20 @@ grammar Bosl rule typed_arg (type name_expression) { - Ast::TypedName.new(capture(:type).value , capture(:name_expression).value.name) + s(:type , capture(:type).value , capture(:name_expression).value) } end rule variable_definition (typed_arg ("=" space* value_expression)?) { - type = capture(:typed_arg).value value = capture(:value_expression) ? capture(:value_expression).value : nil - var = Ast::VariableDefinition.new(type.type , type.name , value) + s(:variable , capture(:typed_arg).value , value ) } end rule assignment (name_expression "=" space* value_expression){ - Ast::AssignmentExpression.new( capture(:name_expression).value.name , capture(:value_expression).value) + s(:assign , capture(:name_expression).value.to_sym , capture(:value_expression).value) } end @@ -219,7 +216,7 @@ grammar Bosl (keyword_if left_parenthesis value_expression right_parenthesis body keyword_end) { - Ast::IfExpression.new( capture(:value_expression).value , capture(:body).value , nil) + s(:if , s(:cond , capture(:value_expression).value ) , s(:then , capture(:body).value) ) } end diff --git a/lib/parser/salama.rb b/lib/parser/salama.rb index 41521bb..1b48639 100644 --- a/lib/parser/salama.rb +++ b/lib/parser/salama.rb @@ -1,10 +1,11 @@ - -require 'ast/expression' +require "ast" module Parser # obviously a work in progress !! + Citrus::Match.include AST::Sexp + Citrus.require "parser/bosl" end diff --git a/test/parser_helper.rb b/test/parser_helper.rb index c4aba26..aacd6c1 100644 --- a/test/parser_helper.rb +++ b/test/parser_helper.rb @@ -1,7 +1,9 @@ require_relative "setup" +require "ast" # Included in parser test will create tests methods module ParserHelper + include AST::Sexp def self.included(base) # base.send :include, InstanceMethods #provides helpers and setup diff --git a/test/unit/test_basic.rb b/test/unit/test_basic.rb index 184c131..274d932 100644 --- a/test/unit/test_basic.rb +++ b/test/unit/test_basic.rb @@ -6,62 +6,62 @@ class TestBasic < MiniTest::Test def test_true @input = 'true ' - @output = Ast::TrueExpression.new() + @output = s(:true) check :keyword_true end def test_false @input = 'false ' - @output = Ast::FalseExpression.new() + @output = s(:false) check :keyword_false end def test_nil @input = 'nil ' - @output = Ast::NilExpression.new() + @output = s(:nil) check :keyword_nil end def test_integer @input = '42 ' - @output = Ast::IntegerExpression.new(42) + @output = s(:int , 42) check :integer_expression end def test_name @input = 'foo ' - @output = Ast::NameExpression.new('foo') + @output = 'foo' check :name_expression end def test_name_underscode_start @input = '_bar ' - @output = Ast::NameExpression.new('_bar') + @output = '_bar' check :name_expression end def test_name_underscode_middle @input = 'foo_bar ' - @output = Ast::NameExpression.new('foo_bar') + @output = 'foo_bar' check :name_expression end def test_module_name @input = 'FooBar ' - @output = Ast::ModuleName.new("FooBar") - check :module_name_expression + @output = s(:aspect , "FooBar") + check :aspect_name_expression end def test_string @input = '"hello"' - @output = Ast::StringExpression.new('hello') + @output = s(:string , 'hello') check :string_expression end def test_string_escapes out = 'hello \nyou' @input = '"' + out + '"' - @output = Ast::StringExpression.new(out) + @output = s(:string , out) check :string_expression end diff --git a/test/unit/test_call_site.rb b/test/unit/test_call_site.rb index 4cb9a95..9d39468 100644 --- a/test/unit/test_call_site.rb +++ b/test/unit/test_call_site.rb @@ -5,38 +5,38 @@ class TestCallSite < MiniTest::Test def test_single_self @input = 'self.foo(42)' - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::NameExpression.new(:self),:foo), [Ast::IntegerExpression.new(42)] ) + @output = s(:call, s(:field , "self" , "foo") , [s(:int, 42)]) check :call_site end def test_single_name @input = 'my_my.foo(42)' @parse_output = {:receiver=>{:name=>"my_my"}, :call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"42"}}]} - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::NameExpression.new(:my_my),:foo), [Ast::IntegerExpression.new(42)] ) + @output = s(:call, s(:field, "my_my", "foo"), [s(:int, 42)]) check :call_site end def test_int_receiver @input = '42.put()' - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::IntegerExpression.new(42),:put), [] ) + @output = s(:call, s(:field, s(:int , 42) , "put") , []) check :call_site end def test_string_receiver @input = '"hello".puts()' - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::StringExpression.new("hello"),:puts), [] ) + @output = s(:call , s(:field , s(:string , "hello") , "puts") , []) check :call_site end def test_call_site_2 @input = 'self.baz(42, foo)' - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::NameExpression.new(:self),:baz), [Ast::IntegerExpression.new(42),Ast::NameExpression.new(:foo)] ) + @output = s(:call ,s(:field , "self", "baz") , [s(:int, 42), "foo"]) check :call_site end def test_call_site_3 @input = 'self.baz(42, foo , bar)' - @output = Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::NameExpression.new(:self),:baz), [Ast::IntegerExpression.new(42),Ast::NameExpression.new(:foo),Ast::NameExpression.new(:bar)] ) + @output = s(:call, s(:field, "self", "baz"), [s(:int, 42), "foo", "bar"]) check :call_site end diff --git a/test/unit/test_conditional.rb b/test/unit/test_conditional.rb index 913791d..2e29de5 100644 --- a/test/unit/test_conditional.rb +++ b/test/unit/test_conditional.rb @@ -5,19 +5,19 @@ class TestConditional < MiniTest::Test def test_assignment @input = "myvar = 42" - @output = Ast::AssignmentExpression.new(:myvar,Ast::IntegerExpression.new(42)) + @output = s(:assign, :myvar, s(:int, 42)) check :assignment end def test_variable_declaration @input = "int myvar" - @output = Ast::VariableDefinition.new(:int,:myvar,nil) + @output = s(:variable,s(:type, "int", "myvar"), nil) check :variable_definition end def test_variable_declaration_value @input = "int myvar = 42" - @output = Ast::VariableDefinition.new(:int,:myvar,Ast::IntegerExpression.new(42)) + @output = s(:variable, s(:type, "int", "myvar"), s(:int, 42)) check :variable_definition end @@ -27,7 +27,9 @@ if( 1 ) int num = 42 end HERE - @output = Ast::IfExpression.new(Ast::IntegerExpression.new(1), [Ast::VariableDefinition.new(:int,:num,Ast::IntegerExpression.new(42))],nil) + @output = s(:if, s(:cond, s(:int, 1)), s(:then, [s(:variable, + s(:type, "int", "num"), + s(:int, 42))])) check :conditional end @@ -37,7 +39,9 @@ if(var) 42.add(5) end HERE - @output = Ast::IfExpression.new(Ast::NameExpression.new(:var), [Ast::CallSiteExpression.new(Ast::FieldExpression.new(Ast::IntegerExpression.new(42),:add), [Ast::IntegerExpression.new(5)] )],nil) + @output = s(:if, + s(:cond, "var"), + s(:then, [s(:call, s(:field, s(:int, 42), "add"), [s(:int, 5)])])) check :conditional end @@ -51,7 +55,7 @@ end HERE @input.chop! @parse_output = {:if=>"if", :conditional=>{:l=>{:integer=>"3"}, :o=>"== ", :r=>{:nil=>"nil"}}, :if_true=>{:expressions=>[{:integer=>"3"}], :else=>"else"}, :if_false=>{:expressions=>[{:integer=>"4"}], :end=>"end"}} - @output = Ast::IfExpression.new(Ast::OperatorExpression.new("==", Ast::IntegerExpression.new(3),Ast::NilExpression.new()), [Ast::IntegerExpression.new(3)],[Ast::IntegerExpression.new(4)] ) + @output = nil @root = :conditional end @@ -63,7 +67,7 @@ end HERE @input.chop! @parse_output = {:if=>"if", :conditional=>{:l=>{:integer=>"3"}, :o=>"== ", :r=>{:nil=>"nil"}}, :if_true=>{:expressions=>[{:integer=>"3"}], :else=>"else"}, :if_false=>{:expressions=>[{:integer=>"4"}], :end=>"end"}} - @output = Ast::IfExpression.new(Ast::OperatorExpression.new("==", Ast::IntegerExpression.new(3),Ast::NilExpression.new()), [Ast::IntegerExpression.new(3)],[Ast::IntegerExpression.new(4)] ) + @output = nil @root = :conditional end