add also calls on classes and more tests for that
This commit is contained in:
parent
4038bd331a
commit
86431120d5
@ -2,10 +2,12 @@ module Ast
|
||||
# assignment, like operators are really function calls
|
||||
|
||||
class CallSiteExpression < Expression
|
||||
attr_reader :name, :args
|
||||
def initialize name, args
|
||||
@name , @args = name.to_sym , args
|
||||
attr_reader :name, :args , :receiver
|
||||
|
||||
def initialize name, args , receiver = Ast::NameExpression.new("self")
|
||||
@name , @args , @receiver = name.to_sym , args , receiver
|
||||
end
|
||||
|
||||
def compile context , into
|
||||
params = args.collect{ |a| a.compile(context, into) }
|
||||
#TOOD, this needs dynamic resolution
|
||||
@ -23,13 +25,13 @@ module Ast
|
||||
|
||||
def inspect
|
||||
self.class.name + ".new(" + name.inspect + ", ["+
|
||||
args.collect{|m| m.inspect }.join( ",") +"] )"
|
||||
args.collect{|m| m.inspect }.join( ",") + "] ," + receiver.inspect + ")"
|
||||
end
|
||||
def to_s
|
||||
"#{name}(" + args.join(",") + ")"
|
||||
end
|
||||
def attributes
|
||||
[:name , :args]
|
||||
[:name , :args , :receiver]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -9,7 +9,8 @@ module Parser
|
||||
space? >> right_parenthesis
|
||||
}
|
||||
|
||||
rule(:call_site) { (name.as(:receiver) >> str(".")).repeat(0,1) >> name.as(:call_site) >> argument_list >> comment.maybe}
|
||||
rule(:call_site) { ((module_name|name).as(:receiver) >> str(".")).maybe >> #possibly qualified
|
||||
name.as(:call_site) >> argument_list >> comment.maybe}
|
||||
|
||||
|
||||
end
|
||||
|
@ -25,6 +25,10 @@ module Parser
|
||||
:argument_list => sequence(:argument_list)) do
|
||||
Ast::CallSiteExpression.new(call_site.name, argument_list )
|
||||
end
|
||||
rule( :receiver => simple(:receiver) , :call_site => simple(:call_site),
|
||||
:argument_list => sequence(:argument_list)) do
|
||||
Ast::CallSiteExpression.new(call_site.name, argument_list , receiver)
|
||||
end
|
||||
|
||||
rule(:if => simple(:if), :conditional => simple(:conditional),
|
||||
:if_true => {:expressions => sequence(:if_true) , :else => simple(:else) },
|
||||
|
@ -12,6 +12,27 @@ class TestCallSite < MiniTest::Test
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_single_self
|
||||
@string_input = 'self.foo(42)'
|
||||
@parse_output = {:receiver=>{:name=>"self"}, :call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"42"}}]}
|
||||
@transform_output = Ast::CallSiteExpression.new 'foo', [Ast::IntegerExpression.new(42)]
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_single_name
|
||||
@string_input = 'my_my.foo(42)'
|
||||
@parse_output = {:receiver=>{:name=>"my_my"}, :call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"42"}}]}
|
||||
@transform_output = Ast::CallSiteExpression.new(:foo, [Ast::IntegerExpression.new(42)] ,Ast::NameExpression.new("my_my"))
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_single_class
|
||||
@string_input = 'Object.foo(42)'
|
||||
@parse_output = {:receiver=>{:module_name=>"Object"}, :call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"42"}}]}
|
||||
@transform_output = Ast::CallSiteExpression.new(:foo, [Ast::IntegerExpression.new(42)] ,Ast::ModuleName.new("Object"))
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_call_site_multi
|
||||
@string_input = 'baz(42, foo)'
|
||||
@parse_output = {:call_site => {:name => 'baz' },
|
||||
@ -52,4 +73,18 @@ class TestCallSite < MiniTest::Test
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_call_chaining_name
|
||||
@string_input = 'puts(name.putint(4), a)'
|
||||
@parse_output = {:call_site=>{:name=>"puts"}, :argument_list=>[{:argument=>{:receiver=>{:name=>"name"}, :call_site=>{:name=>"putint"}, :argument_list=>[{:argument=>{:integer=>"4"}}]}}, {:argument=>{:name=>"a"}}]}
|
||||
@transform_output = Ast::CallSiteExpression.new(:puts, [Ast::CallSiteExpression.new(:putint, [Ast::IntegerExpression.new(4)] ,Ast::NameExpression.new("name")),Ast::NameExpression.new("a")] ,Ast::NameExpression.new("self"))
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
def test_call_chaining_class
|
||||
@string_input = 'Class.new(self.get(4))'
|
||||
@parse_output = {:receiver=>{:module_name=>"Class"}, :call_site=>{:name=>"new"}, :argument_list=>[{:argument=>{:receiver=>{:name=>"self"}, :call_site=>{:name=>"get"}, :argument_list=>[{:argument=>{:integer=>"4"}}]}}]}
|
||||
@transform_output = Ast::CallSiteExpression.new(:new, [Ast::CallSiteExpression.new(:get, [Ast::IntegerExpression.new(4)] ,Ast::NameExpression.new("self"))] ,Ast::ModuleName.new("Class"))
|
||||
@parser = @parser.call_site
|
||||
end
|
||||
|
||||
end
|
@ -20,12 +20,22 @@ else
|
||||
end
|
||||
HERE
|
||||
@string_input = "if #{cond} " + input.chop!
|
||||
@parse_output = {:if=>"if", :conditional=>{:integer=>"0"},
|
||||
:if_true=>{:expressions=>[{:integer=>"42"}], :else=>"else"},
|
||||
:if_false=>{:expressions=>[{:integer=>"667"}], :end=>"end"}}
|
||||
@transform_output = Ast::IfExpression.new( Ast::IntegerExpression.new(0),
|
||||
[Ast::IntegerExpression.new(42)], [Ast::IntegerExpression.new(667)])
|
||||
@parse_output = {:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:integer=>"42"}], :else=>"else"}, :if_false=>{:expressions=>[{:integer=>"667"}], :end=>"end"}}
|
||||
@transform_output = Ast::IfExpression.new(Ast::IntegerExpression.new(0), [Ast::IntegerExpression.new(42)],[Ast::IntegerExpression.new(667)] )
|
||||
@parser = @parser.conditional
|
||||
end
|
||||
|
||||
def test_conditional_with_calls
|
||||
@string_input = <<HERE
|
||||
if(3 > var)
|
||||
Object.initialize(3)
|
||||
else
|
||||
var.new(33)
|
||||
end
|
||||
HERE
|
||||
@string_input.chop!
|
||||
@parse_output = {:if=>"if", :conditional=>{:l=>{:integer=>"3"}, :o=>"> ", :r=>{:name=>"var"}}, :if_true=>{:expressions=>[{:receiver=>{:module_name=>"Object"}, :call_site=>{:name=>"initialize"}, :argument_list=>[{:argument=>{:integer=>"3"}}]}], :else=>"else"}, :if_false=>{:expressions=>[{:receiver=>{:name=>"var"}, :call_site=>{:name=>"new"}, :argument_list=>[{:argument=>{:integer=>"33"}}]}], :end=>"end"}}
|
||||
@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
|
||||
end
|
@ -70,6 +70,7 @@ HERE
|
||||
@transform_output = Ast::ModuleExpression.new(:Soho ,[Ast::CallSiteExpression.new(:ofthen, [Ast::OperatorExpression.new("+", Ast::IntegerExpression.new(3),Ast::IntegerExpression.new(4)),Ast::NameExpression.new("var")] ), Ast::FunctionExpression.new(:ofthen, [Ast::NameExpression.new("n"),Ast::NameExpression.new("m")] , [Ast::IntegerExpression.new(44)] )] )
|
||||
@parser = @parser.module_definition
|
||||
end
|
||||
|
||||
def test_module_class
|
||||
@string_input = <<HERE
|
||||
module Foo
|
||||
|
@ -102,6 +102,17 @@ HERE
|
||||
@transform_output = [Ast::ModuleExpression.new(:FooBo ,[Ast::ClassExpression.new(:Bar ,[Ast::OperatorExpression.new("=", Ast::NameExpression.new("a"),Ast::OperatorExpression.new("+", Ast::IntegerExpression.new(5),Ast::NameExpression.new("foo")))] )] )]
|
||||
end
|
||||
|
||||
def test_class_method
|
||||
@string_input = <<HERE
|
||||
class FooBo
|
||||
Bar.call(35)
|
||||
end
|
||||
|
||||
HERE
|
||||
@parse_output = [{:module_name=>"FooBo", :class_expressions=>[{:receiver=>{:module_name=>"Bar"}, :call_site=>{:name=>"call"}, :argument_list=>[{:argument=>{:integer=>"35"}}]}], :end=>"end"}]
|
||||
@transform_output = [Ast::ClassExpression.new(:FooBo ,[Ast::CallSiteExpression.new(:call, [Ast::IntegerExpression.new(35)] ,Ast::ModuleName.new("Bar"))] )]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -12,15 +12,21 @@ while(1) do
|
||||
end
|
||||
HERE
|
||||
@string_input.chop!
|
||||
@parse_output = {:while=>"while",
|
||||
:while_cond=>{:integer=>"1"},
|
||||
:do=>"do",
|
||||
:body=>{:expressions=>[{:l=>{:name=>"tmp"}, :o=>"= ", :r=>{:name=>"a"}},
|
||||
{:call_site=>{:name=>"puts"}, :argument_list=>[{:argument=>{:name=>"b"}}]}], :end=>"end"}}
|
||||
@transform_output = Ast::WhileExpression.new(
|
||||
Ast::IntegerExpression.new(1),
|
||||
[Ast::OperatorExpression.new("=", Ast::NameExpression.new("tmp"),Ast::NameExpression.new("a")),
|
||||
Ast::CallSiteExpression.new("puts", [Ast::NameExpression.new("b")] )] )
|
||||
@parse_output = {:while=>"while", :while_cond=>{:integer=>"1"}, :do=>"do", :body=>{:expressions=>[{:l=>{:name=>"tmp"}, :o=>"= ", :r=>{:name=>"a"}}, {:call_site=>{:name=>"puts"}, :argument_list=>[{:argument=>{:name=>"b"}}]}], :end=>"end"}}
|
||||
@transform_output = Ast::WhileExpression.new(Ast::IntegerExpression.new(1), [Ast::OperatorExpression.new("=", Ast::NameExpression.new("tmp"),Ast::NameExpression.new("a")), Ast::CallSiteExpression.new(:puts, [Ast::NameExpression.new("b")] ,Ast::NameExpression.new("self"))] )
|
||||
@parser = @parser.while_do
|
||||
end
|
||||
|
||||
def test_while_method
|
||||
@string_input = <<HERE
|
||||
while(1) do
|
||||
tmp = String.new()
|
||||
tmp.puts(i)
|
||||
end
|
||||
HERE
|
||||
@string_input.chop!
|
||||
@parse_output = {:while=>"while", :while_cond=>{:integer=>"1"}, :do=>"do", :body=>{:expressions=>[{:l=>{:name=>"tmp"}, :o=>"= ", :r=>{:receiver=>{:module_name=>"String"}, :call_site=>{:name=>"new"}, :argument_list=>[]}}, {:receiver=>{:name=>"tmp"}, :call_site=>{:name=>"puts"}, :argument_list=>[{:argument=>{:name=>"i"}}]}], :end=>"end"}}
|
||||
@transform_output = Ast::WhileExpression.new(Ast::IntegerExpression.new(1), [Ast::OperatorExpression.new("=", Ast::NameExpression.new("tmp"),Ast::CallSiteExpression.new(:new, [] ,Ast::ModuleName.new("String"))), Ast::CallSiteExpression.new(:puts, [Ast::NameExpression.new("i")] ,Ast::NameExpression.new("tmp"))] )
|
||||
@parser = @parser.while_do
|
||||
end
|
||||
|
||||
@ -35,23 +41,8 @@ while( n > 1) do
|
||||
end
|
||||
HERE
|
||||
@string_input.chop!
|
||||
@parse_output = {:while=>"while",
|
||||
:while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}},
|
||||
:do=>"do",
|
||||
:body=>{:expressions=>[{:l=>{:name=>"tmp"}, :o=>"= ", :r=>{:name=>"a"}},
|
||||
{:l=>{:name=>"a"}, :o=>"= ", :r=>{:name=>"b"}},
|
||||
{:l=>{:name=>"b"}, :o=>"= ", :r=>{:l=>{:name=>"tmp"}, :o=>"+ ", :r=>{:name=>"b"}}},
|
||||
{:call_site=>{:name=>"puts"},
|
||||
:argument_list=>[{:argument=>{:name=>"b"}}]},
|
||||
{:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"- ", :r=>{:integer=>"1"}}}],
|
||||
:end=>"end"}}
|
||||
@transform_output = Ast::WhileExpression.new(
|
||||
Ast::OperatorExpression.new(">", Ast::NameExpression.new("n"),Ast::IntegerExpression.new(1)),
|
||||
[Ast::OperatorExpression.new("=", Ast::NameExpression.new("tmp"),Ast::NameExpression.new("a")),
|
||||
Ast::OperatorExpression.new("=", Ast::NameExpression.new("a"),Ast::NameExpression.new("b")),
|
||||
Ast::OperatorExpression.new("=", Ast::NameExpression.new("b"),Ast::OperatorExpression.new("+", Ast::NameExpression.new("tmp"),
|
||||
Ast::NameExpression.new("b"))), Ast::CallSiteExpression.new("puts", [Ast::NameExpression.new("b")] ),
|
||||
Ast::OperatorExpression.new("=", Ast::NameExpression.new("n"),Ast::OperatorExpression.new("-", Ast::NameExpression.new("n"),Ast::IntegerExpression.new(1)))] )
|
||||
@parse_output = {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :do=>"do", :body=>{:expressions=>[{:l=>{:name=>"tmp"}, :o=>"= ", :r=>{:name=>"a"}}, {:l=>{:name=>"a"}, :o=>"= ", :r=>{:name=>"b"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:l=>{:name=>"tmp"}, :o=>"+ ", :r=>{:name=>"b"}}}, {:call_site=>{:name=>"puts"}, :argument_list=>[{:argument=>{:name=>"b"}}]}, {:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"- ", :r=>{:integer=>"1"}}}], :end=>"end"}}
|
||||
@transform_output = Ast::WhileExpression.new(Ast::OperatorExpression.new(">", Ast::NameExpression.new("n"),Ast::IntegerExpression.new(1)), [Ast::OperatorExpression.new("=", Ast::NameExpression.new("tmp"),Ast::NameExpression.new("a")), Ast::OperatorExpression.new("=", Ast::NameExpression.new("a"),Ast::NameExpression.new("b")), Ast::OperatorExpression.new("=", Ast::NameExpression.new("b"),Ast::OperatorExpression.new("+", Ast::NameExpression.new("tmp"),Ast::NameExpression.new("b"))), Ast::CallSiteExpression.new(:puts, [Ast::NameExpression.new("b")] ,Ast::NameExpression.new("self")), Ast::OperatorExpression.new("=", Ast::NameExpression.new("n"),Ast::OperatorExpression.new("-", Ast::NameExpression.new("n"),Ast::IntegerExpression.new(1)))] )
|
||||
@parser = @parser.while_do
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user