Class: Pione::Lang::StructuralContext
- Defined in:
- lib/pione/lang/context.rb
Overview
StructuralContext is a basic context for all contexts.
Direct Known Subclasses
ConditionalBranchContext, FlowContext, PackageContext, ParamContext, RuleConditionContext
Class Method Summary collapse
-
.accept(elt) ⇒ Object
Trun the element to be accepted in the context.
-
.acceptances ⇒ Object
Return all accepted declaration types in the context.
- .inherited(subclass) ⇒ Object
Instance Method Summary collapse
- #+(other) ⇒ Object
-
#eval(env) ⇒ Object
Evaluete each element in the context.
-
#initialize(*args) ⇒ StructuralContext
constructor
Initialize and validate the context.
-
#pos ⇒ Object
Return the position of first element in the context.
-
#try_to_eval(env, elts) ⇒ Object
Make trial loop for evaluation.
-
#validate(acceptances) ⇒ Object
Validate that the element type is accepted or not.
Methods inherited from Context
Constructor Details
#initialize(*args) ⇒ StructuralContext
Initialize and validate the context.
37 38 39 40 41 |
# File 'lib/pione/lang/context.rb', line 37 def initialize(*args) super(*args) raise ArgumentError.new(args) unless elements validate(acceptances) end |
Class Method Details
.accept(elt) ⇒ Object
Trun the element to be accepted in the context.
18 19 20 21 22 23 24 25 |
# File 'lib/pione/lang/context.rb', line 18 def accept(elt) acceptances << elt # define the accessor by snakecase define_method(elt.to_s.snake_case) do elements.select{|e| e.kind_of?(elt)} end end |
.acceptances ⇒ Object
Return all accepted declaration types in the context.
13 14 15 |
# File 'lib/pione/lang/context.rb', line 13 def acceptances @acceptances ||= [] end |
.inherited(subclass) ⇒ Object
27 28 29 30 |
# File 'lib/pione/lang/context.rb', line 27 def inherited(subclass) acceptances.each {|acceptance| subclass.accept acceptance} members.each {|member_name| subclass.member(member_name, default: default_values[member_name])} end |
Instance Method Details
#+(other) ⇒ Object
101 102 103 104 105 106 107 |
# File 'lib/pione/lang/context.rb', line 101 def +(other) if self.class == other.class set(elements: elements + other.elements) else raise ContextError.new(other, self) end end |
#eval(env) ⇒ Object
Evaluete each element in the context. Pione permit declarations to be in arbitray order, so the strategy of evaluation is try and error.
62 63 64 |
# File 'lib/pione/lang/context.rb', line 62 def eval(env) try_to_eval(env, elements) end |
#pos ⇒ Object
Return the position of first element in the context.
95 96 97 98 99 |
# File 'lib/pione/lang/context.rb', line 95 def pos if elements.size > 0 elements.first.pos end end |
#try_to_eval(env, elts) ⇒ Object
Make trial loop for evaluation.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/pione/lang/context.rb', line 67 def try_to_eval(env, elts) return if elts.empty? exception = nil next_elts = [] # trial elts.each do |elt| begin elt.eval(env).tap {|res| next_elts << res if res.is_a?(Context)} rescue UnboundError => e exception = e next_elts << elt end end if elts # stop endless loop if elts == next_elts raise exception end # go next trial unless next_elts.empty? return try_to_eval(env, next_elts) end end |
#validate(acceptances) ⇒ Object
Validate that the element type is accepted or not. This validation applies same criteria to conditional branches recursively.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/pione/lang/context.rb', line 45 def validate(acceptances) elements.each do |elt| # check the type accepted = acceptances.any? {|type| type == :all or elt.kind_of?(type)} # raise a context error if the type is not accepted raise ContextError.new(elt, self) if not(accepted) # check for inner branches recursively if elt.kind_of?(ConditionalBranch) elt.validate(acceptances) end end end |