using sat gem
This commit is contained in:
parent
d5d26a3ac4
commit
0df098ef7d
1
Gemfile
1
Gemfile
@ -4,6 +4,7 @@ gem "rake"
|
|||||||
|
|
||||||
gem "salama-reader" , :path => "."
|
gem "salama-reader" , :path => "."
|
||||||
gem "citrus" , :github => "salama/citrus" , :branch => "gemspec-readme"
|
gem "citrus" , :github => "salama/citrus" , :branch => "gemspec-readme"
|
||||||
|
gem "ast" , :path => "../ast"
|
||||||
|
|
||||||
# Add dependencies to develop your gem here.
|
# Add dependencies to develop your gem here.
|
||||||
# Include everything needed to run rake, tests, features, etc.
|
# Include everything needed to run rake, tests, features, etc.
|
||||||
|
@ -11,6 +11,11 @@ PATH
|
|||||||
salama-reader (0.2.0)
|
salama-reader (0.2.0)
|
||||||
citrus (~> 3.0.3)
|
citrus (~> 3.0.3)
|
||||||
|
|
||||||
|
PATH
|
||||||
|
remote: ../ast
|
||||||
|
specs:
|
||||||
|
ast (2.1.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
@ -31,9 +36,13 @@ PLATFORMS
|
|||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
ast!
|
||||||
citrus!
|
citrus!
|
||||||
codeclimate-test-reporter
|
codeclimate-test-reporter
|
||||||
minitest
|
minitest
|
||||||
rake
|
rake
|
||||||
rubygems-tasks
|
rubygems-tasks
|
||||||
salama-reader!
|
salama-reader!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.10.5
|
||||||
|
@ -20,11 +20,11 @@ grammar Bosl
|
|||||||
end
|
end
|
||||||
|
|
||||||
rule name_expression
|
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
|
end
|
||||||
|
|
||||||
rule module_name_expression
|
rule aspect_name_expression
|
||||||
(name:([A-Z] [a-zA-Z0-9_]*) space*) { Ast::ModuleName.new(capture(:name).to_str)}
|
(name:([A-Z] [a-zA-Z0-9_]*) space*) { s(:aspect , capture(:name).to_str)}
|
||||||
end
|
end
|
||||||
|
|
||||||
rule digits
|
rule digits
|
||||||
@ -32,17 +32,17 @@ grammar Bosl
|
|||||||
end
|
end
|
||||||
|
|
||||||
rule integer_expression
|
rule integer_expression
|
||||||
(digits space*) { Ast::IntegerExpression.new(to_str.to_i) }
|
(digits space*) { s(:int , to_str.to_i) }
|
||||||
end
|
end
|
||||||
|
|
||||||
rule string_expression
|
rule string_expression
|
||||||
#"'" (/.*/ !"'") "'"
|
#"'" (/.*/ !"'") "'"
|
||||||
('"' str:(!'"' .)* '"') {Ast::StringExpression.new(capture(:str).to_str) }
|
('"' str:(!'"' .)* '"') {s(:string , capture(:str).to_str) }
|
||||||
end
|
end
|
||||||
|
|
||||||
rule basic_expression
|
rule basic_expression
|
||||||
name_expression | integer_expression |
|
name_expression | integer_expression |
|
||||||
module_name_expression | string_expression
|
aspect_name_expression | string_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
rule keyword_begin 'begin' space* end
|
rule keyword_begin 'begin' space* end
|
||||||
@ -54,21 +54,20 @@ grammar Bosl
|
|||||||
rule keyword_if 'if' end
|
rule keyword_if 'if' end
|
||||||
rule keyword_rescue 'rescue' space* end
|
rule keyword_rescue 'rescue' space* end
|
||||||
rule keyword_return 'return' 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_unless 'unless' space* end
|
||||||
rule keyword_until 'until' space* end
|
|
||||||
rule keyword_while 'while' space* end
|
rule keyword_while 'while' space* end
|
||||||
|
|
||||||
rule keyword_nil
|
rule keyword_nil
|
||||||
('nil' space* ){ Ast::NilExpression.new }
|
('nil' space* ){ s(:nil) }
|
||||||
end
|
end
|
||||||
|
|
||||||
rule keyword_false
|
rule keyword_false
|
||||||
('false' space*) { Ast::FalseExpression.new }
|
('false' space*) { s(:false) }
|
||||||
end
|
end
|
||||||
|
|
||||||
rule keyword_true
|
rule keyword_true
|
||||||
('true' space*) { Ast::TrueExpression.new }
|
('true' space*) { s(:true) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# this rule is just to make sure identifiers can't be keywords. Kind of duplication here, but we need the
|
# 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
|
rule call_site
|
||||||
(field_expression argument_list space?) {
|
(field_expression argument_list space?) {
|
||||||
Ast::CallSiteExpression.new(capture(:field_expression).value ,
|
s(:call , capture(:field_expression).value , capture(:argument_list).value )
|
||||||
capture(:argument_list).value )
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
rule field_expression
|
rule field_expression
|
||||||
(basic_expression "." name_expression space?) {
|
(basic_expression "." name_expression space?) {
|
||||||
Ast::FieldExpression.new(capture(:basic_expression).value ,
|
s(:field , capture(:basic_expression).value ,
|
||||||
capture(:name_expression).value.name )
|
capture(:name_expression).value )
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -197,21 +195,20 @@ grammar Bosl
|
|||||||
|
|
||||||
rule typed_arg
|
rule typed_arg
|
||||||
(type name_expression) {
|
(type name_expression) {
|
||||||
Ast::TypedName.new(capture(:type).value , capture(:name_expression).value.name)
|
s(:type , capture(:type).value , capture(:name_expression).value)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
rule variable_definition
|
rule variable_definition
|
||||||
(typed_arg ("=" space* value_expression)?) {
|
(typed_arg ("=" space* value_expression)?) {
|
||||||
type = capture(:typed_arg).value
|
|
||||||
value = capture(:value_expression) ? capture(:value_expression).value : nil
|
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
|
end
|
||||||
|
|
||||||
rule assignment
|
rule assignment
|
||||||
(name_expression "=" space* value_expression){
|
(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
|
end
|
||||||
|
|
||||||
@ -219,7 +216,7 @@ grammar Bosl
|
|||||||
(keyword_if left_parenthesis value_expression right_parenthesis
|
(keyword_if left_parenthesis value_expression right_parenthesis
|
||||||
body
|
body
|
||||||
keyword_end) {
|
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
|
end
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
require "ast"
|
||||||
require 'ast/expression'
|
|
||||||
|
|
||||||
module Parser
|
module Parser
|
||||||
|
|
||||||
# obviously a work in progress !!
|
# obviously a work in progress !!
|
||||||
|
|
||||||
|
Citrus::Match.include AST::Sexp
|
||||||
|
|
||||||
Citrus.require "parser/bosl"
|
Citrus.require "parser/bosl"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
require_relative "setup"
|
require_relative "setup"
|
||||||
|
require "ast"
|
||||||
|
|
||||||
# Included in parser test will create tests methods
|
# Included in parser test will create tests methods
|
||||||
module ParserHelper
|
module ParserHelper
|
||||||
|
include AST::Sexp
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
# base.send :include, InstanceMethods #provides helpers and setup
|
# base.send :include, InstanceMethods #provides helpers and setup
|
||||||
|
@ -6,62 +6,62 @@ class TestBasic < MiniTest::Test
|
|||||||
|
|
||||||
def test_true
|
def test_true
|
||||||
@input = 'true '
|
@input = 'true '
|
||||||
@output = Ast::TrueExpression.new()
|
@output = s(:true)
|
||||||
check :keyword_true
|
check :keyword_true
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_false
|
def test_false
|
||||||
@input = 'false '
|
@input = 'false '
|
||||||
@output = Ast::FalseExpression.new()
|
@output = s(:false)
|
||||||
check :keyword_false
|
check :keyword_false
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_nil
|
def test_nil
|
||||||
@input = 'nil '
|
@input = 'nil '
|
||||||
@output = Ast::NilExpression.new()
|
@output = s(:nil)
|
||||||
check :keyword_nil
|
check :keyword_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_integer
|
def test_integer
|
||||||
@input = '42 '
|
@input = '42 '
|
||||||
@output = Ast::IntegerExpression.new(42)
|
@output = s(:int , 42)
|
||||||
check :integer_expression
|
check :integer_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_name
|
def test_name
|
||||||
@input = 'foo '
|
@input = 'foo '
|
||||||
@output = Ast::NameExpression.new('foo')
|
@output = 'foo'
|
||||||
check :name_expression
|
check :name_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_name_underscode_start
|
def test_name_underscode_start
|
||||||
@input = '_bar '
|
@input = '_bar '
|
||||||
@output = Ast::NameExpression.new('_bar')
|
@output = '_bar'
|
||||||
check :name_expression
|
check :name_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_name_underscode_middle
|
def test_name_underscode_middle
|
||||||
@input = 'foo_bar '
|
@input = 'foo_bar '
|
||||||
@output = Ast::NameExpression.new('foo_bar')
|
@output = 'foo_bar'
|
||||||
check :name_expression
|
check :name_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_module_name
|
def test_module_name
|
||||||
@input = 'FooBar '
|
@input = 'FooBar '
|
||||||
@output = Ast::ModuleName.new("FooBar")
|
@output = s(:aspect , "FooBar")
|
||||||
check :module_name_expression
|
check :aspect_name_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_string
|
def test_string
|
||||||
@input = '"hello"'
|
@input = '"hello"'
|
||||||
@output = Ast::StringExpression.new('hello')
|
@output = s(:string , 'hello')
|
||||||
check :string_expression
|
check :string_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_string_escapes
|
def test_string_escapes
|
||||||
out = 'hello \nyou'
|
out = 'hello \nyou'
|
||||||
@input = '"' + out + '"'
|
@input = '"' + out + '"'
|
||||||
@output = Ast::StringExpression.new(out)
|
@output = s(:string , out)
|
||||||
check :string_expression
|
check :string_expression
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,38 +5,38 @@ class TestCallSite < MiniTest::Test
|
|||||||
|
|
||||||
def test_single_self
|
def test_single_self
|
||||||
@input = 'self.foo(42)'
|
@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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_single_name
|
def test_single_name
|
||||||
@input = 'my_my.foo(42)'
|
@input = 'my_my.foo(42)'
|
||||||
@parse_output = {:receiver=>{:name=>"my_my"}, :call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_int_receiver
|
def test_int_receiver
|
||||||
@input = '42.put()'
|
@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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_string_receiver
|
def test_string_receiver
|
||||||
@input = '"hello".puts()'
|
@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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_call_site_2
|
def test_call_site_2
|
||||||
@input = 'self.baz(42, foo)'
|
@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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_call_site_3
|
def test_call_site_3
|
||||||
@input = 'self.baz(42, foo , bar)'
|
@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
|
check :call_site
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,19 +5,19 @@ class TestConditional < MiniTest::Test
|
|||||||
|
|
||||||
def test_assignment
|
def test_assignment
|
||||||
@input = "myvar = 42"
|
@input = "myvar = 42"
|
||||||
@output = Ast::AssignmentExpression.new(:myvar,Ast::IntegerExpression.new(42))
|
@output = s(:assign, :myvar, s(:int, 42))
|
||||||
check :assignment
|
check :assignment
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_variable_declaration
|
def test_variable_declaration
|
||||||
@input = "int myvar"
|
@input = "int myvar"
|
||||||
@output = Ast::VariableDefinition.new(:int,:myvar,nil)
|
@output = s(:variable,s(:type, "int", "myvar"), nil)
|
||||||
check :variable_definition
|
check :variable_definition
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_variable_declaration_value
|
def test_variable_declaration_value
|
||||||
@input = "int myvar = 42"
|
@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
|
check :variable_definition
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -27,7 +27,9 @@ if( 1 )
|
|||||||
int num = 42
|
int num = 42
|
||||||
end
|
end
|
||||||
HERE
|
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
|
check :conditional
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -37,7 +39,9 @@ if(var)
|
|||||||
42.add(5)
|
42.add(5)
|
||||||
end
|
end
|
||||||
HERE
|
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
|
check :conditional
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -51,7 +55,7 @@ end
|
|||||||
HERE
|
HERE
|
||||||
@input.chop!
|
@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"}}
|
@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
|
@root = :conditional
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -63,7 +67,7 @@ end
|
|||||||
HERE
|
HERE
|
||||||
@input.chop!
|
@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"}}
|
@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
|
@root = :conditional
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user