From be444bc687b60282f7e6e00572af8bdc0eb1f783 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 20 Sep 2015 12:50:06 +0300 Subject: [PATCH] add field access with tests --- lib/parser/call_site.rb | 1 + lib/parser/expression.rb | 2 +- lib/parser/salama.rb | 9 ++-- lib/parser/transform.rb | 3 ++ test/cases/call_site/field_basic.tst | 8 ++++ test/cases/class_def/class_function.tst | 43 ++++++++++++------- .../function_definition/function_return.tst | 30 +++++++------ test/cases/module_def/module_ops.tst | 38 +++++++++------- 8 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 test/cases/call_site/field_basic.tst diff --git a/lib/parser/call_site.rb b/lib/parser/call_site.rb index 55d170f..df7aeef 100644 --- a/lib/parser/call_site.rb +++ b/lib/parser/call_site.rb @@ -12,6 +12,7 @@ module Parser rule(:call_site) { (basic_type.as(:receiver) >> str(".")).maybe >> #possibly qualified name.as(:call_site) >> argument_list >> comment.maybe} + rule(:field_access) { name.as(:receiver) >> str(".") >> name.as(:field) } end end diff --git a/lib/parser/expression.rb b/lib/parser/expression.rb index b285640..4637b95 100644 --- a/lib/parser/expression.rb +++ b/lib/parser/expression.rb @@ -2,7 +2,7 @@ module Parser module Expression include Parslet - rule(:value_expression) { call_site | basic_type } + rule(:value_expression) { call_site | field_access |basic_type } rule(:expression) { (simple_return | while_do | small_conditional | conditional | operator_expression | call_site ) } diff --git a/lib/parser/salama.rb b/lib/parser/salama.rb index aa66b55..d167593 100644 --- a/lib/parser/salama.rb +++ b/lib/parser/salama.rb @@ -10,10 +10,10 @@ require_relative "module_definition" require_relative "operators" module Parser - + # obviously a work in progress !! # We "compose" the parser from bits, divide and hopefully conquer - + # a note about .maybe : .maybe is almost every respect the same as .repeat(0,1) # so either 0, or 1, in other words maybe. Nice feature, but there are strings attached: # a maybe removes the 0 a sequence (array) to a single (hash). Thus 2 transformations are needed @@ -31,8 +31,9 @@ module Parser include Operators include ModuleDef - rule(:root_body) {(module_definition | class_definition | function_definition | expression | - operator_expression | call_site | basic_type | hash_constant | array_constant )} + rule(:root_body) {(module_definition | class_definition | function_definition | + expression | operator_expression | call_site | field_access | + basic_type | hash_constant | array_constant )} rule(:root) { root_body.repeat.as(:expression_list) } end end diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index c9a995b..eba20dc 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -36,6 +36,9 @@ module Parser :argument_list => sequence(:argument_list)) do s(:call , call_site, s(:arguments , *argument_list) , s(:receiver , receiver)) end + rule( :receiver => simple(:receiver) , :field => simple(:field) ) do + s(:field_access , s(:receiver , receiver) , s(:field , field) ) + end rule(:if => simple(:if), :conditional => simple(:conditional), :if_true => {:expressions => sequence(:if_true) , :else => simple(:else) }, diff --git a/test/cases/call_site/field_basic.tst b/test/cases/call_site/field_basic.tst new file mode 100644 index 0000000..20a1994 --- /dev/null +++ b/test/cases/call_site/field_basic.tst @@ -0,0 +1,8 @@ +message.self +-- -- -- +s(:expressions, + s(:field_access, + s(:receiver, + s(:name, :message)), + s(:field, + s(:name, :self)))) diff --git a/test/cases/class_def/class_function.tst b/test/cases/class_def/class_function.tst index 62fad12..d5627dc 100644 --- a/test/cases/class_def/class_function.tst +++ b/test/cases/class_def/class_function.tst @@ -1,22 +1,33 @@ class Pifi ofthen(3 , var) int ofthen(int n , ref m) - 44 + n = n + m.index + return n end end -- -- -- -s(:expressions, - s(:class, :Pifi, - s(:derives, nil), - s(:call, - s(:name, :ofthen), - s(:arguments, - s(:int, 3), - s(:name, :var))), - s(:function, :int, - s(:name, :ofthen), - s(:parameters, - s(:field, :int, :n), - s(:field, :ref, :m)), - s(:expressions, - s(:int, 44))))) +s(:expressions, + s(:class, :Pifi, + s(:derives, nil), + s(:call, + s(:name, :ofthen), + s(:arguments, + s(:int, 3), + s(:name, :var))), + s(:function, :int, + s(:name, :ofthen), + s(:parameters, + s(:field, :int, :n), + s(:field, :ref, :m)), + s(:expressions, + s(:assign, + s(:name, :n), + s(:operator, "+", + s(:name, :n), + s(:field_access, + s(:receiver, + s(:name, :m)), + s(:field, + s(:name, :index))))), + s(:return, + s(:name, :n)))))) diff --git a/test/cases/function_definition/function_return.tst b/test/cases/function_definition/function_return.tst index d70b37c..81b8ae9 100644 --- a/test/cases/function_definition/function_return.tst +++ b/test/cases/function_definition/function_return.tst @@ -1,17 +1,21 @@ int retvar(ref n) - int i = 5 + int i = n.layout return i end -- -- -- -s(:expressions, - s(:function, :int, - s(:name, :retvar), - s(:parameters, - s(:field, :ref, :n)), - s(:expressions, - s(:name, :int), - s(:assign, - s(:name, :i), - s(:int, 5)), - s(:return, - s(:name, :i))))) +s(:expressions, + s(:function, :int, + s(:name, :retvar), + s(:parameters, + s(:field, :ref, :n)), + s(:expressions, + s(:name, :int), + s(:assign, + s(:name, :i), + s(:field_access, + s(:receiver, + s(:name, :n)), + s(:field, + s(:name, :layout)))), + s(:return, + s(:name, :i))))) diff --git a/test/cases/module_def/module_ops.tst b/test/cases/module_def/module_ops.tst index e785416..ac16217 100644 --- a/test/cases/module_def/module_ops.tst +++ b/test/cases/module_def/module_ops.tst @@ -1,22 +1,28 @@ module Opers int foo(int x) - int abba = 5 + int abba = x + self.index return abba + 5 end end -- -- -- -s(:expressions, - s(:module, :Opers, - s(:function, :int, - s(:name, :foo), - s(:parameters, - s(:field, :int, :x)), - s(:expressions, - s(:name, :int), - s(:assign, - s(:name, :abba), - s(:int, 5)), - s(:return, - s(:operator, "+", - s(:name, :abba), - s(:int, 5))))))) +s(:expressions, + s(:module, :Opers, + s(:function, :int, + s(:name, :foo), + s(:parameters, + s(:field, :int, :x)), + s(:expressions, + s(:name, :int), + s(:assign, + s(:name, :abba), + s(:operator, "+", + s(:name, :x), + s(:field_access, + s(:receiver, + s(:name, :self)), + s(:field, + s(:name, :index))))), + s(:return, + s(:operator, "+", + s(:name, :abba), + s(:int, 5)))))))