fabulator 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +30 -1
- data/VERSION +1 -1
- data/features/functions.feature +7 -0
- data/features/primitives.feature +1 -1
- data/features/step_definitions/template_steps.rb +40 -3
- data/features/step_definitions/xml_steps.rb +3 -2
- data/features/templates.feature +49 -22
- data/features/types.feature +4 -4
- data/lib/fabulator.rb +4 -0
- data/lib/fabulator/compiler.rb +27 -0
- data/lib/fabulator/core.rb +3 -8
- data/lib/fabulator/core/actions/choose.rb +0 -18
- data/lib/fabulator/core/actions/for_each.rb +0 -48
- data/lib/fabulator/core/{actions.rb → lib.rb} +189 -117
- data/lib/fabulator/core/structurals.rb +7 -0
- data/lib/fabulator/core/{constraint.rb → structurals/constraint.rb} +2 -0
- data/lib/fabulator/core/{filter.rb → structurals/filter.rb} +2 -0
- data/lib/fabulator/core/{group.rb → structurals/group.rb} +2 -0
- data/lib/fabulator/core/{parameter.rb → structurals/parameter.rb} +2 -0
- data/lib/fabulator/core/{state.rb → structurals/state.rb} +2 -0
- data/lib/fabulator/core/{state_machine.rb → structurals/state_machine.rb} +2 -0
- data/lib/fabulator/core/{transition.rb → structurals/transition.rb} +2 -0
- data/lib/fabulator/expr.rb +6 -0
- data/lib/fabulator/expr/context.rb +65 -10
- data/lib/fabulator/expr/node_logic.rb +3 -2
- data/lib/fabulator/expr/parser.rb +787 -638
- data/lib/fabulator/expr/statement_list.rb +27 -0
- data/lib/fabulator/lib.rb +3 -0
- data/lib/fabulator/lib/action.rb +12 -9
- data/lib/fabulator/lib/lib.rb +85 -9
- data/lib/fabulator/structural.rb +24 -5
- data/lib/fabulator/tag_lib.rb +78 -124
- data/lib/fabulator/tag_lib/presentations.rb +39 -0
- data/lib/fabulator/tag_lib/transformations.rb +66 -0
- data/lib/fabulator/tag_lib/type.rb +176 -0
- data/lib/fabulator/template/parse_result.rb +125 -62
- data/lib/fabulator/template/parser.rb +17 -1
- data/xslt/form.xsl +163 -2083
- data/xsm_expression_parser.racc +35 -20
- metadata +17 -13
- data/lib/fabulator/context.rb +0 -39
@@ -5,6 +5,11 @@ module Fabulator
|
|
5
5
|
@statements = [ ]
|
6
6
|
@ensures = [ ]
|
7
7
|
@catches = [ ]
|
8
|
+
@context = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def use_context(c)
|
12
|
+
@context = c
|
8
13
|
end
|
9
14
|
|
10
15
|
def add_statement(s)
|
@@ -28,6 +33,9 @@ module Fabulator
|
|
28
33
|
end
|
29
34
|
|
30
35
|
def run(context, autovivify = false)
|
36
|
+
if !@context.nil?
|
37
|
+
context = @context
|
38
|
+
end
|
31
39
|
result = [ ]
|
32
40
|
begin
|
33
41
|
if !@statements.nil?
|
@@ -84,6 +92,25 @@ module Fabulator
|
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
95
|
+
class ErrExpr
|
96
|
+
def initialize(e,c)
|
97
|
+
@expr = e
|
98
|
+
@err_expr = c
|
99
|
+
end
|
100
|
+
|
101
|
+
def run(context, autovivify = false)
|
102
|
+
result = []
|
103
|
+
begin
|
104
|
+
result = @expr.run(context, autovivify)
|
105
|
+
rescue => e
|
106
|
+
ctx = context.merge
|
107
|
+
ctx.set_var('e', e)
|
108
|
+
result = @err_expr.run(ctx)
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
87
114
|
class DataSet
|
88
115
|
def initialize(p,v)
|
89
116
|
@path = p
|
data/lib/fabulator/lib.rb
CHANGED
data/lib/fabulator/lib/action.rb
CHANGED
@@ -5,6 +5,7 @@ module Fabulator
|
|
5
5
|
module Lib
|
6
6
|
class Action < Fabulator::Structural
|
7
7
|
attr_accessor :attributes
|
8
|
+
attr_accessor :namespace
|
8
9
|
|
9
10
|
namespace FAB_LIB_NS
|
10
11
|
|
@@ -18,7 +19,7 @@ module Fabulator
|
|
18
19
|
def compile_action(e, context)
|
19
20
|
ret = nil
|
20
21
|
context.with(e) do |ctx|
|
21
|
-
ret = ActionRef.new(
|
22
|
+
ret = ActionRef.new([ e.namespaces.namespace.href, e.name ], ctx, ctx.compile_actions(e))
|
22
23
|
end
|
23
24
|
ret
|
24
25
|
end
|
@@ -30,8 +31,8 @@ module Fabulator
|
|
30
31
|
@action = defining_action
|
31
32
|
@actions = actions
|
32
33
|
@static_attributes = { }
|
33
|
-
@action.attributes.collect{ |a| a.is_static? }.each do |a|
|
34
|
-
@static_attributes[a.
|
34
|
+
@context.get_action(@action.first, @action.last).attributes.collect{ |a| a.is_static? }.each do |a|
|
35
|
+
@static_attributes[a.name] = a.value(@context)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -39,17 +40,19 @@ module Fabulator
|
|
39
40
|
ret = [ ]
|
40
41
|
@context.with(context) do |ctx|
|
41
42
|
@static_attributes.each_pair do |p,v|
|
42
|
-
ctx.
|
43
|
+
ctx.set_var(p, v)
|
43
44
|
end
|
44
45
|
# These can be passed to f:eval to get their value
|
45
|
-
|
46
|
-
|
46
|
+
action = ctx.get_action(@action.first, @action.last)
|
47
|
+
action.attributes.collect{ |a| !a.is_static? }.each do |attr|
|
48
|
+
ctx.set_var(attr.name, attr.value(ctx))
|
47
49
|
end
|
48
50
|
# we can f:eval($actions) in whatever current context we have
|
49
|
-
if
|
50
|
-
|
51
|
+
if action.has_actions?
|
52
|
+
@actions.use_context(context)
|
53
|
+
ctx.set_var('actions', ctx.root.anon_node( @actions, [ FAB_NS, 'expression' ]))
|
51
54
|
end
|
52
|
-
ret =
|
55
|
+
ret = action.run(ctx)
|
53
56
|
end
|
54
57
|
ret
|
55
58
|
end
|
data/lib/fabulator/lib/lib.rb
CHANGED
@@ -8,15 +8,21 @@ module Fabulator
|
|
8
8
|
|
9
9
|
attribute :ns, :static => true
|
10
10
|
|
11
|
-
contains :action, :storage => :hash, :key => :name
|
12
|
-
contains :structural, :storage => :hash, :key => :name
|
13
|
-
contains :function, :storage => :hash, :key => :name
|
14
|
-
contains :mapping, :storage => :hash, :key => :name
|
15
|
-
contains :reduction, :storage => :hash, :key => :name
|
16
|
-
contains :consolidation, :storage => :hash, :key => :name
|
17
|
-
contains :type, :storage => :hash, :key => :name
|
18
|
-
contains :filter, :storage => :hash, :key => :name
|
19
|
-
contains :constraint, :storage => :hash, :key => :name
|
11
|
+
contains :action, :storage => :hash, :key => :name, :delayable => true
|
12
|
+
contains :structural, :storage => :hash, :key => :name, :delayable => true
|
13
|
+
contains :function, :storage => :hash, :key => :name, :delayable => true
|
14
|
+
contains :mapping, :storage => :hash, :key => :name, :delayable => true
|
15
|
+
contains :reduction, :storage => :hash, :key => :name, :delayable => true
|
16
|
+
contains :consolidation, :storage => :hash, :key => :name, :delayable => true
|
17
|
+
contains :type, :storage => :hash, :key => :name, :delayable => true
|
18
|
+
contains :filter, :storage => :hash, :key => :name, :delayable => true
|
19
|
+
contains :constraint, :storage => :hash, :key => :name, :delayable => true
|
20
|
+
contains :format, :storage => :hash, :key => :name
|
21
|
+
contains :transform
|
22
|
+
|
23
|
+
def presentation
|
24
|
+
@presentations ||= Fabulator::TagLib::Presentations.new
|
25
|
+
end
|
20
26
|
|
21
27
|
def register_library
|
22
28
|
Fabulator::TagLib.namespaces[self.ns] = self
|
@@ -28,6 +34,15 @@ module Fabulator
|
|
28
34
|
@actions[name].compile_action(e, context)
|
29
35
|
end
|
30
36
|
|
37
|
+
def get_action(nom, context)
|
38
|
+
return nil unless self.action_exists?(nom)
|
39
|
+
@actions[nom]
|
40
|
+
end
|
41
|
+
|
42
|
+
def action_exists?(nom)
|
43
|
+
@actions.has_key?(nom.to_s)
|
44
|
+
end
|
45
|
+
|
31
46
|
def run_function(context, nom, args)
|
32
47
|
# look for a function/mapping/consolidation
|
33
48
|
# then pass along to any objects in @contained
|
@@ -115,6 +130,67 @@ module Fabulator
|
|
115
130
|
end
|
116
131
|
false
|
117
132
|
end
|
133
|
+
|
134
|
+
protected
|
135
|
+
|
136
|
+
def setup(xml)
|
137
|
+
ns = xml.attributes.get_attribute_ns(FAB_LIB_NS, 'ns').value
|
138
|
+
Fabulator::TagLib.namespaces[ns] = self
|
139
|
+
|
140
|
+
self.init_attribute_storage
|
141
|
+
|
142
|
+
possibilities = self.class.structurals
|
143
|
+
|
144
|
+
if !possibilities.nil?
|
145
|
+
|
146
|
+
our_ns = xml.namespaces.namespace.href
|
147
|
+
our_nom = xml.name
|
148
|
+
delayed = [ ]
|
149
|
+
xml.each_element{ |e| delayed << e }
|
150
|
+
while !delayed.empty?
|
151
|
+
structs = { }
|
152
|
+
new_delayed = [ ]
|
153
|
+
delayed.each do |e|
|
154
|
+
ns = e.namespaces.namespace.href
|
155
|
+
nom = e.name.to_sym
|
156
|
+
allowed = (Fabulator::TagLib.namespaces[our_ns].structural_class(our_nom).accepts_structural?(ns, nom) rescue false)
|
157
|
+
next unless allowed
|
158
|
+
structs[ns] ||= { }
|
159
|
+
structs[ns][nom] ||= [ ]
|
160
|
+
begin
|
161
|
+
structs[ns][nom] << @context.compile_structural(e)
|
162
|
+
rescue => ee
|
163
|
+
new_delayed << e
|
164
|
+
end
|
165
|
+
structs[ns][nom] -= [ nil ]
|
166
|
+
end
|
167
|
+
|
168
|
+
structs.each_pair do |ns, parts|
|
169
|
+
next unless possibilities[ns]
|
170
|
+
parts.each_pair do |nom, objs|
|
171
|
+
next unless possibilities[ns][nom]
|
172
|
+
opts = possibilities[ns][nom]
|
173
|
+
as = "@" + (opts[:as] || nom.to_s.pluralize).to_s
|
174
|
+
if opts[:storage].nil? || opts[:storage] == :array
|
175
|
+
self.instance_variable_set(as.to_sym, self.instance_variable_get(as.to_sym) + objs)
|
176
|
+
else
|
177
|
+
tgt = self.instance_variable_get(as.to_sym)
|
178
|
+
objs.each do |obj|
|
179
|
+
tgt[obj.send(opts[:key] || :name)] = obj
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
if (new_delayed - delayed).empty? && (delayed - new_delayed).empty?
|
186
|
+
delayed = []
|
187
|
+
else
|
188
|
+
delayed = new_delayed
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
118
194
|
end
|
119
195
|
end
|
120
196
|
end
|
data/lib/fabulator/structural.rb
CHANGED
@@ -3,6 +3,8 @@ module Fabulator
|
|
3
3
|
|
4
4
|
def initialize
|
5
5
|
@context = Fabulator::Expr::Context.new
|
6
|
+
self.init_attribute_storage
|
7
|
+
|
6
8
|
end
|
7
9
|
|
8
10
|
def compile_xml(xml, context = nil)
|
@@ -35,6 +37,9 @@ module Fabulator
|
|
35
37
|
@@structurals[self.name] ||= { }
|
36
38
|
@@structurals[self.name][ns] ||= { }
|
37
39
|
@@structurals[self.name][ns][nom.to_sym] = opts
|
40
|
+
self.module_eval {
|
41
|
+
attr_accessor (opts[:as] || nom.to_s.pluralize).to_sym
|
42
|
+
}
|
38
43
|
end
|
39
44
|
|
40
45
|
def self.contained_in(ns, nom, h = {})
|
@@ -43,7 +48,7 @@ module Fabulator
|
|
43
48
|
@@contained_in[ns] ||= { }
|
44
49
|
@@contained_in[ns][nom.to_sym] ||= { }
|
45
50
|
@@contained_in[ns][nom.to_sym][self.namespace] ||= { }
|
46
|
-
@@contained_in[ns][nom.to_sym][self.namespace][self.element.to_sym] =
|
51
|
+
@@contained_in[ns][nom.to_sym][self.namespace][self.element.to_sym] = { :as => :contained }.update(h)
|
47
52
|
end
|
48
53
|
|
49
54
|
def self.structurals
|
@@ -79,16 +84,20 @@ module Fabulator
|
|
79
84
|
|
80
85
|
|
81
86
|
protected
|
82
|
-
def setup(xml)
|
83
|
-
super
|
84
87
|
|
85
|
-
|
88
|
+
def init_attribute_storage
|
86
89
|
possibilities = self.class.structurals
|
87
90
|
|
88
91
|
if !possibilities.nil?
|
89
92
|
possibilities.each_pair do |ns, parts|
|
90
93
|
parts.each_pair do |nom, opts|
|
91
|
-
|
94
|
+
snom = (opts[:as] || nom.to_s.pluralize).to_s
|
95
|
+
as = "@" + snom
|
96
|
+
if !self.class.respond_to?(snom.to_sym)
|
97
|
+
self.class.module_eval {
|
98
|
+
attr_accessor snom.to_sym
|
99
|
+
}
|
100
|
+
end
|
92
101
|
if opts[:storage].nil? || opts[:storage] == :array
|
93
102
|
self.instance_variable_set(as.to_sym, [])
|
94
103
|
elsif opts[:storage] == :hash
|
@@ -96,7 +105,17 @@ module Fabulator
|
|
96
105
|
end
|
97
106
|
end
|
98
107
|
end
|
108
|
+
end
|
109
|
+
end
|
99
110
|
|
111
|
+
def setup(xml)
|
112
|
+
super
|
113
|
+
|
114
|
+
self.init_attribute_storage
|
115
|
+
|
116
|
+
possibilities = self.class.structurals
|
117
|
+
|
118
|
+
if !possibilities.nil?
|
100
119
|
structs = @context.compile_structurals(xml)
|
101
120
|
structs.each_pair do |ns, parts|
|
102
121
|
next unless possibilities[ns]
|
data/lib/fabulator/tag_lib.rb
CHANGED
@@ -8,6 +8,7 @@ module Fabulator
|
|
8
8
|
@@namespaces = {}
|
9
9
|
@@attributes = [ ]
|
10
10
|
@@last_description = nil
|
11
|
+
@@presentations = { }
|
11
12
|
@@types = { }
|
12
13
|
@@axes = { }
|
13
14
|
|
@@ -41,6 +42,9 @@ module Fabulator
|
|
41
42
|
def self.axes
|
42
43
|
@@axes
|
43
44
|
end
|
45
|
+
def self.presentations
|
46
|
+
@@presentations
|
47
|
+
end
|
44
48
|
|
45
49
|
def self.last_description=(x)
|
46
50
|
@@last_description = x
|
@@ -72,30 +76,24 @@ module Fabulator
|
|
72
76
|
def self.axes=(x)
|
73
77
|
@@axes = x
|
74
78
|
end
|
79
|
+
def self.presentations=(x)
|
80
|
+
@@presentations = x
|
81
|
+
end
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
def structural_class(nom)
|
84
|
+
Fabulator::TagLib.structural_classes[self.class.name][nom.to_sym]
|
85
|
+
end
|
79
86
|
|
80
87
|
def self.inherited(base)
|
81
88
|
base.extend(ClassMethods)
|
82
89
|
end
|
83
90
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
# def self.included(new_base)
|
88
|
-
# super
|
89
|
-
# new_base.action_descriptions.merge! self.action_descriptions
|
90
|
-
# new_base.function_descriptions.merge! self.function_descriptions
|
91
|
-
# new_base.function_args.merge! self.function_args
|
92
|
-
# new_base.types.merge! self.types
|
93
|
-
# end
|
94
|
-
# end
|
95
|
-
# end
|
91
|
+
def self.type_handler(t)
|
92
|
+
(@@types[t[0]][t[1].to_sym] rescue nil)
|
93
|
+
end
|
96
94
|
|
97
95
|
def self.find_op(t,o)
|
98
|
-
(
|
96
|
+
(self.type_handler(t).get_method(t + o.upcase) rescue nil)
|
99
97
|
end
|
100
98
|
|
101
99
|
# returns nil if no common type can be found
|
@@ -110,6 +108,7 @@ module Fabulator
|
|
110
108
|
# now group by types since we only need one of each type for unification
|
111
109
|
grouped = { }
|
112
110
|
ts.each do |t|
|
111
|
+
t = t.vtype.collect{ |i| i.to_s} unless t.is_a?(Array)
|
113
112
|
grouped[t.join('')] = t
|
114
113
|
end
|
115
114
|
|
@@ -121,96 +120,17 @@ module Fabulator
|
|
121
120
|
# until we unify all of them
|
122
121
|
t1 = grouped.pop
|
123
122
|
t2 = grouped.pop
|
124
|
-
|
123
|
+
t1_obj = self.type_handler(t1)
|
124
|
+
ut = t1_obj.unify_with_type(t2)
|
125
125
|
return nil if ut.nil?
|
126
126
|
self.unify_types([ ut[:t] ] + grouped)
|
127
127
|
end
|
128
128
|
|
129
129
|
def self.type_path(from, to)
|
130
130
|
return [] if from.nil? || to.nil? || from.join('') == to.join('')
|
131
|
-
|
132
|
-
return [] if
|
133
|
-
return
|
134
|
-
end
|
135
|
-
|
136
|
-
## TODO: allow unification with values as well so we can have
|
137
|
-
# conversions dependent on the value
|
138
|
-
# for example: strings that look like integers can convert to integers
|
139
|
-
def self._unify_types(t1, t2, ordered = false)
|
140
|
-
return nil if t1.nil? || t2.nil?
|
141
|
-
d1 = { t1.join('') => { :t => t1, :w => 1.0, :path => [ t1 ], :convert => [ ] } }
|
142
|
-
d2 = { t2.join('') => { :t => t2, :w => 1.0, :path => [ t2 ], :convert => [ ] } }
|
143
|
-
|
144
|
-
added = true
|
145
|
-
while added
|
146
|
-
added = false
|
147
|
-
[d1, d2].each do |d|
|
148
|
-
d.keys.each do |t|
|
149
|
-
if (@@types[d[t][:t][0]][d[t][:t][1]].has_key?(:to) rescue false)
|
150
|
-
@@types[d[t][:t][0]][d[t][:t][1]][:to].each do |conv|
|
151
|
-
w = d[t][:w] * conv[:weight]
|
152
|
-
conv_key = conv[:type].join('')
|
153
|
-
if d.has_key?(conv_key)
|
154
|
-
if d[conv_key][:w] < w
|
155
|
-
d[conv_key][:w] = w
|
156
|
-
d[conv_key][:path] = d[t][:path] + [ conv[:type] ]
|
157
|
-
d[conv_key][:convert] = d[t][:convert] + [ conv[:convert] ] - [nil]
|
158
|
-
end
|
159
|
-
else
|
160
|
-
d[conv_key] = {
|
161
|
-
:t => conv[:type],
|
162
|
-
:w => w,
|
163
|
-
:path => d[t][:path] + [ conv[:type] ],
|
164
|
-
:convert => d[t][:convert] + [ conv[:convert] ] - [ nil ]
|
165
|
-
}
|
166
|
-
added = true
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
# go through each type looking for :from
|
172
|
-
@@types.keys.each do |ns|
|
173
|
-
@@types[ns].each_pair do |ct, cd|
|
174
|
-
next if cd[:from].nil?
|
175
|
-
to_key = ns + ct
|
176
|
-
cd[:from].each do |conv|
|
177
|
-
next if conv[:type].nil?
|
178
|
-
from_key = conv[:type].join('')
|
179
|
-
next if !d.has_key?(from_key)
|
180
|
-
w = d[from_key][:w] * conv[:weight]
|
181
|
-
if d.has_key?(to_key)
|
182
|
-
if d[to_key][:w] < w
|
183
|
-
d[to_key][:w] = w
|
184
|
-
d[to_key][:path] = d[from_key][:path] + [ conv[:type] ]
|
185
|
-
d[to_key][:convert] = d[from_key][:convert] + [ conv[:convert] ] - [nil]
|
186
|
-
end
|
187
|
-
else
|
188
|
-
d[to_key] = {
|
189
|
-
:t => [ns, ct],
|
190
|
-
:w => w * 95 / 100, # favor to over from
|
191
|
-
:path => d[from_key][:path] + [ conv[:type] ],
|
192
|
-
:convert => d[from_key][:convert] + [ conv[:convert] ] - [ nil ]
|
193
|
-
}
|
194
|
-
added = true
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
r = self._select_type_path(d1, d2, t2, ordered)
|
201
|
-
return r unless r.nil?
|
202
|
-
end
|
203
|
-
return self._select_type_path(d1, d2, t2, ordered)
|
204
|
-
end
|
205
|
-
|
206
|
-
def self._select_type_path(d1, d2, t2, ordered)
|
207
|
-
common = d1.keys & d2.keys
|
208
|
-
if ordered && common.include?(t2.join(''))
|
209
|
-
return d1[t2.join('')]
|
210
|
-
elsif !common.empty?
|
211
|
-
return d1[common.sort_by{ |c| d1[c][:w] * d2[c][:w] / d1[c][:path].size / d2[c][:path].size }.reverse.first]
|
212
|
-
end
|
213
|
-
return nil
|
131
|
+
from_obj = self.type_handler(from)
|
132
|
+
return [] if from_obj.nil?
|
133
|
+
return from_obj.build_conversion_to(to)
|
214
134
|
end
|
215
135
|
|
216
136
|
def self.with_super(s, &block)
|
@@ -237,6 +157,10 @@ module Fabulator
|
|
237
157
|
end
|
238
158
|
end
|
239
159
|
|
160
|
+
def action_exists?(nom)
|
161
|
+
self.respond_to?("action:#{nom.to_s}")
|
162
|
+
end
|
163
|
+
|
240
164
|
def run_function(context, nom, args, depth=0)
|
241
165
|
ret = []
|
242
166
|
|
@@ -273,23 +197,28 @@ module Fabulator
|
|
273
197
|
end
|
274
198
|
rr
|
275
199
|
else
|
276
|
-
|
200
|
+
rt = self.function_return_type(nom)
|
201
|
+
if rt.nil?
|
202
|
+
context.root.anon_node(r) #, self.function_return_type(nom))
|
203
|
+
else
|
204
|
+
context.root.anon_node(r,rt)
|
205
|
+
end
|
277
206
|
end
|
278
207
|
}
|
279
208
|
ret.flatten
|
280
209
|
end
|
281
210
|
|
282
211
|
def function_return_type(name)
|
283
|
-
(self.function_descriptions[name][:returns] rescue nil)
|
212
|
+
(self.function_descriptions[name.to_sym][:returns] rescue nil)
|
284
213
|
end
|
285
214
|
|
286
215
|
def function_run_scaling(name)
|
287
|
-
(self.function_descriptions[name][:scaling] rescue nil)
|
216
|
+
(self.function_descriptions[name.to_sym][:scaling] rescue nil)
|
288
217
|
end
|
289
218
|
|
290
219
|
def function_run_type(name)
|
291
|
-
r = (self.function_descriptions[name][:type] rescue nil)
|
292
|
-
if r.nil? && !self.function_descriptions.has_key?(name)
|
220
|
+
r = (self.function_descriptions[name.to_sym][:type] rescue nil)
|
221
|
+
if r.nil? && !self.function_descriptions.has_key?(name.to_sym)
|
293
222
|
if name =~ /^consolidation:(.*)/
|
294
223
|
if function_run_scaling($1) != :flat
|
295
224
|
return :consolidation
|
@@ -330,6 +259,10 @@ module Fabulator
|
|
330
259
|
self.class.function_args hash
|
331
260
|
end
|
332
261
|
|
262
|
+
def presentation
|
263
|
+
self.class.presentation
|
264
|
+
end
|
265
|
+
|
333
266
|
module ClassMethods
|
334
267
|
def inherited(subclass)
|
335
268
|
subclass.action_descriptions.reverse_merge! self.action_descriptions
|
@@ -353,6 +286,10 @@ module Fabulator
|
|
353
286
|
Fabulator::TagLib.namespaces[ns] = self.new
|
354
287
|
end
|
355
288
|
|
289
|
+
def presentation
|
290
|
+
Fabulator::TagLib.presentations[self.name] ||= Fabulator::TagLib::Presentations.new
|
291
|
+
end
|
292
|
+
|
356
293
|
def register_attribute(a, options = {})
|
357
294
|
ns = nil
|
358
295
|
Fabulator::TagLib.namespaces.each_pair do |k,v|
|
@@ -363,7 +300,17 @@ module Fabulator
|
|
363
300
|
Fabulator::TagLib.attributes << [ ns, a, options ]
|
364
301
|
end
|
365
302
|
|
366
|
-
def
|
303
|
+
def get_type(nom)
|
304
|
+
ns = nil
|
305
|
+
Fabulator::TagLib.namespaces.each_pair do |k,v|
|
306
|
+
if v.is_a?(self)
|
307
|
+
ns = k
|
308
|
+
end
|
309
|
+
end
|
310
|
+
Fabulator::TagLib.types[ns][nom.to_sym]
|
311
|
+
end
|
312
|
+
|
313
|
+
def has_type(nom, &block)
|
367
314
|
ns = nil
|
368
315
|
Fabulator::TagLib.namespaces.each_pair do |k,v|
|
369
316
|
if v.is_a?(self)
|
@@ -371,12 +318,14 @@ module Fabulator
|
|
371
318
|
end
|
372
319
|
end
|
373
320
|
Fabulator::TagLib.types[ns] ||= {}
|
374
|
-
Fabulator::TagLib.types[ns][nom]
|
321
|
+
Fabulator::TagLib.types[ns][nom.to_sym] ||= Fabulator::TagLib::Type.new([ns, nom.to_sym])
|
375
322
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
323
|
+
if block
|
324
|
+
Fabulator::TagLib.types[ns][nom.to_sym].instance_eval &block
|
325
|
+
end
|
326
|
+
|
327
|
+
mapping nom do |ctx, i|
|
328
|
+
ctx.with_root(i).to([ ns, nom.to_s ]).root
|
380
329
|
end
|
381
330
|
end
|
382
331
|
|
@@ -393,10 +342,10 @@ module Fabulator
|
|
393
342
|
end
|
394
343
|
|
395
344
|
def action(name, klass = nil, &block)
|
396
|
-
self.action_descriptions[name] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
345
|
+
self.action_descriptions[name.to_sym] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
397
346
|
Fabulator::TagLib.last_description = nil
|
398
347
|
if block
|
399
|
-
define_method("action:#{name}",
|
348
|
+
define_method("action:#{name.to_s}", block)
|
400
349
|
elsif !klass.nil?
|
401
350
|
action(name) { |e,c|
|
402
351
|
r = klass.new
|
@@ -407,10 +356,10 @@ module Fabulator
|
|
407
356
|
end
|
408
357
|
|
409
358
|
def structural(name, klass = nil, &block)
|
410
|
-
self.structural_descriptions[name] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
359
|
+
self.structural_descriptions[name.to_sym] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
411
360
|
Fabulator::TagLib.last_description = nil
|
412
361
|
if block
|
413
|
-
define_method("structural:#{name}",
|
362
|
+
define_method("structural:#{name.to_s}", block)
|
414
363
|
elsif !klass.nil?
|
415
364
|
structural(name) { |e,c|
|
416
365
|
r = klass.new
|
@@ -423,21 +372,21 @@ module Fabulator
|
|
423
372
|
end
|
424
373
|
|
425
374
|
def function(name, returns = nil, takes = nil, &block)
|
426
|
-
self.function_descriptions[name] = { :returns => returns, :takes => takes }
|
427
|
-
self.function_descriptions[name][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
375
|
+
self.function_descriptions[name.to_sym] = { :returns => returns, :takes => takes }
|
376
|
+
self.function_descriptions[name.to_sym][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
428
377
|
#self.function_args[name] = { :return => returns, :takes => takes }
|
429
378
|
Fabulator::TagLib.last_description = nil
|
430
379
|
define_method("fctn:#{name}", &block)
|
431
380
|
end
|
432
381
|
|
433
382
|
def reduction(name, opts = {}, &block)
|
434
|
-
self.function_descriptions[name] = { :type => :reduction }.merge(opts)
|
435
|
-
self.function_descriptions[name][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
383
|
+
self.function_descriptions[name.to_sym] = { :type => :reduction }.merge(opts)
|
384
|
+
self.function_descriptions[name.to_sym][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
436
385
|
Fabulator::TagLib.last_description = nil
|
437
386
|
define_method("fctn:#{name}", &block)
|
438
|
-
cons = self.function_descriptions[name][:consolidation]
|
387
|
+
cons = self.function_descriptions[name.to_sym][:consolidation]
|
439
388
|
if !cons.nil?
|
440
|
-
Fabulator::TagLib.last_description = self.function_descriptions[name][:description]
|
389
|
+
Fabulator::TagLib.last_description = self.function_descriptions[name.to_sym][:description]
|
441
390
|
consolidation name do |ctx, args|
|
442
391
|
send "fctn:#{cons}", ctx, args
|
443
392
|
end
|
@@ -445,17 +394,18 @@ module Fabulator
|
|
445
394
|
end
|
446
395
|
|
447
396
|
def consolidation(name, opts = {}, &block)
|
448
|
-
self.function_descriptions[name] = { :type => :consolidation }.merge(opts)
|
449
|
-
self.function_descriptions[name][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
397
|
+
self.function_descriptions[name.to_sym] = { :type => :consolidation }.merge(opts)
|
398
|
+
self.function_descriptions[name.to_sym][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
450
399
|
Fabulator::TagLib.last_description = nil
|
451
400
|
define_method("fctn:consolidation:#{name}", &block)
|
452
401
|
end
|
453
402
|
|
454
403
|
def mapping(name, opts = {}, &block)
|
404
|
+
name = name.to_sym
|
455
405
|
self.function_descriptions[name] = { :type => :mapping }.merge(opts)
|
456
406
|
self.function_descriptions[name][:description] = Fabulator::TagLib.last_description if Fabulator::TagLib.last_description
|
457
407
|
Fabulator::TagLib.last_description = nil
|
458
|
-
define_method("fctn:#{name}", &block)
|
408
|
+
define_method("fctn:#{name.to_s}", &block)
|
459
409
|
end
|
460
410
|
|
461
411
|
def function_decl(name, expr, ns)
|
@@ -481,6 +431,10 @@ module Fabulator
|
|
481
431
|
def constraint(name, &block)
|
482
432
|
define_method("constraint:#{name}", &block)
|
483
433
|
end
|
434
|
+
|
435
|
+
def presentations(&block)
|
436
|
+
self.presentation.instance_eval &block
|
437
|
+
end
|
484
438
|
end
|
485
439
|
|
486
440
|
module Util
|