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,165 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An ordered list of tokens.
|
|
5
|
+
# The list of tokens makes up a command.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Core
|
|
10
|
+
class Tokens
|
|
11
|
+
|
|
12
|
+
attr_reader :cmd, :tokens
|
|
13
|
+
|
|
14
|
+
# ---------------------------------------------------------------------
|
|
15
|
+
# Constructor
|
|
16
|
+
# ---------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Set up the tokens.
|
|
20
|
+
# The command string is parsed into tokens during creation.
|
|
21
|
+
#
|
|
22
|
+
def initialize( cmd_string )
|
|
23
|
+
@cmd = cmd_string
|
|
24
|
+
@tokens = []
|
|
25
|
+
tokenize @cmd
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------
|
|
29
|
+
# Public functions
|
|
30
|
+
# ---------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Get the number of tokens
|
|
34
|
+
#
|
|
35
|
+
def token_count
|
|
36
|
+
return @tokens.size
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Get the verb (the first word)
|
|
41
|
+
#
|
|
42
|
+
def verb
|
|
43
|
+
return first
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Get all tokens except the first.
|
|
48
|
+
#
|
|
49
|
+
def params
|
|
50
|
+
return @tokens[ 1..-1 ]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Get the first token.
|
|
55
|
+
#
|
|
56
|
+
def first
|
|
57
|
+
return @tokens.first if @tokens
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Get the last token.
|
|
62
|
+
#
|
|
63
|
+
def last
|
|
64
|
+
return @tokens.last if @tokens
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Get the second token.
|
|
69
|
+
#
|
|
70
|
+
def second
|
|
71
|
+
return @tokens[ 1 ] if @tokens&.size&.positive?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# Get the token at the the requested index.
|
|
76
|
+
#
|
|
77
|
+
def at( index )
|
|
78
|
+
return @tokens[ index ] if @tokens && @tokens.size >= index
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Get the index of the given token.
|
|
83
|
+
#
|
|
84
|
+
def index_of( token )
|
|
85
|
+
return nil unless @tokens
|
|
86
|
+
|
|
87
|
+
return @tokens.find_index { |o| o.casecmp( token ).zero? }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Get the list of tokens after the given token
|
|
92
|
+
#
|
|
93
|
+
def tokens_after( token )
|
|
94
|
+
i = index_of token
|
|
95
|
+
return @tokens[ i + 1..-1 ] if i && @tokens && @tokens.size > ( i + 1 )
|
|
96
|
+
|
|
97
|
+
return nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# Get the expression after the given token
|
|
102
|
+
#
|
|
103
|
+
def expr_after( token )
|
|
104
|
+
str = ''
|
|
105
|
+
tokens_after( token ).each do |t|
|
|
106
|
+
str << ' ' unless str.empty?
|
|
107
|
+
str << t.to_s
|
|
108
|
+
end
|
|
109
|
+
return str
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
# Get the item after a given token.
|
|
114
|
+
#
|
|
115
|
+
def after_token( token )
|
|
116
|
+
i = index_of token
|
|
117
|
+
return @tokens[ i + 1 ] if i && @tokens && @tokens.size > ( i + 1 )
|
|
118
|
+
|
|
119
|
+
return nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Get the item after a given token.
|
|
124
|
+
#
|
|
125
|
+
def before_token( token )
|
|
126
|
+
i = index_of token
|
|
127
|
+
return @tokens[ 0..i - 1 ] if i && @tokens && @tokens.size >= i
|
|
128
|
+
|
|
129
|
+
return nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# ---------------------------------------------------------------------
|
|
133
|
+
# Private functions
|
|
134
|
+
# ---------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
# Create a list of token from the given string.
|
|
140
|
+
#
|
|
141
|
+
def tokenize( str )
|
|
142
|
+
if str.index( '"' )
|
|
143
|
+
i = str.index( '"' )
|
|
144
|
+
j = str.index( '"', i + 1 )
|
|
145
|
+
j ||= str.length
|
|
146
|
+
|
|
147
|
+
tokenize( str[ 0..i - 1 ] ) if i > 1
|
|
148
|
+
@tokens << str[ i..j ]
|
|
149
|
+
tokenize( str[ j + 1..-1 ] ) if j + 1 < str.length
|
|
150
|
+
elsif str.index( "'" )
|
|
151
|
+
i = str.index( "'" )
|
|
152
|
+
j = str.index( "'", i + 1 )
|
|
153
|
+
j ||= str.length
|
|
154
|
+
|
|
155
|
+
tokenize( str[ 0..i - 1 ] ) if i > 1
|
|
156
|
+
@tokens << str[ i..j ]
|
|
157
|
+
tokenize( str[ j + 1..-1 ] ) if j + 1 < str.length
|
|
158
|
+
else
|
|
159
|
+
str.strip.split( ' ' ).each { |t| @tokens << t }
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An abstract base verb.
|
|
5
|
+
# Derives from the Baseo object.
|
|
6
|
+
# It is a special type of object in that it can be run
|
|
7
|
+
# and can perform an action.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
module Gloo
|
|
11
|
+
module Core
|
|
12
|
+
class Verb < Baseo
|
|
13
|
+
|
|
14
|
+
attr_reader :tokens, :params
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Set up the verb.
|
|
18
|
+
#
|
|
19
|
+
def initialize( engine, tokens, params = [] )
|
|
20
|
+
@engine = engine
|
|
21
|
+
@tokens = tokens
|
|
22
|
+
@params = params
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Register verbs when they are loaded.
|
|
27
|
+
#
|
|
28
|
+
def self.inherited( subclass )
|
|
29
|
+
Dictionary.instance.register_verb( subclass )
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Run the verb.
|
|
34
|
+
#
|
|
35
|
+
# We'll mark the application as not running and let the
|
|
36
|
+
# engine stop gracefully next time through the loop.
|
|
37
|
+
#
|
|
38
|
+
def run
|
|
39
|
+
raise 'this method should be overriden'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
# Get the Verb's keyword.
|
|
44
|
+
#
|
|
45
|
+
# The keyword will be in lower case only.
|
|
46
|
+
# It is used by the parser.
|
|
47
|
+
#
|
|
48
|
+
def self.keyword
|
|
49
|
+
raise 'this method should be overriden'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Get the Verb's keyword shortcut.
|
|
54
|
+
#
|
|
55
|
+
def self.keyword_shortcut
|
|
56
|
+
raise 'this method should be overriden'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# The object type, suitable for display.
|
|
61
|
+
#
|
|
62
|
+
def type_display
|
|
63
|
+
return self.class.keyword
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Generic function to get display value.
|
|
68
|
+
# Can be used for debugging, etc.
|
|
69
|
+
#
|
|
70
|
+
def display_value
|
|
71
|
+
return self.class.keyword
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# ---------------------------------------------------------------------
|
|
75
|
+
# Help
|
|
76
|
+
# ---------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
# Get help for this verb.
|
|
80
|
+
#
|
|
81
|
+
def self.help
|
|
82
|
+
return 'No help found.'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An action is a message sent to an object with optional parameters.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Gloo
|
|
8
|
+
module Exec
|
|
9
|
+
class Action
|
|
10
|
+
|
|
11
|
+
attr_accessor :msg, :to, :params
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Set up the action.
|
|
15
|
+
#
|
|
16
|
+
def initialize( msg, to, params = nil )
|
|
17
|
+
@msg = msg
|
|
18
|
+
@to = to
|
|
19
|
+
@params = params
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# The action is valid if the object can receive
|
|
24
|
+
# the message specified.
|
|
25
|
+
#
|
|
26
|
+
def valid?
|
|
27
|
+
return @to.can_receive_message?( @msg )
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Execute the action.
|
|
32
|
+
# Dispatch the message to the object.
|
|
33
|
+
#
|
|
34
|
+
def dispatch
|
|
35
|
+
@to.send_message @msg, @params
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Generic function to get display value.
|
|
40
|
+
# Can be used for debugging, etc.
|
|
41
|
+
#
|
|
42
|
+
def display_value
|
|
43
|
+
return "#{@msg} -> #{@to.pn}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Central Message Dispatch.
|
|
5
|
+
# Responsible for sending message to objects.
|
|
6
|
+
# All object messaging goes through here so we can uniformly
|
|
7
|
+
# manage things like checking to make sure object can
|
|
8
|
+
# receive the messages sent, handling errors, etc.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
module Gloo
|
|
12
|
+
module Exec
|
|
13
|
+
class Dispatch
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Dispatch the given message to the given object.
|
|
17
|
+
#
|
|
18
|
+
def self.message( engine, msg, to_obj, params = nil )
|
|
19
|
+
engine.log.debug "Dispatch message #{msg} to #{to_obj.name}"
|
|
20
|
+
a = Gloo::Exec::Action.new msg, to_obj, params
|
|
21
|
+
Gloo::Exec::Dispatch.action( engine, a )
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Dispatch an action.
|
|
26
|
+
#
|
|
27
|
+
def self.action( engine, action )
|
|
28
|
+
unless action.valid?
|
|
29
|
+
engine.log.warn "Object #{action.to.name} does not respond to #{action.msg}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
engine.exec_env.push_action action
|
|
33
|
+
engine.log.debug "Sending message #{action.msg} to #{action.to.name}"
|
|
34
|
+
action.dispatch
|
|
35
|
+
engine.exec_env.pop_action
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# The execution environment.
|
|
5
|
+
# The current state of running scripts and messaging.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Exec
|
|
10
|
+
class ExecEnv
|
|
11
|
+
|
|
12
|
+
attr_accessor :verbs, :actions, :scripts, :here
|
|
13
|
+
|
|
14
|
+
VERB_STACK = 'verbs'.freeze
|
|
15
|
+
ACTION_STACK = 'actions'.freeze
|
|
16
|
+
SCRIPT_STACK = 'scripts'.freeze
|
|
17
|
+
HERE_STACK = 'here'.freeze
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Set up the execution environment.
|
|
21
|
+
#
|
|
22
|
+
def initialize( engine )
|
|
23
|
+
@engine = engine
|
|
24
|
+
@engine.log.debug 'exec env intialized...'
|
|
25
|
+
|
|
26
|
+
@verbs = Gloo::Exec::Stack.new( @engine, VERB_STACK )
|
|
27
|
+
@actions = Gloo::Exec::Stack.new( @engine, ACTION_STACK )
|
|
28
|
+
@scripts = Gloo::Exec::Stack.new( @engine, SCRIPT_STACK )
|
|
29
|
+
@here = Gloo::Exec::Stack.new( @engine, HERE_STACK )
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Get the here object.
|
|
34
|
+
#
|
|
35
|
+
def here_obj
|
|
36
|
+
return nil if @here.stack.empty?
|
|
37
|
+
|
|
38
|
+
return @here.stack.last
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Push a script onto the stack.
|
|
43
|
+
#
|
|
44
|
+
def push_script( script )
|
|
45
|
+
@scripts.push script
|
|
46
|
+
@here.push script.obj
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Pop a script off the stack.
|
|
51
|
+
#
|
|
52
|
+
def pop_script
|
|
53
|
+
@scripts.pop
|
|
54
|
+
@here.pop
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Push an action onto the stack.
|
|
59
|
+
#
|
|
60
|
+
def push_action( action )
|
|
61
|
+
@actions.push action
|
|
62
|
+
# @here.push action.to
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
# Pop an action off the stack.
|
|
67
|
+
#
|
|
68
|
+
def pop_action
|
|
69
|
+
@actions.pop
|
|
70
|
+
# @here.pop
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# The Runner is a static helper function.
|
|
5
|
+
# It is used to send the run command to verbs.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Exec
|
|
10
|
+
class Runner
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Dispatch run command to a verb.
|
|
14
|
+
# We abstract this out in case there are things
|
|
15
|
+
# that need to be done before or after a verb
|
|
16
|
+
# is done running.
|
|
17
|
+
#
|
|
18
|
+
def self.go( engine, verb )
|
|
19
|
+
engine.log.debug "running verb #{verb.type_display}"
|
|
20
|
+
engine.heap.error.start_tracking
|
|
21
|
+
engine.exec_env.verbs.push verb
|
|
22
|
+
verb&.run
|
|
23
|
+
engine.exec_env.verbs.pop
|
|
24
|
+
engine.heap.error.clear_if_no_errors
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Send 'run' message to the object.
|
|
29
|
+
# Resolve the path_name and then send the run message.
|
|
30
|
+
#
|
|
31
|
+
def self.run( engine, path_name )
|
|
32
|
+
engine.log.debug "running script at #{path_name}"
|
|
33
|
+
pn = Gloo::Core::Pn.new( engine, path_name )
|
|
34
|
+
o = pn.resolve
|
|
35
|
+
|
|
36
|
+
if o
|
|
37
|
+
o.send_message 'run'
|
|
38
|
+
else
|
|
39
|
+
engine.log.error "Could not send message to object. Bad path: #{path_name}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A script to be run.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Gloo
|
|
8
|
+
module Exec
|
|
9
|
+
class Script
|
|
10
|
+
|
|
11
|
+
attr_accessor :obj
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Set up the script.
|
|
15
|
+
#
|
|
16
|
+
def initialize( engine, obj )
|
|
17
|
+
@engine = engine
|
|
18
|
+
@obj = obj
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Run the script.
|
|
23
|
+
# The script might be a single string or an array
|
|
24
|
+
# of lines.
|
|
25
|
+
#
|
|
26
|
+
def run
|
|
27
|
+
@engine.exec_env.push_script self
|
|
28
|
+
|
|
29
|
+
if @obj.value.is_a? String
|
|
30
|
+
@engine.parser.run @obj.value
|
|
31
|
+
elsif @obj.value.is_a? Array
|
|
32
|
+
@obj.value.each do |line|
|
|
33
|
+
@engine.parser.run line
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@engine.exec_env.pop_script
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Generic function to get display value.
|
|
42
|
+
# Can be used for debugging, etc.
|
|
43
|
+
#
|
|
44
|
+
def display_value
|
|
45
|
+
return @obj.pn
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A stack of items, a call stack.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Gloo
|
|
8
|
+
module Exec
|
|
9
|
+
class Stack
|
|
10
|
+
|
|
11
|
+
attr_accessor :stack
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Set up the stack.
|
|
15
|
+
#
|
|
16
|
+
def initialize( engine, name )
|
|
17
|
+
@engine = engine
|
|
18
|
+
@name = name
|
|
19
|
+
clear_stack
|
|
20
|
+
@engine.log.debug "#{name} stack intialized..."
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Push an item onto the stack.
|
|
25
|
+
#
|
|
26
|
+
def push( obj )
|
|
27
|
+
@engine.log.debug "#{@name}:push #{obj.display_value}"
|
|
28
|
+
@stack.push obj
|
|
29
|
+
self.update_out_file if @engine.settings.debug
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Pop an item from the stack.
|
|
34
|
+
#
|
|
35
|
+
def pop
|
|
36
|
+
o = @stack.pop
|
|
37
|
+
@engine.log.debug "#{@name}:pop #{o.display_value}"
|
|
38
|
+
self.update_out_file if @engine.settings.debug
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Get the current size of the call stack.
|
|
43
|
+
#
|
|
44
|
+
def size
|
|
45
|
+
return @stack.size
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Get stack data for output.
|
|
50
|
+
#
|
|
51
|
+
def out_data
|
|
52
|
+
return @stack.map( &:display_value ).join( "\n" )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Get the file we'll write debug information for the stack.
|
|
57
|
+
#
|
|
58
|
+
def out_file
|
|
59
|
+
return File.join( @engine.settings.debug_path, @name )
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Update the stack trace file.
|
|
64
|
+
#
|
|
65
|
+
def update_out_file
|
|
66
|
+
File.write( self.out_file, self.out_data )
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Clear the stack and the output file.
|
|
71
|
+
#
|
|
72
|
+
def clear_stack
|
|
73
|
+
@stack = []
|
|
74
|
+
self.update_out_file
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# An Expression that can be evaluated.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Gloo
|
|
8
|
+
module Expr
|
|
9
|
+
class Expression
|
|
10
|
+
|
|
11
|
+
# ---------------------------------------------------------------------
|
|
12
|
+
# Constructor
|
|
13
|
+
# ---------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Create the expression from a list of tokens.
|
|
17
|
+
#
|
|
18
|
+
def initialize( engine, tokens )
|
|
19
|
+
@engine = engine
|
|
20
|
+
@tokens = tokens
|
|
21
|
+
@symbols = []
|
|
22
|
+
@left = nil
|
|
23
|
+
@right = nil
|
|
24
|
+
@op = nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------
|
|
28
|
+
# Evaluate Expression
|
|
29
|
+
# ---------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Evaluate the expression and return the value.
|
|
33
|
+
#
|
|
34
|
+
def evaluate
|
|
35
|
+
identify_tokens
|
|
36
|
+
|
|
37
|
+
@symbols.each do |sym|
|
|
38
|
+
if sym.is_a? Gloo::Core::Op
|
|
39
|
+
@op = sym
|
|
40
|
+
elsif @left.nil?
|
|
41
|
+
@left = sym
|
|
42
|
+
else
|
|
43
|
+
@right = sym
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
perform_op if @left && @right
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
return @left.value if @left.is_a? Gloo::Core::Literal
|
|
50
|
+
return resolve_ref @left if @left.is_a? Gloo::Core::Pn
|
|
51
|
+
|
|
52
|
+
return @left
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# ---------------------------------------------------------------------
|
|
56
|
+
# Private functions
|
|
57
|
+
# ---------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Perform the operation.
|
|
63
|
+
#
|
|
64
|
+
def perform_op
|
|
65
|
+
@op ||= Gloo::Core::Op.default_op
|
|
66
|
+
l = evaluate_sym @left
|
|
67
|
+
r = evaluate_sym @right
|
|
68
|
+
@left = @op.perform l, r
|
|
69
|
+
@right = nil
|
|
70
|
+
@op = nil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Evaluate the symbol and get a simple value.
|
|
75
|
+
#
|
|
76
|
+
def evaluate_sym( sym )
|
|
77
|
+
return sym.value if sym.is_a? Gloo::Core::Literal
|
|
78
|
+
return resolve_ref sym if sym.is_a? Gloo::Core::Pn
|
|
79
|
+
|
|
80
|
+
return sym
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# resolve an object reference and get the value.
|
|
85
|
+
#
|
|
86
|
+
def resolve_ref( ref )
|
|
87
|
+
return ref.src if ref.named_color?
|
|
88
|
+
|
|
89
|
+
ob = ref.resolve
|
|
90
|
+
return ob.value if ob
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# Identify each token in the list.
|
|
95
|
+
#
|
|
96
|
+
def identify_tokens
|
|
97
|
+
@tokens.each do |o|
|
|
98
|
+
@symbols << identify_token( o )
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Identify the tokens and create appropriate symbols.
|
|
104
|
+
#
|
|
105
|
+
def identify_token( token )
|
|
106
|
+
return Gloo::Core::Op.create_op( token ) if Gloo::Core::Op.op?( token )
|
|
107
|
+
|
|
108
|
+
return LBoolean.new( token ) if LBoolean.boolean?( token )
|
|
109
|
+
return LInteger.new( token ) if LInteger.integer?( token )
|
|
110
|
+
return LString.new( token ) if LString.string?( token )
|
|
111
|
+
return LDecimal.new( token ) if LDecimal.decimal?( token )
|
|
112
|
+
|
|
113
|
+
# last chance: an Object reference
|
|
114
|
+
return Gloo::Core::Pn.new( @engine, token )
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|