From 396a843a5ea92181a9a8de61800e6d9f3a6248dc Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 18 Sep 2015 00:02:52 +0300 Subject: [PATCH] add return and argument types --- Gemfile | 4 +- Gemfile.lock | 1 + README.md | 14 ++--- lib/parser/basic_types.rb | 2 +- lib/parser/function_definition.rb | 9 ++-- lib/parser/keywords.rb | 1 - lib/parser/transform.rb | 28 +++++----- test/roots/test_class.rb | 28 +++++----- test/roots/test_function_definition.rb | 72 +++++++++++++------------- test/roots/test_module.rb | 35 +++++-------- test/roots/test_root.rb | 21 ++++---- test/unit/test_arguments.rb | 13 +++-- test/unit/test_class.rb | 24 ++++----- test/unit/test_function_definition.rb | 62 +++++++++++----------- test/unit/test_module.rb | 20 +++---- 15 files changed, 163 insertions(+), 171 deletions(-) diff --git a/Gemfile b/Gemfile index abc0eb7..024ea4c 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,9 @@ gem "rake" gem "salama-reader" , :path => "." -#gem "ast" , :path => "../ast" +# use this for debugging, the printout is better (cut/paste) +# gem "ast" , :github => "dancinglightning/ast" +gem "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 de359c7..d50872c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,6 +29,7 @@ PLATFORMS ruby DEPENDENCIES + ast codeclimate-test-reporter minitest rake diff --git a/README.md b/README.md index 0fc7777..ad9b4d2 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ Also it is very educational, as it is very readable code, and not too much of it ## Bosl Basic Object System Language Bosl is just forming after a major insight. I used to nag about C quite randomly before, but now i -found the two main things that make it (as a system language)unsuitable for implementing an Object +found the two main things that make it unsuitable, as a system language, for implementing an Object system: -- C has inherrent non object features. But one could just use structs to get around that. +- C has inherent non object features. But one could just use structs to get around that. One would have to (unlike c++ eg) forbid the usage of large parts of the language - The calling convention is not object based, ie not upward compatible in an oo system. @@ -29,6 +29,8 @@ is closed until run-time. Then one needs to have the same compiling capabilities Types, or a static type system, is also quite necessary to stay sane. It is "just" a matter of extending that for oo later. Luckily i have found a system to do that. +Return and argument types for functions are now done! + ### Syntax Syntax (and semantics) of bosl are just forming, but some things are clear: @@ -88,10 +90,9 @@ a complete transformation process. ### Operators Parslets operator support is **outstanding** and such it was a breeze to implement most operators -very simply. See the operators.rb for details. Below is a list from the web of how it should be. - - -Operator list from http://stackoverflow.com/questions/21060234/ruby-operator-precedence-table +very simply. See the operators.rb for details. +As this started as an attempt to parse ruby, below list of order precedence is close to ruby. +It would not have to be anymore though, and so is subject to change. N A M Operator(s) Description - - - ----------- ----------- @@ -130,4 +131,3 @@ N A M Operator(s) Description 1 N N defined? test variable definition and type 1 R N not boolean NOT (low precedence) 2 L N and or boolean AND, boolean OR (low precedence) -2 N N if unless while until conditional and loop modifiers diff --git a/lib/parser/basic_types.rb b/lib/parser/basic_types.rb index 5a16f0a..d9d754a 100644 --- a/lib/parser/basic_types.rb +++ b/lib/parser/basic_types.rb @@ -36,7 +36,7 @@ module Parser rule(:digit) { match('[0-9]') } rule(:exponent) { (str('e')| str('E')) } - rule(:type) { (str("int") | str("ref")).as(:type) >> space? } + rule(:type) { (str("int") | str("ref")).as(:type) >> space } # identifier must start with lower case # TODO rule forbit names like if_true, because it starts with a keyword. a little looser please! rule(:name) { keyword.absent? >> (match['a-z_'] >> match['a-zA-Z0-9_'].repeat).as(:name) >> space? } diff --git a/lib/parser/function_definition.rb b/lib/parser/function_definition.rb index 66560d8..fba0e7d 100644 --- a/lib/parser/function_definition.rb +++ b/lib/parser/function_definition.rb @@ -3,14 +3,13 @@ module Parser include Parslet rule(:function_definition) { - keyword_def >> ((module_name|name).as(:receiver) >> str(".")).maybe >> #possibly qualified - name.as(:function_name) >> parameter_list.maybe >> space >> expressions_end >> space? + type >> ((module_name|name).as(:receiver) >> str(".")).maybe >> #possibly qualified + name.as(:function_name) >> left_parenthesis >> + parameter_list.maybe >> right_parenthesis >> expressions_end >> space? } rule(:parameter_list) { - left_parenthesis >> - ((name.as(:parameter) >> (comma >> name.as(:parameter)).repeat(0)).repeat(0,1)).as(:parameter_list) >> - right_parenthesis + ((field.as(:parameter) >> (comma >> field.as(:parameter)).repeat(0)).repeat(0,1)).as(:parameter_list) } end diff --git a/lib/parser/keywords.rb b/lib/parser/keywords.rb index b32da83..ca9a4f8 100644 --- a/lib/parser/keywords.rb +++ b/lib/parser/keywords.rb @@ -4,7 +4,6 @@ module Parser rule(:keyword_begin) { str('begin').as(:begin) >> space?} rule(:keyword_class) { str('class') >> space? } - rule(:keyword_def) { str('def') >> space? } rule(:keyword_do) { str('do').as(:do) >> space?} rule(:keyword_else) { str('else').as(:else) >> space? } rule(:keyword_end) { str('end').as(:end) >> space? } diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index f93ae37..931e7f8 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -17,6 +17,7 @@ module Parser rule(:integer => simple(:value)) { s(:int ,value.to_i) } rule(:name => simple(:name)) { s(:name , name.to_s) } rule(:type => simple(:type), :name => simple(:name)) { s(:field , type.to_sym , name.to_sym) } + rule(:module_name => simple(:module_name)) { s(:module,module_name.to_s) } rule(:array_constant => sequence(:array_constant) ) { s(:array , array_constant) } @@ -63,22 +64,23 @@ module Parser rule(:parameter_list => sequence(:parameter_list)) { parameter_list } # Also two rules for function definitions, unqualified and qualified - rule(:function_name => simple(:function_name), - :parameter_list => sequence(:parameter_list), - :expressions => sequence(:expressions) , :end => simple(:e)) do - s(:function, function_name, parameter_list, expressions) - end - - rule(:function_name => simple(:function_name), - :expressions => sequence(:expressions) , :end => simple(:e)) do - s(:function , function_name, [], expressions) - end - - rule(:receiver=> simple(:receiver), + rule(:type => simple(:type) , :function_name => simple(:function_name), :parameter_list => sequence(:parameter_list), :expressions => sequence(:expressions) , :end => simple(:e)) do - s(:function, function_name, parameter_list, expressions , receiver) + s(:function, type.to_sym , function_name, parameter_list, expressions) + end + + rule(:type => simple(:type) , :function_name => simple(:function_name), + :expressions => sequence(:expressions) , :end => simple(:e)) do + s(:function , type.to_sym, function_name, [], expressions) + end + + rule(:type => simple(:type) , :receiver=> simple(:receiver), + :function_name => simple(:function_name), + :parameter_list => sequence(:parameter_list), + :expressions => sequence(:expressions) , :end => simple(:e)) do + s(:function, type.to_sym , function_name, parameter_list, expressions , receiver) end rule(l: simple(:l), o: simple(:o) , r: simple(:r)) do diff --git a/test/roots/test_class.rb b/test/roots/test_class.rb index 9125ef6..a36ac48 100644 --- a/test/roots/test_class.rb +++ b/test/roots/test_class.rb @@ -17,20 +17,20 @@ HERE def test_class_ops @string_input = <[{:module_name=>"Opers", :derived_name=>nil, :class_expressions=>[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:class, "Opers", nil, [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])])]) + @parse_output = {:expression_list=>[{:module_name=>"Opers", :derived_name=>nil, :class_expressions=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"x"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:name=>"abba"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:class, "Opers", nil, [s(:function, :int, s(:name, "foo"), [s(:field, :int, :x)], [s(:name, "int"), s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:name, "abba"), s(:int, 5))])])]) end def test_class_if @string_input = <[{:module_name=>"Ifi", :derived_name=>nil, :class_expressions=>[{:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:class, "Ifi", nil, [s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])])]) + @parse_output = {:expression_list=>[{:module_name=>"Ifi", :derived_name=>nil, :class_expressions=>[{:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:class, "Ifi", nil, [s(:function, :int, s(:name, "ofthen"), [s(:field, :int, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])])]) end def test_class_function @string_input = <[{:module_name=>"Pifi", :derived_name=>nil, :class_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}, {:parameter=>{:name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:class, "Pifi", nil, [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, s(:name, "ofthen"), [s(:name, "n"), s(:name, "m")], [s(:int, 44)])])]) + @parse_output = {:expression_list=>[{:module_name=>"Pifi", :derived_name=>nil, :class_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}, {:parameter=>{:type=>"ref", :name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:class, "Pifi", nil, [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, :int, s(:name, "ofthen"), [s(:field, :int, :n), s(:field, :ref, :m)], [s(:int, 44)])])]) end def test_class_module @string_input = <[{:module_name=>"Foo", :derived_name=>{:module_name=>"Object"}, :class_expressions=>[{:receiver=>{:module_name=>"Foo"}, :function_name=>{:name=>"test"}, :parameter_list=>[], :expressions=>[{:integer=>"43"}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:class, "Foo", s(:module, "Object"), [s(:function, s(:name, "test"), [], [s(:int, 43)], s(:module, "Foo"))])]) + @parse_output = {:expression_list=>[{:module_name=>"Foo", :derived_name=>{:module_name=>"Object"}, :class_expressions=>[{:type=>"int", :receiver=>{:module_name=>"Foo"}, :function_name=>{:name=>"test"}, :parameter_list=>[], :expressions=>[{:integer=>"43"}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:class, "Foo", s(:module, "Object"), [s(:function, :int, s(:name, "test"), [], [s(:int, 43)], s(:module, "Foo"))])]) end end diff --git a/test/roots/test_function_definition.rb b/test/roots/test_function_definition.rb index 5ef708e..0522213 100644 --- a/test/roots/test_function_definition.rb +++ b/test/roots/test_function_definition.rb @@ -6,58 +6,58 @@ class RootTestFunctionDefinition < MiniTest::Test def test_simplest_function @string_input = <[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:integer=>"5"}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:int, 5)])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:integer=>"5"}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "foo"), [s(:field, :ref, :x)], [s(:int, 5)])]) end def test_function_no_arg @string_input = <[{:function_name=>{:name=>"foo"}, :parameter_list=>[], :expressions=>[{:integer=>"5"}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "foo"), [], [s(:int, 5)])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[], :expressions=>[{:integer=>"5"}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "foo"), [], [s(:int, 5)])]) end def test_function_two_args @string_input = <[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"n"}}, {:parameter=>{:name=>"m"}}], :expressions=>[{:name=>"n"}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "foo"), [s(:name, "n"), s(:name, "m")], [s(:name, "n")])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}, {:parameter=>{:type=>"ref", :name=>"m"}}], :expressions=>[{:name=>"n"}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "foo"), [s(:field, :int, :n), s(:field, :ref, :m)], [s(:name, "n")])]) end def test_class_function @string_input = <[{:receiver=>{:module_name=>"String"}, :function_name=>{:name=>"length"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:name=>"length"}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "length"), [s(:name, "x")], [s(:name, "length")], s(:module, "String"))]) + @parse_output = {:expression_list=>[{:type=>"int", :receiver=>{:module_name=>"String"}, :function_name=>{:name=>"length"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:name=>"length"}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "length"), [s(:field, :ref, :x)], [s(:name, "length")], s(:module, "String"))]) end def test_function_ops @string_input = <[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"x"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:name=>"abba"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "foo"), [s(:field, :int, :x)], [s(:name, "int"), s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:name, "abba"), s(:int, 5))])]) end def test_function_if @string_input = <[{:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) + @parse_output = {:expression_list=>[{:type=>"ref", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :ref, s(:name, "ofthen"), [s(:field, :int, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) end def test_function_return @string_input = <[{:function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"i"}, :o=>"= ", :r=>{:integer=>"5"}}, {:return=>"return", :return_expression=>{:name=>"i"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:assign, s(:name, "i"), s(:int, 5)), s(:return, s(:name, "i"))])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"n"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"i"}, :o=>"= ", :r=>{:integer=>"5"}}, {:return=>"return", :return_expression=>{:name=>"i"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "retvar"), [s(:field, :ref, :n)], [s(:name, "int"), s(:assign, s(:name, "i"), s(:int, 5)), s(:return, s(:name, "i"))])]) end def test_function_return_if @string_input = < 5) return 10 else @@ -90,26 +90,26 @@ def retvar(n) end end HERE - @parse_output = {:expression_list=>[{:function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :if_true=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"10"}}], :else=>"else"}, :if_false=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"20"}}], :end=>"end"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:if, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:return, s(:int, 10))], [s(:return, s(:int, 20))])])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :if_true=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"10"}}], :else=>"else"}, :if_false=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"20"}}], :end=>"end"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "retvar"), [s(:field, :int, :n)], [s(:if, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:return, s(:int, 10))], [s(:return, s(:int, 20))])])]) end def test_function_return_while @string_input = < 5) n = n + 1 return n end end HERE - @parse_output = {:expression_list=>[{:function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :body=>{:expressions=>[{:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"+ ", :r=>{:integer=>"1"}}}, {:return=>"return", :return_expression=>{:name=>"n"}}], :end=>"end"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:while, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:assign, s(:name, "n"), s(:operator, "+", s(:name, "n"), s(:int, 1))), s(:return, s(:name, "n"))])])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :body=>{:expressions=>[{:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"+ ", :r=>{:integer=>"1"}}}, {:return=>"return", :return_expression=>{:name=>"n"}}], :end=>"end"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "retvar"), [s(:field, :int, :n)], [s(:while, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:assign, s(:name, "n"), s(:operator, "+", s(:name, "n"), s(:int, 1))), s(:return, s(:name, "n"))])])]) end def test_function_while @string_input = <[{:function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:while=>"while", :while_cond=>{:name=>"n"}, :body=>{:expressions=>[{:l=>{:name=>"some"}, :o=>"= ", :r=>{:integer=>"43"}}, {:l=>{:name=>"other"}, :o=>"= ", :r=>{:l=>{:name=>"some"}, :o=>"* ", :r=>{:integer=>"4"}}}], :end=>"end"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0)), s(:while, s(:name, "n"), [s(:assign, s(:name, "some"), s(:int, 43)), s(:assign, s(:name, "other"), s(:operator, "*", s(:name, "some"), s(:int, 4)))])])]) + @parse_output = {:expression_list=>[{:type=>"ref", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:while=>"while", :while_cond=>{:name=>"n"}, :body=>{:expressions=>[{:l=>{:name=>"some"}, :o=>"= ", :r=>{:integer=>"43"}}, {:l=>{:name=>"other"}, :o=>"= ", :r=>{:l=>{:name=>"some"}, :o=>"* ", :r=>{:integer=>"4"}}}], :end=>"end"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :ref, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:assign, s(:name, "a"), s(:int, 0)), s(:while, s(:name, "n"), [s(:assign, s(:name, "some"), s(:int, 43)), s(:assign, s(:name, "other"), s(:operator, "*", s(:name, "some"), s(:int, 4)))])])]) end def test_function_big_while @string_input = < 1 ) @@ -135,7 +135,7 @@ def fibonaccit(n) end end HERE - @parse_output = {:expression_list=>[{:function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"}]} - @transform_output = s(:list, [s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0)), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:assign, s(:name, "a"), s(:int, 0)), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])])]) end end diff --git a/test/roots/test_module.rb b/test/roots/test_module.rb index bf7dc5e..704909a 100644 --- a/test/roots/test_module.rb +++ b/test/roots/test_module.rb @@ -17,14 +17,14 @@ HERE def test_module_ops @string_input = <[{:module_name=>"Opers", :module_expressions=>[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:module, "Opers", [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])])]) + @parse_output = {:expression_list=>[{:module_name=>"Opers", :module_expressions=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"x"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:return=>"return", :return_expression=>{:l=>{:name=>"abba"}, :o=>"+ ", :r=>{:integer=>"5"}}}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:module, "Opers", [s(:function, :int, s(:name, "foo"), [s(:field, :int, :x)], [s(:name, "int"), s(:assign, s(:name, "abba"), s(:int, 5)), s(:return, s(:operator, "+", s(:name, "abba"), s(:int, 5)))])])]) end def test_module_assign_var @@ -40,7 +40,7 @@ HERE def test_module_if @string_input = <[{:module_name=>"Foo", :module_expressions=>[{:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:module, "Foo", [s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])])]) + @parse_output = {:expression_list=>[{:module_name=>"Foo", :module_expressions=>[{:type=>"ref", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:module, "Foo", [s(:function, :ref, s(:name, "ofthen"), [s(:field, :int, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])])]) end def test_module_function @string_input = <[{:module_name=>"Soho", :module_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}, {:parameter=>{:name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:module, "Soho", [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, s(:name, "ofthen"), [s(:name, "n"), s(:name, "m")], [s(:int, 44)])])]) + @parse_output = {:expression_list=>[{:module_name=>"Soho", :module_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}, {:parameter=>{:type=>"ref", :name=>"m"}}], :expressions=>[{:return=>"return", :return_expression=>{:integer=>"44"}}], :end=>"end"}], :end=>"end"}]} + @transform_output = s(:list, [s(:module, "Soho", [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, :int, s(:name, "ofthen"), [s(:field, :int, :n), s(:field, :ref, :m)], [s(:return, s(:int, 44))])])]) end - def test_function_without_braces - @string_input = <[{:module_name=>"Foo", :derived_name=>nil, :class_expressions=>[{:function_name=>{:name=>"bar"}, :expressions=>[{:integer=>"4"}], :end=>"end"}], :end=>"end"}]} - @transform_output = s(:list, [s(:class, "Foo", nil, [s(:function, s(:name, "bar"), [], [s(:int, 4)])])]) - end def test_module_class @string_input = <[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"5"}}], :end=>"end"}, {:call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"3"}}]}]} - @transform_output = s(:list, [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "a"), s(:int, 5))]), s(:call, s(:name, "foo"), [s(:int, 3)])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"5"}}], :end=>"end"}, {:call_site=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"3"}}]}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "foo"), [s(:field, :ref, :x)], [s(:assign, s(:name, "a"), s(:int, 5))]), s(:call, s(:name, "foo"), [s(:int, 3)])]) end def ttest_comments @@ -37,7 +37,7 @@ HERE def test_fibo1 @string_input = < 1 ) @@ -51,23 +51,24 @@ end fibonaccit( 10 ) HERE - @parse_output = {:expression_list=>[{:function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"}, {:call_site=>{:name=>"fibonaccit"}, :argument_list=>[{:argument=>{:integer=>"10"}}]}]} - @transform_output = s(:list, [s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0)), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])]), s(:call, s(:name, "fibonaccit"), [s(:int, 10)])]) + @parse_output = {:expression_list=>[{:type=>"int", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"}, {:call_site=>{:name=>"fibonaccit"}, :argument_list=>[{:argument=>{:integer=>"10"}}]}]} + @transform_output = s(:list, [s(:function, :int, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:assign, s(:name, "a"), s(:int, 0)), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])]), s(:call, s(:name, "fibonaccit"), [s(:int, 10)])]) end def test_module_method @string_input = <[{:module_name=>"Fibo", :module_expressions=>[{:function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}], :end=>"end"}, {:call_site=>{:name=>"fibonaccit"}, :argument_list=>[{:argument=>{:integer=>"10"}}]}], :end=>"end"}]} - @transform_output = s(:list, [s(:module, "Fibo", [s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0))]), s(:call, s(:name, "fibonaccit"), [s(:int, 10)])])]) + @parse_output = {:expression_list=>[{:module_name=>"Fibo", :module_expressions=>[{:type=>"int", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:return=>"return", :return_expression=>{:name=>"a"}}], :end=>"end"}, {:call_site=>{:name=>"fibonaccit"}, :argument_list=>[{:argument=>{:integer=>"10"}}]}], :end=>"end"}]} + @transform_output = s(:list, [s(:module, "Fibo", [s(:function, :int, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:name, "int"), s(:assign, s(:name, "a"), s(:int, 0)), s(:return, s(:name, "a"))]), s(:call, s(:name, "fibonaccit"), [s(:int, 10)])])]) end def test_module_assignment diff --git a/test/unit/test_arguments.rb b/test/unit/test_arguments.rb index 1ed5faf..41a4d7f 100644 --- a/test/unit/test_arguments.rb +++ b/test/unit/test_arguments.rb @@ -20,17 +20,16 @@ class TestArguments < MiniTest::Test end def test_parameter - @string_input = "(foo)" - @parse_output = {:parameter_list=>[{:parameter=>{:name=>"foo"}}]} - @transform_output = [s(:name, "foo")] + @string_input = "ref foo" + @parse_output = {:parameter_list=>[{:parameter=>{:type=>"ref", :name=>"foo"}}]} + @transform_output = [s(:field, :ref, :foo)] @parser = @parser.parameter_list end def test_parameter_list - @string_input = "( foo , bar)" - @parse_output = {:parameter_list => [{:parameter => { :name => "foo"}}, - {:parameter => { :name => "bar"}} ]} - @transform_output = [s(:name, "foo"), s(:name, "bar")] + @string_input = "int foo , ref bar" + @parse_output = {:parameter_list=>[{:parameter=>{:type=>"int", :name=>"foo"}}, {:parameter=>{:type=>"ref", :name=>"bar"}}]} + @transform_output = [s(:field, :int, :foo), s(:field, :ref, :bar)] @parser = @parser.parameter_list end diff --git a/test/unit/test_class.rb b/test/unit/test_class.rb index a053bae..99f5215 100644 --- a/test/unit/test_class.rb +++ b/test/unit/test_class.rb @@ -18,21 +18,21 @@ HERE def test_class_ops @string_input = <"Opers", :derived_name=>nil, :class_expressions=>[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"} - @transform_output = s(:class, "Opers", nil, [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])]) + @parse_output = {:module_name=>"Opers", :derived_name=>nil, :class_expressions=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"} + @transform_output = s(:class, "Opers", nil, [s(:function, :int, s(:name, "foo"), [s(:field, :ref, :x)], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])]) @parser = @parser.class_definition end def test_class_if @string_input = <"Ifi", :derived_name=>nil, :class_expressions=>[{:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"} - @transform_output = s(:class, "Ifi", nil, [s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) + @parse_output = {:module_name=>"Ifi", :derived_name=>nil, :class_expressions=>[{:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"} + @transform_output = s(:class, "Ifi", nil, [s(:function, :int, s(:name, "ofthen"), [s(:field, :int, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) @parser = @parser.class_definition end @@ -50,13 +50,13 @@ HERE @string_input = <"Pifi", :derived_name=>nil, :class_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}, {:parameter=>{:name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"} - @transform_output = s(:class, "Pifi", nil, [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, s(:name, "ofthen"), [s(:name, "n"), s(:name, "m")], [s(:int, 44)])]) + @parse_output = {:module_name=>"Pifi", :derived_name=>nil, :class_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}, {:parameter=>{:type=>"ref", :name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"} + @transform_output = s(:class, "Pifi", nil, [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, :int, s(:name, "ofthen"), [s(:field, :int, :n), s(:field, :ref, :m)], [s(:int, 44)])]) @parser = @parser.class_definition end def test_class_module @@ -84,13 +84,13 @@ HERE def test_class_method @string_input = <"Foo", :derived_name=>{:module_name=>"Object"}, :class_expressions=>[{:receiver=>{:module_name=>"Foo"}, :function_name=>{:name=>"test"}, :parameter_list=>[], :expressions=>[{:integer=>"43"}], :end=>"end"}], :end=>"end"} - @transform_output = s(:class, "Foo", s(:module, "Object"), [s(:function, s(:name, "test"), [], [s(:int, 43)], s(:module, "Foo"))]) + @parse_output = {:module_name=>"Foo", :derived_name=>{:module_name=>"Object"}, :class_expressions=>[{:type=>"int", :receiver=>{:module_name=>"Foo"}, :function_name=>{:name=>"test"}, :parameter_list=>[], :expressions=>[{:integer=>"43"}], :end=>"end"}], :end=>"end"} + @transform_output = s(:class, "Foo", s(:module, "Object"), [s(:function, :int, s(:name, "test"), [], [s(:int, 43)], s(:module, "Foo"))]) @parser = @parser.class_definition end diff --git a/test/unit/test_function_definition.rb b/test/unit/test_function_definition.rb index 217ece4..0869aca 100644 --- a/test/unit/test_function_definition.rb +++ b/test/unit/test_function_definition.rb @@ -6,41 +6,41 @@ class TestFunctionDefinition < MiniTest::Test def test_simplest_function @string_input = <{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:integer=>"5"}], :end=>"end"} - @transform_output = s(:function, s(:name, "foo"), [s(:name, "x")], [s(:int, 5)]) + @parse_output = {:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"x"}}], :expressions=>[{:integer=>"5"}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "foo"), [s(:field, :int, :x)], [s(:int, 5)]) @parser = @parser.function_definition end def test_class_function @string_input = <{:module_name=>"String"}, :function_name=>{:name=>"length"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:name=>"length"}], :end=>"end"} - @transform_output = s(:function, s(:name, "length"), [s(:name, "x")], [s(:name, "length")], s(:module, "String")) + @parse_output = {:type=>"int", :receiver=>{:module_name=>"String"}, :function_name=>{:name=>"length"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:name=>"length"}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "length"), [s(:field, :ref, :x)], [s(:name, "length")], s(:module, "String")) @parser = @parser.function_definition end def test_function_ops @string_input = <{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))]) + @parse_output = {:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "foo"), [s(:field, :ref, :x)], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))]) @parser = @parser.function_definition end def test_function_if @string_input = <{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])]) + @parse_output = {:type=>"ref", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"} + @transform_output = s(:function, :ref, s(:name, "ofthen"), [s(:field, :int, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])]) @parser = @parser.function_definition end def test_function_return @string_input = <{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"i"}, :o=>"= ", :r=>{:integer=>"5"}}, {:return=>"return", :return_expression=>{:name=>"i"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:assign, s(:name, "i"), s(:int, 5)), s(:return, s(:name, "i"))]) + @parse_output = {:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"n"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"i"}, :o=>"= ", :r=>{:integer=>"5"}}, {:return=>"return", :return_expression=>{:name=>"i"}}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "retvar"), [s(:field, :ref, :n)], [s(:name, "int"), s(:assign, s(:name, "i"), s(:int, 5)), s(:return, s(:name, "i"))]) @parser = @parser.function_definition end def test_function_return_if @string_input = < 5) return 10 else @@ -75,45 +75,45 @@ def retvar(n) end end HERE - @parse_output = {:function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :if_true=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"10"}}], :else=>"else"}, :if_false=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"20"}}], :end=>"end"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:if, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:return, s(:int, 10))], [s(:return, s(:int, 20))])]) + @parse_output = {:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :if_true=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"10"}}], :else=>"else"}, :if_false=>{:expressions=>[{:return=>"return", :return_expression=>{:integer=>"20"}}], :end=>"end"}}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "retvar"), [s(:field, :int, :n)], [s(:if, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:return, s(:int, 10))], [s(:return, s(:int, 20))])]) @parser = @parser.function_definition end def test_function_return_while @string_input = < 5) n = n + 1 return n end end HERE - @parse_output = {:function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :body=>{:expressions=>[{:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"+ ", :r=>{:integer=>"1"}}}, {:return=>"return", :return_expression=>{:name=>"n"}}], :end=>"end"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "retvar"), [s(:name, "n")], [s(:while, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:assign, s(:name, "n"), s(:operator, "+", s(:name, "n"), s(:int, 1))), s(:return, s(:name, "n"))])]) + @parse_output = {:type=>"int", :function_name=>{:name=>"retvar"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"5"}}, :body=>{:expressions=>[{:l=>{:name=>"n"}, :o=>"= ", :r=>{:l=>{:name=>"n"}, :o=>"+ ", :r=>{:integer=>"1"}}}, {:return=>"return", :return_expression=>{:name=>"n"}}], :end=>"end"}}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "retvar"), [s(:field, :int, :n)], [s(:while, s(:operator, ">", s(:name, "n"), s(:int, 5)), [s(:assign, s(:name, "n"), s(:operator, "+", s(:name, "n"), s(:int, 1))), s(:return, s(:name, "n"))])]) @parser = @parser.function_definition end def test_function_while @string_input = <{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:while=>"while", :while_cond=>{:name=>"n"}, :body=>{:expressions=>[{:l=>{:name=>"some"}, :o=>"= ", :r=>{:integer=>"43"}}, {:l=>{:name=>"other"}, :o=>"= ", :r=>{:l=>{:name=>"some"}, :o=>"* ", :r=>{:integer=>"4"}}}], :end=>"end"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0)), s(:while, s(:name, "n"), [s(:assign, s(:name, "some"), s(:int, 43)), s(:assign, s(:name, "other"), s(:operator, "*", s(:name, "some"), s(:int, 4)))])]) + @parse_output = {:type=>"ref", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:while=>"while", :while_cond=>{:name=>"n"}, :body=>{:expressions=>[{:l=>{:name=>"some"}, :o=>"= ", :r=>{:integer=>"43"}}, {:l=>{:name=>"other"}, :o=>"= ", :r=>{:l=>{:name=>"some"}, :o=>"* ", :r=>{:integer=>"4"}}}], :end=>"end"}}], :end=>"end"} + @transform_output = s(:function, :ref, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:name, "int"), s(:assign, s(:name, "a"), s(:int, 0)), s(:while, s(:name, "n"), [s(:assign, s(:name, "some"), s(:int, 43)), s(:assign, s(:name, "other"), s(:operator, "*", s(:name, "some"), s(:int, 4)))])]) @parser = @parser.function_definition end def test_function_big_while @string_input = < 1 ) tmp = a a = b @@ -123,8 +123,8 @@ def fibonaccit(n) end end HERE - @parse_output = {:function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"} - @transform_output = s(:function, s(:name, "fibonaccit"), [s(:name, "n")], [s(:assign, s(:name, "a"), s(:int, 0)), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])]) + @parse_output = {:type=>"int", :function_name=>{:name=>"fibonaccit"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, {:name=>"int"}, {:l=>{:name=>"b"}, :o=>"= ", :r=>{:integer=>"1"}}, {:while=>"while", :while_cond=>{:l=>{:name=>"n"}, :o=>"> ", :r=>{:integer=>"1"}}, :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"}}], :end=>"end"} + @transform_output = s(:function, :int, s(:name, "fibonaccit"), [s(:field, :int, :n)], [s(:name, "int"), s(:assign, s(:name, "a"), s(:int, 0)), s(:name, "int"), s(:assign, s(:name, "b"), s(:int, 1)), s(:while, s(:operator, ">", s(:name, "n"), s(:int, 1)), [s(:assign, s(:name, "tmp"), s(:name, "a")), s(:assign, s(:name, "a"), s(:name, "b")), s(:assign, s(:name, "b"), s(:operator, "+", s(:name, "tmp"), s(:name, "b"))), s(:call, s(:name, "puts"), [s(:name, "b")]), s(:assign, s(:name, "n"), s(:operator, "-", s(:name, "n"), s(:int, 1)))])]) @parser = @parser.function_definition end end diff --git a/test/unit/test_module.rb b/test/unit/test_module.rb index 5f4098f..0576d75 100644 --- a/test/unit/test_module.rb +++ b/test/unit/test_module.rb @@ -18,14 +18,14 @@ HERE def test_module_ops @string_input = <"Opers", :module_expressions=>[{:function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"} - @transform_output = s(:module, "Opers", [s(:function, s(:name, "foo"), [s(:name, "x")], [s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])]) + @parse_output = {:module_name=>"Opers", :module_expressions=>[{:type=>"int", :function_name=>{:name=>"foo"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"x"}}], :expressions=>[{:name=>"int"}, {:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"}], :end=>"end"} + @transform_output = s(:module, "Opers", [s(:function, :int, s(:name, "foo"), [s(:field, :int, :x)], [s(:name, "int"), s(:assign, s(:name, "abba"), s(:int, 5)), s(:operator, "+", s(:int, 2), s(:int, 5))])]) @parser = @parser.module_definition end @@ -43,7 +43,7 @@ HERE def test_module_if @string_input = <"Foo", :module_expressions=>[{:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"} - @transform_output = s(:module, "Foo", [s(:function, s(:name, "ofthen"), [s(:name, "n")], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) + @parse_output = {:module_name=>"Foo", :module_expressions=>[{:type=>"int", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"ref", :name=>"n"}}], :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], :end=>"end"}], :end=>"end"} + @transform_output = s(:module, "Foo", [s(:function, :int, s(:name, "ofthen"), [s(:field, :ref, :n)], [s(:if, s(:int, 0), [s(:assign, s(:name, "isit"), s(:int, 42))], [s(:assign, s(:name, "maybenot"), s(:int, 667))])])]) @parser = @parser.module_definition end @@ -61,13 +61,13 @@ HERE @string_input = <"Soho", :module_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:name=>"n"}}, {:parameter=>{:name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"} - @transform_output = s(:module, "Soho", [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, s(:name, "ofthen"), [s(:name, "n"), s(:name, "m")], [s(:int, 44)])]) + @parse_output = {:module_name=>"Soho", :module_expressions=>[{:call_site=>{:name=>"ofthen"}, :argument_list=>[{:argument=>{:l=>{:integer=>"3"}, :o=>"+", :r=>{:integer=>"4"}}}, {:argument=>{:name=>"var"}}]}, {:type=>"ref", :function_name=>{:name=>"ofthen"}, :parameter_list=>[{:parameter=>{:type=>"int", :name=>"n"}}, {:parameter=>{:type=>"ref", :name=>"m"}}], :expressions=>[{:integer=>"44"}], :end=>"end"}], :end=>"end"} + @transform_output = s(:module, "Soho", [s(:call, s(:name, "ofthen"), [s(:operator, "+", s(:int, 3), s(:int, 4)), s(:name, "var")]), s(:function, :ref, s(:name, "ofthen"), [s(:field, :int, :n), s(:field, :ref, :m)], [s(:int, 44)])]) @parser = @parser.module_definition end