gloo 6.7.2 → 7.0.1
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/CLAUDE.md +1 -0
- data/docs/application.md +3 -1
- data/docs/iterators.md +39 -3
- data/docs/language_syntax.md +53 -5
- data/docs/objects.md +59 -2
- data/docs/operators.md +16 -0
- data/docs/plugins.md +9 -1
- data/docs/verbs.md +4 -2
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +24 -0
- data/lib/gloo/app/engine.rb +64 -8
- data/lib/gloo/app/log.rb +47 -6
- data/lib/gloo/convert/converter.rb +63 -2
- data/lib/gloo/convert/string_to_date.rb +14 -0
- data/lib/gloo/convert/string_to_datetime.rb +16 -0
- data/lib/gloo/convert/string_to_decimal.rb +13 -0
- data/lib/gloo/convert/string_to_integer.rb +9 -2
- data/lib/gloo/convert/string_to_time.rb +28 -0
- data/lib/gloo/core/error.rb +11 -2
- data/lib/gloo/core/event_manager.rb +7 -4
- data/lib/gloo/core/factory.rb +16 -11
- data/lib/gloo/core/gloo_system.rb +3 -2
- data/lib/gloo/core/here.rb +6 -1
- data/lib/gloo/core/invoker.rb +2 -3
- data/lib/gloo/core/not_found.rb +42 -0
- data/lib/gloo/core/obj.rb +30 -3
- data/lib/gloo/core/op.rb +2 -0
- data/lib/gloo/core/parser.rb +1 -1
- data/lib/gloo/core/pn.rb +33 -12
- data/lib/gloo/core/tokens.rb +38 -0
- data/lib/gloo/core/verb.rb +54 -0
- data/lib/gloo/exec/dispatch.rb +5 -6
- data/lib/gloo/exec/exec_env.rb +13 -0
- data/lib/gloo/exec/runner.rb +10 -2
- data/lib/gloo/exec/script.rb +13 -1
- data/lib/gloo/expr/expression.rb +39 -1
- data/lib/gloo/expr/op_plus.rb +3 -0
- data/lib/gloo/objs/basic/boolean.rb +16 -0
- data/lib/gloo/objs/basic/container.rb +154 -6
- data/lib/gloo/objs/basic/decimal.rb +1 -0
- data/lib/gloo/objs/basic/integer.rb +1 -0
- data/lib/gloo/objs/basic/string.rb +0 -1
- data/lib/gloo/objs/basic/string_msgs.rb +68 -32
- data/lib/gloo/objs/ctrl/each.rb +22 -3
- data/lib/gloo/objs/ctrl/each_dir.rb +20 -7
- data/lib/gloo/objs/ctrl/each_file.rb +78 -9
- data/lib/gloo/objs/ctrl/function.rb +6 -5
- data/lib/gloo/objs/dt/date.rb +28 -11
- data/lib/gloo/objs/dt/datetime.rb +72 -21
- data/lib/gloo/objs/dt/dt_tools.rb +46 -2
- data/lib/gloo/objs/dt/time.rb +28 -11
- data/lib/gloo/objs/str_utils/cipher.rb +17 -4
- data/lib/gloo/objs/str_utils/password.rb +6 -2
- data/lib/gloo/objs/system/erb.rb +9 -3
- data/lib/gloo/objs/system/file_handle.rb +57 -21
- data/lib/gloo/objs/system/system.rb +6 -2
- data/lib/gloo/objs/web/http_get.rb +12 -2
- data/lib/gloo/objs/web/http_post.rb +6 -2
- data/lib/gloo/objs/web/json.rb +38 -18
- data/lib/gloo/objs/web/uri.rb +36 -16
- data/lib/gloo/persist/file_loader.rb +72 -11
- data/lib/gloo/persist/file_saver.rb +2 -1
- data/lib/gloo/persist/indent_stack.rb +49 -33
- data/lib/gloo/persist/line_splitter.rb +40 -3
- data/lib/gloo/persist/persist_man.rb +2 -4
- data/lib/gloo/plugin/ext_manager.rb +6 -9
- data/lib/gloo/plugin/lib_manager.rb +2 -2
- data/lib/gloo/verbs/break.rb +1 -0
- data/lib/gloo/verbs/check.rb +1 -1
- data/lib/gloo/verbs/cls.rb +1 -0
- data/lib/gloo/verbs/create.rb +32 -4
- data/lib/gloo/verbs/execute.rb +1 -1
- data/lib/gloo/verbs/exists.rb +27 -15
- data/lib/gloo/verbs/files.rb +2 -1
- data/lib/gloo/verbs/help.rb +1 -0
- data/lib/gloo/verbs/if.rb +1 -1
- data/lib/gloo/verbs/invoke.rb +1 -1
- data/lib/gloo/verbs/list.rb +4 -3
- data/lib/gloo/verbs/load.rb +3 -3
- data/lib/gloo/verbs/move.rb +10 -8
- data/lib/gloo/verbs/put.rb +20 -8
- data/lib/gloo/verbs/quit.rb +1 -0
- data/lib/gloo/verbs/redirect.rb +8 -2
- data/lib/gloo/verbs/reload.rb +9 -1
- data/lib/gloo/verbs/run.rb +2 -2
- data/lib/gloo/verbs/save.rb +4 -2
- data/lib/gloo/verbs/tell.rb +1 -1
- data/lib/gloo/verbs/unless.rb +1 -1
- data/lib/gloo/verbs/unload.rb +8 -0
- data/test.gloo/ctrl/each.test.gloo +88 -0
- data/test.gloo/dt/datetime.test.gloo +5 -3
- data/test.gloo/lang/convert.test.gloo +1 -0
- data/test.gloo/lang/declaration.test.gloo +38 -0
- data/test.gloo/lang/exceptions.test.gloo +68 -0
- data/test.gloo/lang/failures.test.gloo +143 -0
- data/test.gloo/lang/gloo_sys.test.gloo +14 -9
- data/test.gloo/lang/it.test.gloo +139 -0
- data/test.gloo/lang/naming.test.gloo +21 -0
- data/test.gloo/lang/ops.test.gloo +30 -0
- data/test.gloo/math/div.test.gloo +2 -2
- data/test.gloo/math/mult.test.gloo +4 -4
- data/test.gloo/objs/can.test.gloo +104 -0
- data/test.gloo/objs/function.test.gloo +1 -0
- data/test.gloo/objs/string.test.gloo +24 -0
- data/test.gloo/string/str.test.gloo +28 -0
- data/test.gloo/verbs/check.test.gloo +10 -1
- data/test.gloo/verbs/create.test.gloo +37 -0
- data/test.gloo/verbs/exists.test.gloo +34 -1
- data/test.gloo/verbs/invoke.test.gloo +1 -0
- data/test.gloo/verbs/list.test.gloo +1 -0
- data/test.gloo/verbs/load.test.gloo +2 -0
- data/test.gloo/verbs/reload.test.gloo +1 -0
- data/test.gloo/verbs/save.test.gloo +2 -0
- data/test.gloo/verbs/throw.test.gloo +2 -0
- data/test.gloo/verbs/unload.test.gloo +35 -0
- metadata +4 -1
|
@@ -12,10 +12,8 @@ module Gloo
|
|
|
12
12
|
|
|
13
13
|
attr_reader :maps, :mech
|
|
14
14
|
|
|
15
|
-
OBJ_NOT_FOUND_ERR = 'Could not resolve object to save: '.freeze
|
|
16
15
|
PATH_EXISTS_ERR = 'Will not overwrite a file not already saved there: '.freeze
|
|
17
16
|
RELOAD_DIRTY_WARNING = 'Reloading will discard unsaved changes in: '.freeze
|
|
18
|
-
FILE_NOT_FOUND_ERR = 'File not found: '.freeze
|
|
19
17
|
|
|
20
18
|
#
|
|
21
19
|
# Constructor for the persistence manager.
|
|
@@ -92,7 +90,7 @@ module Gloo
|
|
|
92
90
|
def load( name )
|
|
93
91
|
pns = get_full_path_names name
|
|
94
92
|
if pns.nil? || pns.empty?
|
|
95
|
-
@engine.err(
|
|
93
|
+
@engine.err( Gloo::Core::NotFound.file( name ) ) unless name.to_s.strip.empty?
|
|
96
94
|
return false
|
|
97
95
|
end
|
|
98
96
|
|
|
@@ -239,7 +237,7 @@ module Gloo
|
|
|
239
237
|
#
|
|
240
238
|
def resolve_for_save( name )
|
|
241
239
|
obj = Gloo::Core::Pn.new( @engine, name ).resolve
|
|
242
|
-
@engine.err(
|
|
240
|
+
@engine.err( Gloo::Core::NotFound.object( name ) ) unless obj
|
|
243
241
|
return obj
|
|
244
242
|
end
|
|
245
243
|
|
|
@@ -35,13 +35,13 @@ module Gloo
|
|
|
35
35
|
root = @engine.settings.ext_path
|
|
36
36
|
|
|
37
37
|
unless File.exist?( root )
|
|
38
|
-
@engine.
|
|
38
|
+
@engine.err Gloo::Core::NotFound.folder( root )
|
|
39
39
|
return nil
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
f = File.join( root, name, name + EXT_FILE )
|
|
43
43
|
unless File.exist?( f )
|
|
44
|
-
@engine.
|
|
44
|
+
@engine.err Gloo::Core::NotFound.file( f )
|
|
45
45
|
return nil
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -62,10 +62,8 @@ module Gloo
|
|
|
62
62
|
@engine.log.debug "Loading extension: #{name}"
|
|
63
63
|
fn = ext_start_file name
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return
|
|
68
|
-
end
|
|
65
|
+
# ext_start_file has already reported what's missing.
|
|
66
|
+
return unless fn
|
|
69
67
|
|
|
70
68
|
@extensions[name] = fn
|
|
71
69
|
register_extension name, fn
|
|
@@ -85,9 +83,8 @@ module Gloo
|
|
|
85
83
|
inst = plugin_class.new
|
|
86
84
|
ext_cb = Callback.new( @engine )
|
|
87
85
|
inst.register( ext_cb )
|
|
88
|
-
rescue NameError
|
|
89
|
-
@engine.
|
|
90
|
-
@engine.log.error "Could not find class #{class_name} in file #{full_path}"
|
|
86
|
+
rescue NameError
|
|
87
|
+
@engine.err "Could not find class '#{class_name}' in extension file '#{full_path}'."
|
|
91
88
|
end
|
|
92
89
|
end
|
|
93
90
|
|
|
@@ -93,8 +93,8 @@ module Gloo
|
|
|
93
93
|
inst = plugin_class.new
|
|
94
94
|
lib_cb = Callback.new( @engine )
|
|
95
95
|
inst.register( lib_cb )
|
|
96
|
-
rescue NameError
|
|
97
|
-
@engine.
|
|
96
|
+
rescue NameError
|
|
97
|
+
@engine.err "Could not find class '#{class_name}' in library '#{name}'."
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
data/lib/gloo/verbs/break.rb
CHANGED
data/lib/gloo/verbs/check.rb
CHANGED
data/lib/gloo/verbs/cls.rb
CHANGED
data/lib/gloo/verbs/create.rb
CHANGED
|
@@ -13,6 +13,10 @@ module Gloo
|
|
|
13
13
|
AS = 'as'.freeze
|
|
14
14
|
VAL = ':'.freeze
|
|
15
15
|
NO_NAME_ERR = 'Object name is missing!'.freeze
|
|
16
|
+
BAD_NAME_CHARS = /[()"']/.freeze
|
|
17
|
+
BAD_NAME_ERR = "'%s' isn't a name! To create an object at a " \
|
|
18
|
+
'computed path, put the path into an alias, then create ' \
|
|
19
|
+
'the alias: create slot* as string.'.freeze
|
|
16
20
|
|
|
17
21
|
#
|
|
18
22
|
# Run the verb.
|
|
@@ -23,9 +27,10 @@ module Gloo
|
|
|
23
27
|
value = @tokens.after_token( VAL )
|
|
24
28
|
|
|
25
29
|
unless name
|
|
26
|
-
@engine.
|
|
27
|
-
return
|
|
30
|
+
@engine.syntax_err NO_NAME_ERR
|
|
31
|
+
return @engine.heap.it.set_to( false )
|
|
28
32
|
end
|
|
33
|
+
return @engine.heap.it.set_to( false ) if bad_name?( name )
|
|
29
34
|
create name, type, value
|
|
30
35
|
end
|
|
31
36
|
|
|
@@ -49,6 +54,22 @@ module Gloo
|
|
|
49
54
|
|
|
50
55
|
private
|
|
51
56
|
|
|
57
|
+
#
|
|
58
|
+
# Is the name something create can't use? A name is taken as
|
|
59
|
+
# written, so expression characters -- parentheses or quotes -- or
|
|
60
|
+
# extra words between the name and 'as' / ':' mean the script was
|
|
61
|
+
# trying to compute it. Report that and return true.
|
|
62
|
+
#
|
|
63
|
+
def bad_name?( name )
|
|
64
|
+
after = @tokens.token_count > 2 ? @tokens.tokens[ 2 ] : nil
|
|
65
|
+
return false unless name.match?( BAD_NAME_CHARS ) ||
|
|
66
|
+
!( after.nil? || after.downcase == AS || after.start_with?( VAL ) )
|
|
67
|
+
|
|
68
|
+
written = @tokens.tokens[ 1..].take_while { |t| t.downcase != AS && !t.start_with?( VAL ) }
|
|
69
|
+
@engine.syntax_err format( BAD_NAME_ERR, written.join( ' ' ) )
|
|
70
|
+
return true
|
|
71
|
+
end
|
|
72
|
+
|
|
52
73
|
#
|
|
53
74
|
# Create an object with given name of given type with
|
|
54
75
|
# the given initial value.
|
|
@@ -60,12 +81,18 @@ module Gloo
|
|
|
60
81
|
|
|
61
82
|
# Check to see if this is an alias
|
|
62
83
|
pn = Gloo::Core::Pn.new( @engine, name )
|
|
84
|
+
return if pn.it_target_err?( 'created',
|
|
85
|
+
'it is reserved for the result of the last command, so use another name' )
|
|
86
|
+
|
|
63
87
|
obj = pn.resolve if pn
|
|
64
88
|
name = obj.value if obj&.is_alias?
|
|
65
89
|
|
|
66
90
|
obj = @engine.factory.create( { name: name, type: type, value: value } )
|
|
67
91
|
|
|
68
|
-
|
|
92
|
+
# Couldn't be created (already reported).
|
|
93
|
+
return @engine.heap.it.set_to( false ) unless obj
|
|
94
|
+
|
|
95
|
+
obj.add_default_children if obj.add_children_on_create?
|
|
69
96
|
@engine.heap.it.set_to value
|
|
70
97
|
end
|
|
71
98
|
|
|
@@ -96,7 +123,8 @@ module Gloo
|
|
|
96
123
|
"to the existing object's current value.",
|
|
97
124
|
:errors => [
|
|
98
125
|
"#{NO_NAME_ERR} — The name of the object was not specified and the object cannot be created.",
|
|
99
|
-
|
|
126
|
+
"Could not create '{path}': Object '{parent.path}' was not found. — The parent container named in the path does not exist. The path is root-relative and every container above the new object must already exist. Nothing is created, and it is false.",
|
|
127
|
+
"#{format( BAD_NAME_ERR, '{name}' )} — The name has parentheses or quotes, or there are extra words between the name and as / : — create takes a name as written. Nothing is created, and it is false."
|
|
100
128
|
],
|
|
101
129
|
:examples => <<~EXAMPLES.strip
|
|
102
130
|
# Basic examples of creating an object from the gloo shell:
|
data/lib/gloo/verbs/execute.rb
CHANGED
data/lib/gloo/verbs/exists.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
2
|
# Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
|
|
3
3
|
#
|
|
4
|
-
# Check to see if a verb or object type has been defined (or loaded)
|
|
4
|
+
# Check to see if a verb or object type has been defined (or loaded),
|
|
5
|
+
# or if an object instance exists.
|
|
5
6
|
#
|
|
6
7
|
|
|
7
8
|
module Gloo
|
|
@@ -14,7 +15,9 @@ module Gloo
|
|
|
14
15
|
OBJ_TYPE = 'object'.freeze
|
|
15
16
|
ANY_TYPE = 'any'.freeze
|
|
16
17
|
INSTANCE = 'instance'.freeze
|
|
18
|
+
KINDS = [ ANY_TYPE, OBJ_TYPE, VERB_TYPE, INSTANCE ].freeze
|
|
17
19
|
WRONG_NUM_ARGS_ERR = 'Wrong number of arguments! 1 or 2 expected.'.freeze
|
|
20
|
+
UNKNOWN_KIND_ERR = "Unknown kind '%s'! Use any, object, verb or instance.".freeze
|
|
18
21
|
|
|
19
22
|
#
|
|
20
23
|
# Run the verb.
|
|
@@ -23,12 +26,16 @@ module Gloo
|
|
|
23
26
|
if @tokens.token_count == 3
|
|
24
27
|
type = @tokens.second.strip.downcase
|
|
25
28
|
keyword = @tokens.last
|
|
29
|
+
unless KINDS.include?( type )
|
|
30
|
+
@engine.syntax_err format( UNKNOWN_KIND_ERR, @tokens.second )
|
|
31
|
+
return @engine.heap.it.set_to( false )
|
|
32
|
+
end
|
|
26
33
|
elsif @tokens.token_count == 2
|
|
27
34
|
type = ANY_TYPE
|
|
28
35
|
keyword = @tokens.second
|
|
29
36
|
else
|
|
30
|
-
@engine.
|
|
31
|
-
return
|
|
37
|
+
@engine.syntax_err WRONG_NUM_ARGS_ERR
|
|
38
|
+
return @engine.heap.it.set_to( false )
|
|
32
39
|
end
|
|
33
40
|
|
|
34
41
|
@engine.heap.it.set_to lookup_keyword(keyword, type)
|
|
@@ -64,7 +71,9 @@ module Gloo
|
|
|
64
71
|
elsif type == OBJ_TYPE
|
|
65
72
|
return @engine.dictionary.obj?(keyword)
|
|
66
73
|
elsif type == ANY_TYPE
|
|
67
|
-
return @engine.dictionary.verb?(keyword) ||
|
|
74
|
+
return @engine.dictionary.verb?(keyword) ||
|
|
75
|
+
@engine.dictionary.obj?(keyword) ||
|
|
76
|
+
instance_exists?(keyword)
|
|
68
77
|
elsif type == INSTANCE
|
|
69
78
|
return instance_exists?(keyword)
|
|
70
79
|
end
|
|
@@ -94,26 +103,29 @@ module Gloo
|
|
|
94
103
|
:name => KEYWORD,
|
|
95
104
|
:shortcut => KEYWORD_SHORT,
|
|
96
105
|
:description => 'Check to see if a verb or object type has ' \
|
|
97
|
-
'been defined (or loaded)
|
|
98
|
-
'
|
|
106
|
+
'been defined (or loaded), or if an object instance exists ' \
|
|
107
|
+
'in the heap. With no kind, any of the three counts.',
|
|
99
108
|
:syntax => [ 'exists? |any,object,verb,instance| {keyword}' ],
|
|
100
109
|
:parameters => [
|
|
101
|
-
"Kind of Keyword —
|
|
102
|
-
"any
|
|
103
|
-
"object checks for an object matching the keyword or keyword " \
|
|
110
|
+
"Kind of Keyword — Optional; any is the default. " \
|
|
111
|
+
"any checks for a verb, an object type, or an object instance; " \
|
|
112
|
+
"object checks for an object type matching the keyword or keyword " \
|
|
104
113
|
"shortcut; verb checks for a verb matching the keyword or " \
|
|
105
114
|
"keyword shortcut; instance checks to see if an object " \
|
|
106
115
|
"instance exists at the pathname represented by keyword. " \
|
|
107
116
|
"`exists? any markdown` is identical to `exists? markdown`.",
|
|
108
|
-
'{keyword} —
|
|
109
|
-
'
|
|
110
|
-
'the pathname to an object instance.'
|
|
117
|
+
'{keyword} — A verb or object type keyword or keyword shortcut, ' \
|
|
118
|
+
'or the pathname to an object instance. Must be specified.'
|
|
111
119
|
],
|
|
112
|
-
:result => 'If the object or
|
|
113
|
-
'otherwise false. The result will be in it.',
|
|
120
|
+
:result => 'If the verb, object type or instance exists, then ' \
|
|
121
|
+
'true, otherwise false. The result will be in it.',
|
|
114
122
|
:errors => [
|
|
115
|
-
"#{WRONG_NUM_ARGS_ERR} The kind of keyword is optional."
|
|
123
|
+
"#{WRONG_NUM_ARGS_ERR} The kind of keyword is optional.",
|
|
124
|
+
"#{format( UNKNOWN_KIND_ERR, '{kind}' )} The kind is not one of the four."
|
|
116
125
|
],
|
|
126
|
+
:notes => 'To check that a core library or extension has been ' \
|
|
127
|
+
'loaded, use object: exists? object markdown. With no kind, ' \
|
|
128
|
+
'an object instance with the same name would also count.',
|
|
117
129
|
:examples => <<~EXAMPLES.strip
|
|
118
130
|
#
|
|
119
131
|
# Example of exists? keyword.
|
data/lib/gloo/verbs/files.rb
CHANGED
|
@@ -15,7 +15,8 @@ module Gloo
|
|
|
15
15
|
# Run the verb.
|
|
16
16
|
#
|
|
17
17
|
def run
|
|
18
|
-
|
|
18
|
+
warn_extra_words
|
|
19
|
+
return @engine.heap.it.set_to( 0 ) unless @engine.persist_man.maps
|
|
19
20
|
|
|
20
21
|
@engine.persist_man.maps.each do |map|
|
|
21
22
|
@engine.log.show "#{map.obj.name} - #{map.pn}"
|
data/lib/gloo/verbs/help.rb
CHANGED
data/lib/gloo/verbs/if.rb
CHANGED
data/lib/gloo/verbs/invoke.rb
CHANGED
|
@@ -67,7 +67,7 @@ module Gloo
|
|
|
67
67
|
'directly rather than going through it.',
|
|
68
68
|
:errors => [
|
|
69
69
|
"#{Gloo::Core::Invoker::NO_TARGET_ERR} — No function reference was given.",
|
|
70
|
-
"
|
|
70
|
+
"Object '{path.to.function}' was not found. — The path doesn't resolve to any object.",
|
|
71
71
|
"#{Gloo::Core::Invoker::NOT_FUNCTION_ERR}{path.to.function} — The path resolves to an object that isn't a function.",
|
|
72
72
|
"#{Gloo::Core::Invoker::PARAM_COUNT_ERR}{path.to.function} (expected N, got N) — The number of params given doesn't match what the function declares."
|
|
73
73
|
],
|
data/lib/gloo/verbs/list.rb
CHANGED
|
@@ -10,7 +10,6 @@ module Gloo
|
|
|
10
10
|
|
|
11
11
|
KEYWORD = 'list'.freeze
|
|
12
12
|
KEYWORD_SHORT = '.'.freeze
|
|
13
|
-
TARGET_MISSING_ERR = 'Object does not exist: '.freeze
|
|
14
13
|
|
|
15
14
|
#
|
|
16
15
|
# Run the verb.
|
|
@@ -20,11 +19,13 @@ module Gloo
|
|
|
20
19
|
target = self.determine_target
|
|
21
20
|
indent = self.determine_indent
|
|
22
21
|
|
|
22
|
+
return if target.it_target_err?( 'listed' )
|
|
23
|
+
|
|
23
24
|
obj = target.resolve
|
|
24
25
|
if obj
|
|
25
26
|
show_target( obj, levels, indent )
|
|
26
27
|
else
|
|
27
|
-
@engine.err
|
|
28
|
+
@engine.err Gloo::Core::NotFound.object( @tokens.second )
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
@@ -191,7 +192,7 @@ module Gloo
|
|
|
191
192
|
:result => 'Object and children are listed out in the CLI. ' \
|
|
192
193
|
'Doc lines are included when the list_docs setting is on.',
|
|
193
194
|
:errors => [
|
|
194
|
-
"
|
|
195
|
+
"Object '{path.to.object}' was not found. — The object specified that is to be listed could not be found."
|
|
195
196
|
],
|
|
196
197
|
:examples => <<~EXAMPLES.strip
|
|
197
198
|
> list
|
data/lib/gloo/verbs/load.rb
CHANGED
|
@@ -30,12 +30,12 @@ module Gloo
|
|
|
30
30
|
opt = @tokens.second.strip.downcase
|
|
31
31
|
fn = @tokens.last
|
|
32
32
|
else
|
|
33
|
-
@engine.
|
|
33
|
+
@engine.syntax_err WRONG_NUM_ARGS_ERR
|
|
34
34
|
return
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
if fn.blank?
|
|
38
|
-
@engine.
|
|
38
|
+
@engine.syntax_err MISSING_EXPR_ERR
|
|
39
39
|
elsif opt == FILE_OPT
|
|
40
40
|
load_gloo_file fn
|
|
41
41
|
elsif opt == EXT_OPT
|
|
@@ -43,7 +43,7 @@ module Gloo
|
|
|
43
43
|
elsif opt == LIB_OPT
|
|
44
44
|
load_library fn
|
|
45
45
|
else
|
|
46
|
-
@engine.
|
|
46
|
+
@engine.syntax_err UNKNOWN_OPT_ERR
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
data/lib/gloo/verbs/move.rb
CHANGED
|
@@ -12,9 +12,7 @@ module Gloo
|
|
|
12
12
|
KEYWORD_SHORT = 'mv'.freeze
|
|
13
13
|
TO = 'to'.freeze
|
|
14
14
|
MISSING_SRC_ERR = 'Object to move was not specified!'.freeze
|
|
15
|
-
MISSING_SRC_OBJ_ERR = 'Could not find object to move: '.freeze
|
|
16
15
|
MISSING_DST_ERR = "'Move' must include 'to' parent object!".freeze
|
|
17
|
-
MISSING_DST_OBJ_ERR = 'Could not resolve target: '.freeze
|
|
18
16
|
|
|
19
17
|
#
|
|
20
18
|
# Run the verb.
|
|
@@ -56,15 +54,17 @@ module Gloo
|
|
|
56
54
|
def lookup_obj
|
|
57
55
|
arr = @tokens.before_token( TO )
|
|
58
56
|
if arr.count == 1
|
|
59
|
-
@engine.
|
|
57
|
+
@engine.syntax_err MISSING_SRC_ERR
|
|
60
58
|
return
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
name = arr[ 1 ]
|
|
64
62
|
pn = Gloo::Core::Pn.new( @engine, name )
|
|
63
|
+
return nil if pn.it_target_err?( 'moved' )
|
|
64
|
+
|
|
65
65
|
o = pn.resolve
|
|
66
66
|
|
|
67
|
-
@engine.err(
|
|
67
|
+
@engine.err( Gloo::Core::NotFound.object( name ) ) unless o
|
|
68
68
|
return o
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -74,13 +74,15 @@ module Gloo
|
|
|
74
74
|
def lookup_dst
|
|
75
75
|
dst = @tokens.after_token( TO )
|
|
76
76
|
unless dst
|
|
77
|
-
@engine.
|
|
77
|
+
@engine.syntax_err MISSING_DST_ERR
|
|
78
78
|
return nil
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
pn = Gloo::Core::Pn.new( @engine, dst )
|
|
82
|
+
return nil if pn.it_target_err?( 'moved into' )
|
|
83
|
+
|
|
82
84
|
o = pn.resolve
|
|
83
|
-
@engine.err(
|
|
85
|
+
@engine.err( Gloo::Core::NotFound.object( dst ) ) unless o
|
|
84
86
|
return o
|
|
85
87
|
end
|
|
86
88
|
|
|
@@ -104,9 +106,9 @@ module Gloo
|
|
|
104
106
|
:result => 'The object will now be in the new location.',
|
|
105
107
|
:errors => [
|
|
106
108
|
"#{MISSING_SRC_ERR} The {path.to.object} is not specified.",
|
|
107
|
-
"
|
|
109
|
+
"Object '{path.to.object}' was not found. — The {path.to.object} cannot be resolved.",
|
|
108
110
|
"#{MISSING_DST_ERR} The {new.parent} is not specified.",
|
|
109
|
-
"
|
|
111
|
+
"Object '{new.parent}' was not found. — The {new.parent} cannot be resolved."
|
|
110
112
|
],
|
|
111
113
|
:examples => <<~EXAMPLES.strip
|
|
112
114
|
can [can] :
|
data/lib/gloo/verbs/put.rb
CHANGED
|
@@ -13,17 +13,16 @@ module Gloo
|
|
|
13
13
|
INTO = 'into'.freeze
|
|
14
14
|
MISSING_EXPR_ERR = 'Missing Expression!'.freeze
|
|
15
15
|
INTO_MISSING_ERR = 'Target (into) missing!'.freeze
|
|
16
|
-
TARGET_ERR = 'Target could not be resolved: '.freeze
|
|
17
16
|
|
|
18
17
|
#
|
|
19
18
|
# Run the verb.
|
|
20
19
|
#
|
|
21
20
|
def run
|
|
22
21
|
value = fetch_value_tokens
|
|
23
|
-
return if value.nil?
|
|
22
|
+
return @engine.heap.it.set_to( false ) if value.nil?
|
|
24
23
|
|
|
25
24
|
target = lookup_target
|
|
26
|
-
return if target.nil?
|
|
25
|
+
return @engine.heap.it.set_to( false ) if target.nil?
|
|
27
26
|
|
|
28
27
|
update_target target, value
|
|
29
28
|
end
|
|
@@ -54,7 +53,7 @@ module Gloo
|
|
|
54
53
|
def fetch_value_tokens
|
|
55
54
|
value = @tokens.before_token( INTO )
|
|
56
55
|
if value.nil? || ( value.count <= 1 )
|
|
57
|
-
@engine.
|
|
56
|
+
@engine.syntax_err MISSING_EXPR_ERR
|
|
58
57
|
return nil
|
|
59
58
|
end
|
|
60
59
|
|
|
@@ -69,7 +68,7 @@ module Gloo
|
|
|
69
68
|
target = @tokens.after_token( INTO )
|
|
70
69
|
return target if target
|
|
71
70
|
|
|
72
|
-
@engine.
|
|
71
|
+
@engine.syntax_err INTO_MISSING_ERR
|
|
73
72
|
return nil
|
|
74
73
|
end
|
|
75
74
|
|
|
@@ -78,12 +77,22 @@ module Gloo
|
|
|
78
77
|
#
|
|
79
78
|
def update_target( target, value )
|
|
80
79
|
pn = Gloo::Core::Pn.new( @engine, target )
|
|
80
|
+
return if pn.it_target_err?( 'put into',
|
|
81
|
+
'put the value into an object instead' )
|
|
82
|
+
|
|
81
83
|
o = pn.resolve
|
|
82
84
|
if o.nil?
|
|
83
|
-
@engine.err
|
|
85
|
+
@engine.err Gloo::Core::NotFound.object( target )
|
|
86
|
+
@engine.heap.it.set_to false
|
|
84
87
|
elsif value.count.positive?
|
|
88
|
+
errors_before = @engine.heap.error.error_count
|
|
85
89
|
expr = Gloo::Expr::Expression.new( @engine, value )
|
|
86
90
|
result = expr.evaluate
|
|
91
|
+
|
|
92
|
+
# The value couldn't be evaluated (already reported); leave
|
|
93
|
+
# the target with its last good value rather than nil.
|
|
94
|
+
return @engine.heap.it.set_to( false ) if @engine.heap.error.error_count > errors_before
|
|
95
|
+
|
|
87
96
|
o.set_value result
|
|
88
97
|
@engine.heap.it.set_to result
|
|
89
98
|
end
|
|
@@ -108,11 +117,14 @@ module Gloo
|
|
|
108
117
|
'{dst.path} — The path to the destination object.'
|
|
109
118
|
],
|
|
110
119
|
:result => 'The destination object has the result of the ' \
|
|
111
|
-
'evaluated expression. It will also be set into it.'
|
|
120
|
+
'evaluated expression. It will also be set into it. If ' \
|
|
121
|
+
'evaluating the expression reports an error (eg. it uses ' \
|
|
122
|
+
'an object that does not exist), the destination is left ' \
|
|
123
|
+
'unchanged. If the put fails for any reason, it is false.',
|
|
112
124
|
:errors => [
|
|
113
125
|
"#{MISSING_EXPR_ERR} — The into keyword is missing, or no source expression is provided.",
|
|
114
126
|
"#{INTO_MISSING_ERR} — The destination is not specified.",
|
|
115
|
-
"
|
|
127
|
+
"Object '{dst.path}' was not found. — The destination of the put cannot be resolved."
|
|
116
128
|
],
|
|
117
129
|
:examples => <<~EXAMPLES.strip
|
|
118
130
|
> put 'one' into str
|
data/lib/gloo/verbs/quit.rb
CHANGED
data/lib/gloo/verbs/redirect.rb
CHANGED
|
@@ -24,14 +24,19 @@ module Gloo
|
|
|
24
24
|
#
|
|
25
25
|
def run
|
|
26
26
|
if @tokens.token_count < 2
|
|
27
|
-
@engine.
|
|
27
|
+
@engine.syntax_err MISSING_EXPR_ERR
|
|
28
28
|
return
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
if is_hard_redirect?
|
|
32
32
|
redirect_hard
|
|
33
33
|
else
|
|
34
|
+
pn = Gloo::Core::Pn.new( @engine, @tokens.second )
|
|
35
|
+
return if pn.it_target_err?( 'redirected to' )
|
|
36
|
+
|
|
34
37
|
determine_target
|
|
38
|
+
return @engine.err( Gloo::Core::NotFound.object( @tokens.second ) ) unless @target_obj
|
|
39
|
+
|
|
35
40
|
redirect_to_target
|
|
36
41
|
end
|
|
37
42
|
end
|
|
@@ -163,7 +168,8 @@ module Gloo
|
|
|
163
168
|
'the target page.',
|
|
164
169
|
:errors => [
|
|
165
170
|
"#{MISSING_EXPR_ERR} — Redirect requires the target page or script to redirect to.",
|
|
166
|
-
"
|
|
171
|
+
"Object '{target}' was not found. — The target object does not exist.",
|
|
172
|
+
"#{BAD_TARGET_ERR} — The target object cannot receive the redirect.",
|
|
167
173
|
"#{APP_NOT_RUNING_ERR} — Page cannot redirect because the application is not running."
|
|
168
174
|
],
|
|
169
175
|
:examples => <<~EXAMPLES.strip
|
data/lib/gloo/verbs/reload.rb
CHANGED
|
@@ -17,6 +17,8 @@ module Gloo
|
|
|
17
17
|
# Then the engine will restart with the original parameters.
|
|
18
18
|
#
|
|
19
19
|
def run
|
|
20
|
+
return if extra_words_err?( 'nothing was reloaded; to reload one object, use tell x to reload' )
|
|
21
|
+
|
|
20
22
|
@engine.persist_man.reload_all
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -61,9 +63,15 @@ module Gloo
|
|
|
61
63
|
'loaded again. Note that re-load does not trigger the ' \
|
|
62
64
|
'on_load script to run. There is an on_reload message sent ' \
|
|
63
65
|
'to all open files.',
|
|
66
|
+
:errors => [
|
|
67
|
+
'reload takes no object, so nothing was reloaded — anything ' \
|
|
68
|
+
'written after reload is an error, and nothing is reloaded. ' \
|
|
69
|
+
'To reload one object, use tell x to reload.'
|
|
70
|
+
],
|
|
64
71
|
:notes => 'If a file has changes that have not been saved, ' \
|
|
65
72
|
'reloading discards them (a warning is logged, but the ' \
|
|
66
|
-
'reload still proceeds).'
|
|
73
|
+
'reload still proceeds). reload takes no object; to reload ' \
|
|
74
|
+
'just one object\'s file, send it the reload message.',
|
|
67
75
|
:examples => <<~EXAMPLES.strip
|
|
68
76
|
> reload
|
|
69
77
|
EXAMPLES
|
data/lib/gloo/verbs/run.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Gloo
|
|
|
19
19
|
#
|
|
20
20
|
def run
|
|
21
21
|
if @tokens.token_count < 2
|
|
22
|
-
@engine.
|
|
22
|
+
@engine.syntax_err MISSING_EXPR_ERR
|
|
23
23
|
return
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -62,7 +62,7 @@ module Gloo
|
|
|
62
62
|
#
|
|
63
63
|
def run_expression
|
|
64
64
|
unless @tokens.token_count > 2
|
|
65
|
-
@engine.
|
|
65
|
+
@engine.syntax_err MISSING_EXPR_ERR
|
|
66
66
|
return
|
|
67
67
|
end
|
|
68
68
|
|
data/lib/gloo/verbs/save.rb
CHANGED
|
@@ -17,7 +17,9 @@ module Gloo
|
|
|
17
17
|
# Run the verb.
|
|
18
18
|
#
|
|
19
19
|
def run
|
|
20
|
-
|
|
20
|
+
name = @tokens.second
|
|
21
|
+
return if name && Gloo::Core::Pn.new( @engine, name ).it_target_err?( 'saved' )
|
|
22
|
+
return @engine.persist_man.save name unless @tokens.index_of( TO )
|
|
21
23
|
|
|
22
24
|
run_save_to
|
|
23
25
|
end
|
|
@@ -49,7 +51,7 @@ module Gloo
|
|
|
49
51
|
name = @tokens.before_token( TO )[ 1 ]
|
|
50
52
|
path = @tokens.after_token( TO )
|
|
51
53
|
unless path
|
|
52
|
-
@engine.
|
|
54
|
+
@engine.syntax_err MISSING_PATH_ERR
|
|
53
55
|
return
|
|
54
56
|
end
|
|
55
57
|
|
data/lib/gloo/verbs/tell.rb
CHANGED