From 34691f36d13f68d2c39cea266f26ea201bc78bb6 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 27 Sep 2015 12:05:35 +0300 Subject: [PATCH] add class_fields as separate syntax --- lib/parser/basic_types.rb | 2 +- lib/parser/expression.rb | 3 ++- lib/parser/keywords.rb | 3 ++- lib/parser/module_definition.rb | 2 +- lib/parser/transform.rb | 6 ++++++ test/cases/class_def/class_derived.tst | 8 ++++---- test/cases/module_def/module_assign_var.tst | 9 +++++---- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/parser/basic_types.rb b/lib/parser/basic_types.rb index 33f2b7e..77f1fe8 100644 --- a/lib/parser/basic_types.rb +++ b/lib/parser/basic_types.rb @@ -42,8 +42,8 @@ module Parser rule(:name) { (keyword|type).absent? >> (match['a-z_'] >> match['a-zA-Z0-9_'].repeat).as(:name) >> space? } # fields have type rule(:field) { type >> name >> (assign >> value_expression.as(:value) ).maybe} + rule(:class_field) { keyword_field >> field } # and class/module names must start with capital - # (admittatly the rule matches constants too, but one step at a time) rule(:module_name) { keyword.absent? >> (match['A-Z'] >> match['a-zA-Z0-9_'].repeat).as(:module_name) >> space? } rule(:escape) { str('\\') >> any.as(:esc) } diff --git a/lib/parser/expression.rb b/lib/parser/expression.rb index de67f28..7185aa3 100644 --- a/lib/parser/expression.rb +++ b/lib/parser/expression.rb @@ -5,7 +5,8 @@ module Parser rule(:value_expression) { call_site | field_access |basic_type } rule(:expression) { (simple_return | while_do | small_conditional | conditional | - operator_expression | call_site | field | hash_constant | array_constant) } + operator_expression | call_site | class_field | field | + hash_constant | array_constant) } def delimited_expressions( delimit ) ( (delimit.absent? >> expression).repeat(1)).as(:expressions) >> delimit diff --git a/lib/parser/keywords.rb b/lib/parser/keywords.rb index ca9a4f8..89b6a6c 100644 --- a/lib/parser/keywords.rb +++ b/lib/parser/keywords.rb @@ -8,6 +8,7 @@ module Parser rule(:keyword_else) { str('else').as(:else) >> space? } rule(:keyword_end) { str('end').as(:end) >> space? } rule(:keyword_false) { str('false').as(:false) } + rule(:keyword_field) { str('field').as(:field) >> space? } rule(:keyword_if) { str('if').as(:if) } rule(:keyword_rescue) { str('rescue').as(:rescue) >> space?} rule(:keyword_return) { str('return').as(:return) >> space?} @@ -22,6 +23,6 @@ module Parser # space in above rules, so just make sure to add any here too. rule(:keyword){ str('begin') | str('def') | str('do') | str('else') | str('end') | str('false')| str('if')| str('rescue')| str('true')| str('nil') | - str('unless')| str('until')| str('while')} + str('unless')| str('until')| str('while') | str('field')} end end diff --git a/lib/parser/module_definition.rb b/lib/parser/module_definition.rb index 69f24ac..f8e7337 100644 --- a/lib/parser/module_definition.rb +++ b/lib/parser/module_definition.rb @@ -7,7 +7,7 @@ module Parser end rule(:class_definition) do - keyword_class >> module_name >> (smaller >> module_name).maybe.as(:derived_name) >> + keyword_class >> module_name >> (smaller >> module_name).maybe.as(:derived_name) >> ( (keyword_end.absent? >> root_body).repeat()).as(:class_expressions) >> keyword_end end diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index 3300c94..56d3548 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -14,9 +14,15 @@ module Parser rule(:nil => simple(:nil)) { s(:nil) } rule(:integer => simple(:value)) { s(:int ,value.to_i) } rule(:name => simple(:name)) { s(:name , name.to_sym) } + # local variables rule(:type => simple(:type), :name => simple(:name)) { s(:field_def , type.to_sym , name.to_sym) } rule(:type => simple(:type), :name => simple(:name) , :value => simple(:value)) { s(:field_def , type.to_sym , name.to_sym , value ) } + # class field + rule(:field => simple(:field) , :type => simple(:type), :name => simple(:name)) { + s(:class_field , type.to_sym , name.to_sym) } + rule(:field => simple(:field) , :type => simple(:type), :name => simple(:name) , :value => simple(:value)) { + s(:class_field , type.to_sym , name.to_sym , value ) } rule(:module_name => simple(:module_name)) { s(:module,module_name.to_s) } diff --git a/test/cases/class_def/class_derived.tst b/test/cases/class_def/class_derived.tst index c838ec6..a650c7e 100644 --- a/test/cases/class_def/class_derived.tst +++ b/test/cases/class_def/class_derived.tst @@ -1,7 +1,7 @@ class Foo < Object - int field = 3 + field int fff = 3 int func() - return self.field + return self.fff end ofthen(3 , var) end @@ -10,7 +10,7 @@ s(:expressions, s(:class, :Foo, s(:derives, :Object), s(:expressions, - s(:field_def, :int, :field, + s(:class_field, :int, :fff, s(:int, 3)), s(:function, :int, s(:name, :func), @@ -21,7 +21,7 @@ s(:expressions, s(:receiver, s(:name, :self)), s(:field, - s(:name, :field)))))), + s(:name, :fff)))))), s(:call, s(:name, :ofthen), s(:arguments, diff --git a/test/cases/module_def/module_assign_var.tst b/test/cases/module_def/module_assign_var.tst index a96f9c9..0873dd3 100644 --- a/test/cases/module_def/module_assign_var.tst +++ b/test/cases/module_def/module_assign_var.tst @@ -1,10 +1,11 @@ module Opers - abba = 5 + field int abba = 5 + field ref baab end -- -- -- s(:expressions, s(:module, :Opers, s(:expressions, - s(:assign, - s(:name, :abba), - s(:int, 5))))) + s(:class_field, :int, :abba, + s(:int, 5)), + s(:class_field, :ref, :baab))))