gloo 1.4.2 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/gloo.gemspec +0 -2
- data/lib/VERSION +1 -1
- data/lib/dependencies.rb +4 -4
- data/lib/gloo/app/args.rb +112 -0
- data/lib/gloo/app/engine.rb +247 -0
- data/lib/gloo/app/engine_context.rb +25 -0
- data/lib/gloo/app/info.rb +20 -3
- data/lib/gloo/app/log.rb +73 -1
- data/lib/gloo/app/mode.rb +27 -0
- data/lib/gloo/app/platform.rb +8 -1
- data/lib/gloo/app/settings.rb +202 -0
- data/lib/gloo/convert/converter.rb +42 -0
- data/lib/gloo/convert/string_to_date.rb +21 -0
- data/lib/gloo/convert/string_to_datetime.rb +21 -0
- data/lib/gloo/convert/string_to_decimal.rb +20 -0
- data/lib/gloo/convert/string_to_integer.rb +20 -0
- data/lib/gloo/convert/string_to_time.rb +21 -0
- data/lib/gloo/core/baseo.rb +31 -0
- data/lib/gloo/core/dictionary.rb +245 -0
- data/lib/gloo/core/error.rb +61 -0
- data/lib/gloo/core/event_manager.rb +45 -0
- data/lib/gloo/core/factory.rb +211 -0
- data/lib/gloo/core/gloo_system.rb +267 -0
- data/lib/gloo/core/heap.rb +53 -0
- data/lib/gloo/core/here.rb +36 -0
- data/lib/gloo/core/it.rb +36 -0
- data/lib/gloo/core/literal.rb +30 -0
- data/lib/gloo/core/obj.rb +318 -0
- data/lib/gloo/core/obj_finder.rb +30 -0
- data/lib/gloo/core/op.rb +40 -0
- data/lib/gloo/core/parser.rb +60 -0
- data/lib/gloo/core/pn.rb +212 -0
- data/lib/gloo/core/tokens.rb +165 -0
- data/lib/gloo/core/verb.rb +87 -0
- data/lib/gloo/exec/action.rb +48 -0
- data/lib/gloo/exec/dispatch.rb +40 -0
- data/lib/gloo/exec/exec_env.rb +75 -0
- data/lib/gloo/exec/runner.rb +45 -0
- data/lib/gloo/exec/script.rb +50 -0
- data/lib/gloo/exec/stack.rb +79 -0
- data/lib/gloo/expr/expression.rb +119 -0
- data/lib/gloo/expr/l_boolean.rb +36 -0
- data/lib/gloo/expr/l_decimal.rb +39 -0
- data/lib/gloo/expr/l_integer.rb +37 -0
- data/lib/gloo/expr/l_string.rb +58 -0
- data/lib/gloo/expr/op_div.rb +22 -0
- data/lib/gloo/expr/op_minus.rb +22 -0
- data/lib/gloo/expr/op_mult.rb +22 -0
- data/lib/gloo/expr/op_plus.rb +24 -0
- data/lib/gloo/objs/basic/alias.rb +78 -0
- data/lib/gloo/objs/basic/boolean.rb +120 -0
- data/lib/gloo/objs/basic/container.rb +65 -0
- data/lib/gloo/objs/basic/decimal.rb +76 -0
- data/lib/gloo/objs/basic/integer.rb +73 -0
- data/lib/gloo/objs/basic/script.rb +99 -0
- data/lib/gloo/objs/basic/string.rb +77 -0
- data/lib/gloo/objs/basic/text.rb +79 -0
- data/lib/gloo/objs/basic/untyped.rb +41 -0
- data/lib/gloo/objs/cli/banner.rb +1 -1
- data/lib/gloo/objs/cli/bar.rb +3 -3
- data/lib/gloo/objs/cli/colorize.rb +1 -1
- data/lib/gloo/objs/cli/confirm.rb +1 -1
- data/lib/gloo/objs/cli/menu.rb +6 -6
- data/lib/gloo/objs/cli/menu_item.rb +1 -1
- data/lib/gloo/objs/cli/pastel.rb +1 -1
- data/lib/gloo/objs/cli/prompt.rb +1 -1
- data/lib/gloo/objs/cli/select.rb +2 -2
- data/lib/gloo/objs/ctrl/each.rb +279 -0
- data/lib/gloo/objs/ctrl/repeat.rb +108 -0
- data/lib/gloo/objs/data/markdown.rb +79 -0
- data/lib/gloo/objs/data/mysql.rb +5 -5
- data/lib/gloo/objs/data/query.rb +4 -4
- data/lib/gloo/objs/data/sqlite.rb +1 -1
- data/lib/gloo/objs/data/table.rb +112 -0
- data/lib/gloo/objs/dev/git.rb +2 -2
- data/lib/gloo/objs/dev/stats.rb +4 -4
- data/lib/gloo/objs/dt/date.rb +65 -0
- data/lib/gloo/objs/dt/datetime.rb +120 -0
- data/lib/gloo/objs/dt/dt_tools.rb +100 -0
- data/lib/gloo/objs/dt/time.rb +65 -0
- data/lib/gloo/objs/ror/erb.rb +116 -0
- data/lib/gloo/objs/ror/eval.rb +107 -0
- data/lib/gloo/objs/snd/play.rb +1 -1
- data/lib/gloo/objs/snd/say.rb +1 -1
- data/lib/gloo/objs/system/file_handle.rb +4 -4
- data/lib/gloo/objs/system/ssh_exec.rb +1 -1
- data/lib/gloo/objs/system/system.rb +1 -1
- data/lib/gloo/objs/web/http_get.rb +159 -0
- data/lib/gloo/objs/web/http_post.rb +183 -0
- data/lib/gloo/objs/web/json.rb +135 -0
- data/lib/gloo/objs/web/slack.rb +130 -0
- data/lib/gloo/objs/web/teams.rb +117 -0
- data/lib/gloo/objs/web/uri.rb +148 -0
- data/lib/gloo/persist/disc_mech.rb +87 -0
- data/lib/gloo/persist/file_loader.rb +193 -0
- data/lib/gloo/persist/file_saver.rb +51 -0
- data/lib/gloo/persist/file_storage.rb +46 -0
- data/lib/gloo/persist/line_splitter.rb +81 -0
- data/lib/gloo/persist/persist_man.rb +153 -0
- data/lib/gloo/utils/format.rb +21 -0
- data/lib/gloo/utils/stats.rb +206 -0
- data/lib/gloo/utils/words.rb +19 -0
- data/lib/gloo/verbs/alert.rb +2 -2
- data/lib/gloo/verbs/beep.rb +1 -1
- data/lib/gloo/verbs/cls.rb +1 -1
- data/lib/gloo/verbs/context.rb +62 -0
- data/lib/gloo/verbs/create.rb +68 -0
- data/lib/gloo/verbs/execute.rb +56 -0
- data/lib/gloo/verbs/files.rb +49 -0
- data/lib/gloo/verbs/help.rb +1 -1
- data/lib/gloo/verbs/if.rb +92 -0
- data/lib/gloo/verbs/list.rb +98 -0
- data/lib/gloo/verbs/load.rb +45 -0
- data/lib/gloo/verbs/move.rb +89 -0
- data/lib/gloo/verbs/put.rb +94 -0
- data/lib/gloo/verbs/quit.rb +40 -0
- data/lib/gloo/verbs/reload.rb +43 -0
- data/lib/gloo/verbs/run.rb +75 -0
- data/lib/gloo/verbs/save.rb +39 -0
- data/lib/gloo/verbs/show.rb +63 -0
- data/lib/gloo/verbs/tell.rb +80 -0
- data/lib/gloo/verbs/unless.rb +92 -0
- data/lib/gloo/verbs/unload.rb +46 -0
- data/lib/gloo/verbs/version.rb +3 -3
- data/lib/gloo/verbs/wait.rb +42 -0
- data/lib/gloo.rb +2 -2
- data/lib/run.rb +2 -2
- metadata +97 -22
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An data/value object.
|
|
5
|
+
# Derives from the Baseo object. Is not a verb.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Core
|
|
10
|
+
class Obj < Baseo
|
|
11
|
+
|
|
12
|
+
attr_accessor :value
|
|
13
|
+
attr_reader :children, :parent
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Set up the object.
|
|
17
|
+
#
|
|
18
|
+
def initialize( engine )
|
|
19
|
+
@engine = engine
|
|
20
|
+
@value = ''
|
|
21
|
+
@children = []
|
|
22
|
+
@parent = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Register object types when they are loaded.
|
|
27
|
+
#
|
|
28
|
+
def self.inherited( subclass )
|
|
29
|
+
Dictionary.instance.register_obj( subclass )
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# The name of the object type.
|
|
34
|
+
#
|
|
35
|
+
def self.typename
|
|
36
|
+
raise 'this method should be overriden'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# The object type, suitable for display.
|
|
41
|
+
#
|
|
42
|
+
def type_display
|
|
43
|
+
return self.class.typename
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Set the parent for the object.
|
|
48
|
+
#
|
|
49
|
+
def set_parent( obj )
|
|
50
|
+
@parent = obj
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Is this the root object?
|
|
55
|
+
#
|
|
56
|
+
def root?
|
|
57
|
+
return false if @parent
|
|
58
|
+
return false unless name.downcase == 'root'
|
|
59
|
+
|
|
60
|
+
return true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Can this object be created?
|
|
64
|
+
# This is true by default and only false for some special cases
|
|
65
|
+
# such as the System object.
|
|
66
|
+
def self.can_create?
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Get the path and name to this object.
|
|
72
|
+
#
|
|
73
|
+
def pn
|
|
74
|
+
str = self.name
|
|
75
|
+
p = self.parent
|
|
76
|
+
while p && !p.root?
|
|
77
|
+
str = "#{p.name}.#{str}"
|
|
78
|
+
p = p.parent
|
|
79
|
+
end
|
|
80
|
+
return str
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Generic function to get display value.
|
|
85
|
+
# Can be used for debugging, etc.
|
|
86
|
+
#
|
|
87
|
+
def display_value
|
|
88
|
+
return self.pn
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# ---------------------------------------------------------------------
|
|
92
|
+
# Value
|
|
93
|
+
# ---------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Set the value with any necessary type conversions.
|
|
97
|
+
#
|
|
98
|
+
def set_value( new_value )
|
|
99
|
+
self.value = new_value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Get the value for display purposes.
|
|
104
|
+
#
|
|
105
|
+
def value_display
|
|
106
|
+
return self.value.to_s
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# Does this object support multi-line values?
|
|
111
|
+
# Initially only true for scripts.
|
|
112
|
+
#
|
|
113
|
+
def multiline_value?
|
|
114
|
+
return false
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# Is the value a String?
|
|
119
|
+
#
|
|
120
|
+
def value_string?
|
|
121
|
+
return self.value.is_a? String
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#
|
|
125
|
+
# Is the value an Array?
|
|
126
|
+
#
|
|
127
|
+
def value_is_array?
|
|
128
|
+
return self.value.is_a? Array
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# Is the value a blank string?
|
|
133
|
+
#
|
|
134
|
+
def value_is_blank?
|
|
135
|
+
return true if value.nil?
|
|
136
|
+
|
|
137
|
+
return self.value.to_s.strip.empty?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# ---------------------------------------------------------------------
|
|
141
|
+
# Children
|
|
142
|
+
# ---------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
#
|
|
145
|
+
# Find a child of the given name.
|
|
146
|
+
# If found, return it. If not found create it.
|
|
147
|
+
#
|
|
148
|
+
def find_add_child( name, type )
|
|
149
|
+
child = self.find_child( name )
|
|
150
|
+
return child if child
|
|
151
|
+
|
|
152
|
+
params = { :name => name,
|
|
153
|
+
:type => type,
|
|
154
|
+
:value => nil,
|
|
155
|
+
:parent => self }
|
|
156
|
+
return @engine.factory.create params
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
# Add a child object to the container.
|
|
161
|
+
#
|
|
162
|
+
def add_child( obj )
|
|
163
|
+
@children << obj
|
|
164
|
+
obj.set_parent self
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Get the number of children.
|
|
169
|
+
#
|
|
170
|
+
def child_count
|
|
171
|
+
return @children.count
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# Does this object contain an object with the given name?
|
|
176
|
+
#
|
|
177
|
+
def contains_child?( name )
|
|
178
|
+
@children.each do |o|
|
|
179
|
+
return true if name.downcase == o.name.downcase
|
|
180
|
+
end
|
|
181
|
+
return false
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# Find a child object with the given name.
|
|
186
|
+
#
|
|
187
|
+
def find_child( name )
|
|
188
|
+
if name.end_with?( Gloo::Objs::Alias::ALIAS_REFERENCE )
|
|
189
|
+
name = name[ 0..-2 ]
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
@children.each do |o|
|
|
193
|
+
return o if name.downcase == o.name.downcase
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
if self.type_display == Gloo::Objs::Alias.typename
|
|
197
|
+
ln = Gloo::Core::Pn.new( @engine, self.value )
|
|
198
|
+
redirect = ln.resolve
|
|
199
|
+
return redirect.find_child( name )
|
|
200
|
+
end
|
|
201
|
+
return nil
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
#
|
|
205
|
+
# Delete all children from the container.
|
|
206
|
+
#
|
|
207
|
+
def delete_children
|
|
208
|
+
@children.reverse.each do |o|
|
|
209
|
+
self.remove_child o
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# Remove the object from the children collection.
|
|
215
|
+
#
|
|
216
|
+
def remove_child( obj )
|
|
217
|
+
@children.delete obj
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Does this object have children to add when an object
|
|
221
|
+
# is created in interactive mode?
|
|
222
|
+
# This does not apply during obj load, etc.
|
|
223
|
+
def add_children_on_create?
|
|
224
|
+
return false
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Add children to this object.
|
|
228
|
+
# This is used by containers to add children needed
|
|
229
|
+
# for default configurations.
|
|
230
|
+
def add_default_children
|
|
231
|
+
# Override this.
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# ---------------------------------------------------------------------
|
|
235
|
+
# Messages
|
|
236
|
+
# ---------------------------------------------------------------------
|
|
237
|
+
|
|
238
|
+
#
|
|
239
|
+
# Get a list of message names that this object receives.
|
|
240
|
+
#
|
|
241
|
+
def self.messages
|
|
242
|
+
return %w[reload unload]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# Can this object receive a message?
|
|
247
|
+
#
|
|
248
|
+
def can_receive_message?( msg )
|
|
249
|
+
msgs = self.class.messages
|
|
250
|
+
return msgs.include?( msg.strip.downcase )
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
#
|
|
254
|
+
# Sent this object the given message.
|
|
255
|
+
#
|
|
256
|
+
def send_message( msg, params = nil )
|
|
257
|
+
@params = params
|
|
258
|
+
return self.dispatch msg if self.can_receive_message? msg
|
|
259
|
+
|
|
260
|
+
@engine.log.error "Object #{self.name} cannot receive message #{msg}"
|
|
261
|
+
return false
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
#
|
|
265
|
+
# Dispatch the message to the object.
|
|
266
|
+
#
|
|
267
|
+
def dispatch( msg )
|
|
268
|
+
o = "msg_#{msg}"
|
|
269
|
+
if self.respond_to? o
|
|
270
|
+
self.public_send( o )
|
|
271
|
+
return true
|
|
272
|
+
else
|
|
273
|
+
@engine.log.error "Message #{msg} not implemented"
|
|
274
|
+
return false
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
#
|
|
279
|
+
# Send the object the unload message.
|
|
280
|
+
#
|
|
281
|
+
def msg_unload
|
|
282
|
+
if self.root?
|
|
283
|
+
@engine.log.error 'Cannot unload the root object.'
|
|
284
|
+
return
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
@engine.event_manager.on_unload self
|
|
288
|
+
@engine.heap.unload self
|
|
289
|
+
@engine.persist_man.unload self
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
#
|
|
293
|
+
# Send the object the reload message.
|
|
294
|
+
# Note that this will only work for objects with file assoications.
|
|
295
|
+
#
|
|
296
|
+
def msg_reload
|
|
297
|
+
if self.root?
|
|
298
|
+
@engine.log.error 'Cannot reload the root object.'
|
|
299
|
+
return
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
@engine.persist_man.reload self
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# ---------------------------------------------------------------------
|
|
306
|
+
# Help
|
|
307
|
+
# ---------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
#
|
|
310
|
+
# Get help for this object.
|
|
311
|
+
#
|
|
312
|
+
def self.help
|
|
313
|
+
return 'No help found.'
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Utility used to find objects.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Gloo
|
|
8
|
+
module Core
|
|
9
|
+
class ObjFinder
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Find all objects in the given container that have
|
|
13
|
+
# the given name.
|
|
14
|
+
# If the container isn't provided, root will be used.
|
|
15
|
+
#
|
|
16
|
+
def self.by_name( engine, name, container = nil )
|
|
17
|
+
container = engine.heap.root if container.nil?
|
|
18
|
+
arr = []
|
|
19
|
+
|
|
20
|
+
container.children.each do |o|
|
|
21
|
+
arr << o if o.name == name
|
|
22
|
+
arr += by_name( engine, name, o ) if o.child_count.positive?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
return arr
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/gloo/core/op.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An Operator; part of an expression.
|
|
5
|
+
# A static helper class.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Core
|
|
10
|
+
class Op
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Is the token an operator?
|
|
14
|
+
#
|
|
15
|
+
def self.op?( token )
|
|
16
|
+
return [ '+', '-', '*', '/' ].include?( token.strip )
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Create the operator for the given token.
|
|
21
|
+
#
|
|
22
|
+
def self.create_op( token )
|
|
23
|
+
return Gloo::Expr::OpMinus.new if token == '-'
|
|
24
|
+
return Gloo::Expr::OpMult.new if token == '*'
|
|
25
|
+
return Gloo::Expr::OpDiv.new if token == '/'
|
|
26
|
+
return Gloo::Expr::OpPlus.new if token == '+'
|
|
27
|
+
|
|
28
|
+
return default_op
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Get the default operator (+).
|
|
33
|
+
#
|
|
34
|
+
def self.default_op
|
|
35
|
+
return Gloo::Expr::OpPlus.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# The Parser.
|
|
5
|
+
# Can parse single line commands or files.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Core
|
|
10
|
+
class Parser
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Set up the parser.
|
|
14
|
+
#
|
|
15
|
+
def initialize( engine )
|
|
16
|
+
@engine = engine
|
|
17
|
+
@engine.log.debug 'parser intialized...'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Parse a command from the immediate execution context.
|
|
22
|
+
#
|
|
23
|
+
def parse_immediate( cmd )
|
|
24
|
+
cmd, params = split_params cmd
|
|
25
|
+
params = Gloo::Core::Tokens.new( params ) if params
|
|
26
|
+
tokens = Gloo::Core::Tokens.new( cmd )
|
|
27
|
+
dic = Gloo::Core::Dictionary.instance
|
|
28
|
+
verb = dic.find_verb( tokens.verb )
|
|
29
|
+
return verb.new( @engine, tokens, params ) if verb
|
|
30
|
+
|
|
31
|
+
@engine.log.error "Verb '#{tokens.verb}' was not found."
|
|
32
|
+
return nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# If additional params were provided, split them out
|
|
37
|
+
# from the token list.
|
|
38
|
+
#
|
|
39
|
+
def split_params( cmd )
|
|
40
|
+
params = nil
|
|
41
|
+
i = cmd.rindex( '(' )
|
|
42
|
+
if i && cmd.strip.end_with?( ')' )
|
|
43
|
+
pstr = cmd[ i + 1..-1 ]
|
|
44
|
+
params = pstr.strip[ 0..-2 ] if pstr
|
|
45
|
+
cmd = cmd[ 0, i - 1 ]
|
|
46
|
+
end
|
|
47
|
+
return cmd, params
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# Parse a command and then run it if it parsed correctly.
|
|
52
|
+
#
|
|
53
|
+
def run( cmd )
|
|
54
|
+
v = parse_immediate( cmd )
|
|
55
|
+
Gloo::Exec::Runner.go( @engine, v ) if v
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/gloo/core/pn.rb
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An object path name.
|
|
5
|
+
# Path and name elements are separated by periods.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Core
|
|
10
|
+
class Pn < Baseo
|
|
11
|
+
|
|
12
|
+
ROOT = 'root'.freeze
|
|
13
|
+
IT = 'it'.freeze
|
|
14
|
+
ERROR = 'error'.freeze
|
|
15
|
+
CONTEXT = '@'.freeze
|
|
16
|
+
|
|
17
|
+
attr_reader :src, :elements
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Set up the object given a source string,
|
|
21
|
+
# ie: the full path and name.
|
|
22
|
+
#
|
|
23
|
+
def initialize( engine, src )
|
|
24
|
+
@engine = engine
|
|
25
|
+
set_to src
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Reference to the root object path.
|
|
30
|
+
#
|
|
31
|
+
def self.root( engine )
|
|
32
|
+
return Pn.new( engine, ROOT )
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Reference to it.
|
|
37
|
+
#
|
|
38
|
+
def self.it( engine )
|
|
39
|
+
return Pn.new( engine, IT )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
# Reference to the error message.
|
|
44
|
+
#
|
|
45
|
+
def self.error( engine )
|
|
46
|
+
return Pn.new( engine, ERROR )
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Does the pathname reference refer to the root?
|
|
51
|
+
#
|
|
52
|
+
def root?
|
|
53
|
+
return @src.downcase == ROOT
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# Does the pathname reference refer to it?
|
|
58
|
+
#
|
|
59
|
+
def it?
|
|
60
|
+
return @src.downcase == IT
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Does the pathname reference refer to error?
|
|
65
|
+
#
|
|
66
|
+
def error?
|
|
67
|
+
return @src.downcase == ERROR
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Does the pathname reference refer to the gloo system object?
|
|
72
|
+
#
|
|
73
|
+
def gloo_sys?
|
|
74
|
+
return false unless @elements&.count&.positive?
|
|
75
|
+
|
|
76
|
+
o = @elements.first.downcase
|
|
77
|
+
return true if o == Gloo::Core::GlooSystem.typename
|
|
78
|
+
return true if o == Gloo::Core::GlooSystem.short_typename
|
|
79
|
+
|
|
80
|
+
return false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Get the string representation of the pathname.
|
|
85
|
+
#
|
|
86
|
+
def to_s
|
|
87
|
+
return @src
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Set the object pathname to the given value.
|
|
92
|
+
#
|
|
93
|
+
def set_to( value )
|
|
94
|
+
@src = value.nil? ? nil : value.strip
|
|
95
|
+
@elements = @src.nil? ? [] : @src.split( '.' )
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Convert the raw string to a list of segments.
|
|
100
|
+
#
|
|
101
|
+
def segments
|
|
102
|
+
return @elements
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# Get the name element.
|
|
107
|
+
#
|
|
108
|
+
def name
|
|
109
|
+
return '' unless self.named?
|
|
110
|
+
|
|
111
|
+
return @elements.last
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#
|
|
115
|
+
# Does the value include path elements?
|
|
116
|
+
#
|
|
117
|
+
def named?
|
|
118
|
+
return @elements.count.positive?
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
#
|
|
122
|
+
# Does the value include a name?
|
|
123
|
+
#
|
|
124
|
+
def includes_path?
|
|
125
|
+
return @elements.count > 1
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Does the path start with the context?
|
|
130
|
+
#
|
|
131
|
+
def includes_context?
|
|
132
|
+
return @src.start_with?( "#{CONTEXT}." )
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Expand the context so we have the full path.
|
|
137
|
+
#
|
|
138
|
+
def expand_context
|
|
139
|
+
# return unless @engine.heap.context
|
|
140
|
+
self.set_to( "#{@engine.heap.context}#{@src[1..-1]}" )
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
#
|
|
144
|
+
# Get the parent that contains the object referenced.
|
|
145
|
+
#
|
|
146
|
+
def get_parent
|
|
147
|
+
o = @engine.heap.root
|
|
148
|
+
|
|
149
|
+
if self.includes_path?
|
|
150
|
+
@elements[ 0..-2 ].each do |e|
|
|
151
|
+
o = o.find_child( e )
|
|
152
|
+
if o.nil?
|
|
153
|
+
@engine.log.error "Object '#{e}' was not found."
|
|
154
|
+
return nil
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
return o
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
#
|
|
163
|
+
# Does the object at the path exist?
|
|
164
|
+
#
|
|
165
|
+
def exists?
|
|
166
|
+
return true if self.root?
|
|
167
|
+
return true if self.it?
|
|
168
|
+
return true if self.error?
|
|
169
|
+
|
|
170
|
+
parent = self.get_parent
|
|
171
|
+
return false unless parent
|
|
172
|
+
|
|
173
|
+
return parent.contains_child? name
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
#
|
|
177
|
+
# Is the reference to a color?
|
|
178
|
+
#
|
|
179
|
+
def named_color?
|
|
180
|
+
colors = %w[red blue green white black yellow]
|
|
181
|
+
return true if colors.include?( @src.downcase )
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# Resolve the pathname reference.
|
|
186
|
+
# Find the object referenced or return nil if it is not found.
|
|
187
|
+
#
|
|
188
|
+
def resolve
|
|
189
|
+
return @engine.heap.root if self.root?
|
|
190
|
+
return @engine.heap.it if self.it?
|
|
191
|
+
return @engine.heap.error if self.error?
|
|
192
|
+
return Gloo::Core::GlooSystem.new(
|
|
193
|
+
@engine, self ) if self.gloo_sys?
|
|
194
|
+
|
|
195
|
+
if Here.includes_here_ref?( @elements )
|
|
196
|
+
Here.expand_here( @engine, self )
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
if self.includes_context?
|
|
200
|
+
expand_context
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
parent = self.get_parent
|
|
204
|
+
return nil unless parent
|
|
205
|
+
|
|
206
|
+
obj = parent.find_child( self.name )
|
|
207
|
+
return Gloo::Objs::Alias.resolve_alias( @engine, obj, self.src )
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|