code-ruby 3.1.2 → 4.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/VERSION +1 -1
- data/bin/code +97 -20
- data/lib/code/concerns/shared.rb +331 -15
- data/lib/code/format.rb +15 -1
- data/lib/code/network.rb +87 -0
- data/lib/code/node/call.rb +79 -2
- data/lib/code/node/call_argument.rb +14 -0
- data/lib/code/node/code.rb +5 -4
- data/lib/code/node/function_parameter.rb +7 -4
- data/lib/code/node/list.rb +29 -1
- data/lib/code/object/base_64.rb +132 -6
- data/lib/code/object/boolean.rb +60 -0
- data/lib/code/object/class.rb +138 -2
- data/lib/code/object/code.rb +111 -3
- data/lib/code/object/context.rb +57 -1
- data/lib/code/object/cryptography.rb +63 -0
- data/lib/code/object/date.rb +13339 -462
- data/lib/code/object/decimal.rb +1725 -0
- data/lib/code/object/dictionary.rb +1790 -11
- data/lib/code/object/duration.rb +28 -0
- data/lib/code/object/function.rb +261 -23
- data/lib/code/object/global.rb +534 -1
- data/lib/code/object/html.rb +179 -7
- data/lib/code/object/http.rb +244 -14
- data/lib/code/object/ics.rb +75 -13
- data/lib/code/object/identifier_list.rb +17 -2
- data/lib/code/object/integer.rb +1937 -2
- data/lib/code/object/json.rb +75 -1
- data/lib/code/object/list.rb +3383 -10
- data/lib/code/object/nothing.rb +53 -0
- data/lib/code/object/number.rb +110 -0
- data/lib/code/object/parameter.rb +140 -0
- data/lib/code/object/range.rb +576 -14
- data/lib/code/object/smtp.rb +95 -12
- data/lib/code/object/string.rb +944 -3
- data/lib/code/object/super.rb +10 -1
- data/lib/code/object/time.rb +13358 -498
- data/lib/code/object/url.rb +65 -0
- data/lib/code/object.rb +543 -0
- data/lib/code/parser.rb +161 -24
- data/lib/code-ruby.rb +3 -0
- data/lib/code.rb +30 -3
- metadata +135 -84
- data/.github/dependabot.yml +0 -15
- data/.github/workflows/ci.yml +0 -38
- data/.gitignore +0 -30
- data/.node-version +0 -1
- data/.npm-version +0 -1
- data/.prettierignore +0 -2
- data/.rspec +0 -1
- data/.rubocop.yml +0 -140
- data/.ruby-version +0 -1
- data/.tool-versions +0 -3
- data/AGENTS.md +0 -43
- data/Gemfile +0 -22
- data/Gemfile.lock +0 -292
- data/Rakefile +0 -5
- data/bin/bundle +0 -123
- data/bin/bundle-audit +0 -31
- data/bin/bundler-audit +0 -31
- data/bin/dorian +0 -31
- data/bin/rspec +0 -31
- data/bin/rubocop +0 -31
- data/bin/test +0 -5
- data/code-ruby.gemspec +0 -34
- data/docs/precedence.txt +0 -36
- data/package-lock.json +0 -14
- data/package.json +0 -7
- data/spec/bin/code_spec.rb +0 -48
- data/spec/code/format_spec.rb +0 -153
- data/spec/code/node/call_spec.rb +0 -11
- data/spec/code/object/boolean_spec.rb +0 -18
- data/spec/code/object/cryptography_spec.rb +0 -25
- data/spec/code/object/decimal_spec.rb +0 -50
- data/spec/code/object/dictionary_spec.rb +0 -98
- data/spec/code/object/function_spec.rb +0 -268
- data/spec/code/object/http_spec.rb +0 -33
- data/spec/code/object/ics_spec.rb +0 -50
- data/spec/code/object/integer_spec.rb +0 -42
- data/spec/code/object/list_spec.rb +0 -22
- data/spec/code/object/nothing_spec.rb +0 -14
- data/spec/code/object/range_spec.rb +0 -23
- data/spec/code/object/string_spec.rb +0 -26
- data/spec/code/parser/boolean_spec.rb +0 -11
- data/spec/code/parser/chained_call_spec.rb +0 -16
- data/spec/code/parser/dictionary_spec.rb +0 -18
- data/spec/code/parser/function_spec.rb +0 -16
- data/spec/code/parser/group_spec.rb +0 -11
- data/spec/code/parser/if_modifier_spec.rb +0 -18
- data/spec/code/parser/list_spec.rb +0 -17
- data/spec/code/parser/number_spec.rb +0 -11
- data/spec/code/parser/string_spec.rb +0 -20
- data/spec/code/parser_spec.rb +0 -52
- data/spec/code/type_spec.rb +0 -21
- data/spec/code_spec.rb +0 -717
- data/spec/spec_helper.rb +0 -21
- data/spec/zeitwerk/loader_spec.rb +0 -7
data/lib/code/object/global.rb
CHANGED
|
@@ -3,6 +3,515 @@
|
|
|
3
3
|
class Code
|
|
4
4
|
class Object
|
|
5
5
|
class Global < Object
|
|
6
|
+
CLASS_DOCUMENTATION = {
|
|
7
|
+
name: "Global",
|
|
8
|
+
description: "dispatches top-level functions, constructors, and control flow helpers.",
|
|
9
|
+
examples: [
|
|
10
|
+
"globals.keys.include?(:puts)",
|
|
11
|
+
"classes.keys.include?(:List)",
|
|
12
|
+
"evaluate(\"1 + 2\")"
|
|
13
|
+
]
|
|
14
|
+
}.freeze
|
|
15
|
+
GETTING_STARTED_EXAMPLES = [
|
|
16
|
+
{
|
|
17
|
+
name: "expression",
|
|
18
|
+
description: "evaluate an expression and print the result.",
|
|
19
|
+
source: "1 + 2",
|
|
20
|
+
expected: "3",
|
|
21
|
+
command: "bin/code '1 + 2'"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "list",
|
|
25
|
+
description: "transform every item in a list with a block.",
|
|
26
|
+
source: "[1, 2, 3].map { |number| number * 2 }",
|
|
27
|
+
expected: "[2, 4, 6]",
|
|
28
|
+
command: "bin/code '[1, 2, 3].map { |number| number * 2 }'"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "dictionary",
|
|
32
|
+
description: "store named values in a dictionary and read them by key.",
|
|
33
|
+
source: "user = { name: :Dorian, age: 31 } user.name",
|
|
34
|
+
expected: ":Dorian",
|
|
35
|
+
command: "bin/code 'user = { name: :Dorian, age: 31 } user.name'"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "function",
|
|
39
|
+
description: "define a function and call it with an argument.",
|
|
40
|
+
source: "double = (number) => { number * 2 } double(21)",
|
|
41
|
+
expected: "42",
|
|
42
|
+
command: "bin/code 'double = (number) => { number * 2 } double(21)'"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "documentation",
|
|
46
|
+
description: "query built-in documentation from the language.",
|
|
47
|
+
source: "globals.fetch(:puts).examples.first",
|
|
48
|
+
expected: "\"puts(:hello)\"",
|
|
49
|
+
command: "bin/code 'globals.fetch(:puts).examples.first'"
|
|
50
|
+
}
|
|
51
|
+
].freeze
|
|
52
|
+
GETTING_STARTED = {
|
|
53
|
+
title: "Getting started with Code",
|
|
54
|
+
description: "a short guide with steps and runnable examples.",
|
|
55
|
+
steps: [
|
|
56
|
+
{
|
|
57
|
+
title: "Install dependencies",
|
|
58
|
+
action: "run bundle install from the repository root.",
|
|
59
|
+
command: "bundle install"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
title: "Run one expression",
|
|
63
|
+
action: "pass Code source to bin/code and read the printed result.",
|
|
64
|
+
example: GETTING_STARTED_EXAMPLES.fetch(0)
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: "Format source",
|
|
68
|
+
action: "use -f before a snippet or file to print formatted Code.",
|
|
69
|
+
command: "bin/code -f '{a:1}'",
|
|
70
|
+
expected: "{ a: 1 }"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
title: "Work with data",
|
|
74
|
+
action: "use lists, dictionaries, and functions together.",
|
|
75
|
+
examples: GETTING_STARTED_EXAMPLES[1, 3]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
title: "Find built-in functions",
|
|
79
|
+
action: "use globals, functions, instance_functions, and class_functions from inside Code.",
|
|
80
|
+
example: GETTING_STARTED_EXAMPLES.fetch(4)
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
examples: GETTING_STARTED_EXAMPLES,
|
|
84
|
+
next_steps: [
|
|
85
|
+
"run bin/code 'getting_started'",
|
|
86
|
+
"run bin/code 'globals.keys'",
|
|
87
|
+
"run bin/code 'List.instance_functions.keys'"
|
|
88
|
+
]
|
|
89
|
+
}.freeze
|
|
90
|
+
FUNCTIONS = {
|
|
91
|
+
"Base64" => {
|
|
92
|
+
name: "Base64",
|
|
93
|
+
description: "returns the Base64 class when called without arguments, otherwise calls Base64.new.",
|
|
94
|
+
examples: [
|
|
95
|
+
"Base64",
|
|
96
|
+
"Base64.new",
|
|
97
|
+
"Base64.new(nothing)"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"Boolean" => {
|
|
101
|
+
name: "Boolean",
|
|
102
|
+
description: "returns the Boolean class when called without arguments, otherwise calls Boolean.new.",
|
|
103
|
+
examples: [
|
|
104
|
+
"Boolean",
|
|
105
|
+
"Boolean.new",
|
|
106
|
+
"Boolean.new(nothing)"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"Class" => {
|
|
110
|
+
name: "Class",
|
|
111
|
+
description: "returns the Class class when called without arguments, otherwise calls Class.new.",
|
|
112
|
+
examples: [
|
|
113
|
+
"Class",
|
|
114
|
+
"Class.new",
|
|
115
|
+
"Class.new(nothing)"
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"Code" => {
|
|
119
|
+
name: "Code",
|
|
120
|
+
description: "returns the Code class when called without arguments, otherwise calls Code.new.",
|
|
121
|
+
examples: [
|
|
122
|
+
"Code",
|
|
123
|
+
"Code.new",
|
|
124
|
+
"Code.new(nothing)"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"Context" => {
|
|
128
|
+
name: "Context",
|
|
129
|
+
description: "returns the Context class when called without arguments, otherwise calls Context.new.",
|
|
130
|
+
examples: [
|
|
131
|
+
"Context",
|
|
132
|
+
"Context.new",
|
|
133
|
+
"Context.new(nothing)"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"Cryptography" => {
|
|
137
|
+
name: "Cryptography",
|
|
138
|
+
description: "returns the Cryptography class when called without arguments, otherwise calls Cryptography.new.",
|
|
139
|
+
examples: [
|
|
140
|
+
"Cryptography",
|
|
141
|
+
"Cryptography.new",
|
|
142
|
+
"Cryptography.new(nothing)"
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
"Date" => {
|
|
146
|
+
name: "Date",
|
|
147
|
+
description: "returns the Date class when called without arguments, otherwise calls Date.new.",
|
|
148
|
+
examples: [
|
|
149
|
+
"Date",
|
|
150
|
+
"Date.new",
|
|
151
|
+
"Date.new(nothing)"
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"Decimal" => {
|
|
155
|
+
name: "Decimal",
|
|
156
|
+
description: "returns the Decimal class when called without arguments, otherwise calls Decimal.new.",
|
|
157
|
+
examples: [
|
|
158
|
+
"Decimal",
|
|
159
|
+
"Decimal.new",
|
|
160
|
+
"Decimal.new(nothing)"
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
"Dictionary" => {
|
|
164
|
+
name: "Dictionary",
|
|
165
|
+
description: "returns the Dictionary class when called without arguments, otherwise calls Dictionary.new.",
|
|
166
|
+
examples: [
|
|
167
|
+
"Dictionary",
|
|
168
|
+
"Dictionary.new",
|
|
169
|
+
"Dictionary.new(nothing)"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"Duration" => {
|
|
173
|
+
name: "Duration",
|
|
174
|
+
description: "returns the Duration class when called without arguments, otherwise calls Duration.new.",
|
|
175
|
+
examples: [
|
|
176
|
+
"Duration",
|
|
177
|
+
"Duration.new",
|
|
178
|
+
"Duration.new(nothing)"
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"Function" => {
|
|
182
|
+
name: "Function",
|
|
183
|
+
description: "returns the Function class when called without arguments, otherwise calls Function.new.",
|
|
184
|
+
examples: [
|
|
185
|
+
"Function",
|
|
186
|
+
"Function.new",
|
|
187
|
+
"Function.new(nothing)"
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
"Html" => {
|
|
191
|
+
name: "Html",
|
|
192
|
+
description: "returns the Html class when called without arguments, otherwise calls Html.new.",
|
|
193
|
+
examples: [
|
|
194
|
+
"Html",
|
|
195
|
+
"Html.new",
|
|
196
|
+
"Html.new(nothing)"
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
"Http" => {
|
|
200
|
+
name: "Http",
|
|
201
|
+
description: "returns the Http class when called without arguments, otherwise calls Http.new.",
|
|
202
|
+
examples: [
|
|
203
|
+
"Http",
|
|
204
|
+
"Http.new",
|
|
205
|
+
"Http.new(nothing)"
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
"Ics" => {
|
|
209
|
+
name: "Ics",
|
|
210
|
+
description: "returns the Ics class when called without arguments, otherwise calls Ics.new.",
|
|
211
|
+
examples: [
|
|
212
|
+
"Ics",
|
|
213
|
+
"Ics.new",
|
|
214
|
+
"Ics.new(nothing)"
|
|
215
|
+
]
|
|
216
|
+
},
|
|
217
|
+
"IdentifierList" => {
|
|
218
|
+
name: "IdentifierList",
|
|
219
|
+
description: "returns the IdentifierList class when called without arguments, otherwise calls IdentifierList.new.",
|
|
220
|
+
examples: [
|
|
221
|
+
"IdentifierList",
|
|
222
|
+
"IdentifierList.new",
|
|
223
|
+
"IdentifierList.new(nothing)"
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"Integer" => {
|
|
227
|
+
name: "Integer",
|
|
228
|
+
description: "returns the Integer class when called without arguments, otherwise calls Integer.new.",
|
|
229
|
+
examples: [
|
|
230
|
+
"Integer",
|
|
231
|
+
"Integer.new",
|
|
232
|
+
"Integer.new(nothing)"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
"Json" => {
|
|
236
|
+
name: "Json",
|
|
237
|
+
description: "returns the Json class when called without arguments, otherwise calls Json.new.",
|
|
238
|
+
examples: [
|
|
239
|
+
"Json",
|
|
240
|
+
"Json.new",
|
|
241
|
+
"Json.new(nothing)"
|
|
242
|
+
]
|
|
243
|
+
},
|
|
244
|
+
"List" => {
|
|
245
|
+
name: "List",
|
|
246
|
+
description: "returns the List class when called without arguments, otherwise calls List.new.",
|
|
247
|
+
examples: [
|
|
248
|
+
"List",
|
|
249
|
+
"List.new",
|
|
250
|
+
"List.new(nothing)"
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
"Nothing" => {
|
|
254
|
+
name: "Nothing",
|
|
255
|
+
description: "returns the Nothing class when called without arguments, otherwise calls Nothing.new.",
|
|
256
|
+
examples: [
|
|
257
|
+
"Nothing",
|
|
258
|
+
"Nothing.new",
|
|
259
|
+
"Nothing.new(nothing)"
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
"Number" => {
|
|
263
|
+
name: "Number",
|
|
264
|
+
description: "returns the Number class when called without arguments, otherwise calls Number.new.",
|
|
265
|
+
examples: [
|
|
266
|
+
"Number",
|
|
267
|
+
"Number.new",
|
|
268
|
+
"Number.new(nothing)"
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
"Object" => {
|
|
272
|
+
name: "Object",
|
|
273
|
+
description: "returns the Object class when called without arguments, otherwise calls Object.new.",
|
|
274
|
+
examples: [
|
|
275
|
+
"Object",
|
|
276
|
+
"Object.new",
|
|
277
|
+
"Object.new(nothing)"
|
|
278
|
+
]
|
|
279
|
+
},
|
|
280
|
+
"Parameter" => {
|
|
281
|
+
name: "Parameter",
|
|
282
|
+
description: "returns the Parameter class when called without arguments, otherwise calls Parameter.new.",
|
|
283
|
+
examples: [
|
|
284
|
+
"Parameter",
|
|
285
|
+
"Parameter.new",
|
|
286
|
+
"Parameter.new(nothing)"
|
|
287
|
+
]
|
|
288
|
+
},
|
|
289
|
+
"Range" => {
|
|
290
|
+
name: "Range",
|
|
291
|
+
description: "returns the Range class when called without arguments, otherwise calls Range.new.",
|
|
292
|
+
examples: [
|
|
293
|
+
"Range",
|
|
294
|
+
"Range.new",
|
|
295
|
+
"Range.new(nothing)"
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
"Smtp" => {
|
|
299
|
+
name: "Smtp",
|
|
300
|
+
description: "returns the Smtp class when called without arguments, otherwise calls Smtp.new.",
|
|
301
|
+
examples: [
|
|
302
|
+
"Smtp",
|
|
303
|
+
"Smtp.new",
|
|
304
|
+
"Smtp.new(nothing)"
|
|
305
|
+
]
|
|
306
|
+
},
|
|
307
|
+
"String" => {
|
|
308
|
+
name: "String",
|
|
309
|
+
description: "returns the String class when called without arguments, otherwise calls String.new.",
|
|
310
|
+
examples: [
|
|
311
|
+
"String",
|
|
312
|
+
"String.new",
|
|
313
|
+
"String.new(nothing)"
|
|
314
|
+
]
|
|
315
|
+
},
|
|
316
|
+
"Time" => {
|
|
317
|
+
name: "Time",
|
|
318
|
+
description: "returns the Time class when called without arguments, otherwise calls Time.new.",
|
|
319
|
+
examples: [
|
|
320
|
+
"Time",
|
|
321
|
+
"Time.new",
|
|
322
|
+
"Time.new(nothing)"
|
|
323
|
+
]
|
|
324
|
+
},
|
|
325
|
+
"Url" => {
|
|
326
|
+
name: "Url",
|
|
327
|
+
description: "returns the Url class when called without arguments, otherwise calls Url.new.",
|
|
328
|
+
examples: [
|
|
329
|
+
"Url",
|
|
330
|
+
"Url.new",
|
|
331
|
+
"Url.new(nothing)"
|
|
332
|
+
]
|
|
333
|
+
},
|
|
334
|
+
"classes" => {
|
|
335
|
+
name: "classes",
|
|
336
|
+
description: "returns documentation for built-in classes exposed by globals.",
|
|
337
|
+
examples: [
|
|
338
|
+
"classes",
|
|
339
|
+
"classes.keys.include?(:List)",
|
|
340
|
+
"classes.fetch(:String).description"
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
"break" => {
|
|
344
|
+
name: "break",
|
|
345
|
+
description: "exits the current loop and returns an optional value.",
|
|
346
|
+
examples: [
|
|
347
|
+
"[1].each { break }",
|
|
348
|
+
"[1].each { break 1 }",
|
|
349
|
+
"while true { break :done }"
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
"continue" => {
|
|
353
|
+
name: "continue",
|
|
354
|
+
description: "skips the rest of the current loop iteration.",
|
|
355
|
+
examples: [
|
|
356
|
+
"[1].each { continue }",
|
|
357
|
+
"[1, 2].each { |value| continue if value == 1 }",
|
|
358
|
+
"while false { continue }"
|
|
359
|
+
]
|
|
360
|
+
},
|
|
361
|
+
"context" => {
|
|
362
|
+
name: "context",
|
|
363
|
+
description: "returns the current evaluation context dictionary.",
|
|
364
|
+
examples: [
|
|
365
|
+
"context",
|
|
366
|
+
"context.keys",
|
|
367
|
+
"context.has_key?(:context)"
|
|
368
|
+
]
|
|
369
|
+
},
|
|
370
|
+
"evaluate" => {
|
|
371
|
+
name: "evaluate",
|
|
372
|
+
description: "evaluates a string as Code source and returns its result.",
|
|
373
|
+
examples: [
|
|
374
|
+
"evaluate(\"1 + 2\")",
|
|
375
|
+
"evaluate(\":hello\")",
|
|
376
|
+
"evaluate(\"[1, 2].size\")"
|
|
377
|
+
]
|
|
378
|
+
},
|
|
379
|
+
"getting_started" => {
|
|
380
|
+
name: "getting_started",
|
|
381
|
+
description: "returns a short guide with runnable examples and commands.",
|
|
382
|
+
examples: [
|
|
383
|
+
"getting_started.title",
|
|
384
|
+
"getting_started.steps.first.command",
|
|
385
|
+
"getting_started.examples.map(&:name)"
|
|
386
|
+
]
|
|
387
|
+
},
|
|
388
|
+
"globals" => {
|
|
389
|
+
name: "globals",
|
|
390
|
+
description: "returns documentation for top-level functions and constructors.",
|
|
391
|
+
examples: [
|
|
392
|
+
"globals",
|
|
393
|
+
"globals.keys.include?(:List)",
|
|
394
|
+
"globals.fetch(:puts).description"
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
"next" => {
|
|
398
|
+
name: "next",
|
|
399
|
+
description: "exits the current block iteration and returns an optional value.",
|
|
400
|
+
examples: [
|
|
401
|
+
"[1].map { next }",
|
|
402
|
+
"[1].map { next 2 }",
|
|
403
|
+
"[1, 2].map { next it if it > 1 }"
|
|
404
|
+
]
|
|
405
|
+
},
|
|
406
|
+
"p" => {
|
|
407
|
+
name: "p",
|
|
408
|
+
description: "writes inspected values to output and returns nothing.",
|
|
409
|
+
examples: [
|
|
410
|
+
"p(:hello)",
|
|
411
|
+
"p(1, 2)",
|
|
412
|
+
"p([1, 2])"
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
"print" => {
|
|
416
|
+
name: "print",
|
|
417
|
+
description: "writes values to output without adding a newline.",
|
|
418
|
+
examples: [
|
|
419
|
+
"print(:hello)",
|
|
420
|
+
"print(1, 2)",
|
|
421
|
+
"print(\"hello\")"
|
|
422
|
+
]
|
|
423
|
+
},
|
|
424
|
+
"puts" => {
|
|
425
|
+
name: "puts",
|
|
426
|
+
description: "writes values to output with newlines and returns nothing.",
|
|
427
|
+
examples: [
|
|
428
|
+
"puts(:hello)",
|
|
429
|
+
"puts(1, 2)",
|
|
430
|
+
"puts(\"hello\")"
|
|
431
|
+
]
|
|
432
|
+
},
|
|
433
|
+
"read" => {
|
|
434
|
+
name: "read",
|
|
435
|
+
description: "reads one line from input.",
|
|
436
|
+
examples: [
|
|
437
|
+
"read",
|
|
438
|
+
"name = read",
|
|
439
|
+
"read.to_string"
|
|
440
|
+
]
|
|
441
|
+
},
|
|
442
|
+
"redo" => {
|
|
443
|
+
name: "redo",
|
|
444
|
+
description: "retries the current loop iteration.",
|
|
445
|
+
examples: [
|
|
446
|
+
"[1].each { redo if false }",
|
|
447
|
+
"while false { redo }",
|
|
448
|
+
"[1, 2].each { |value| redo if value == 0 }"
|
|
449
|
+
]
|
|
450
|
+
},
|
|
451
|
+
"retry" => {
|
|
452
|
+
name: "retry",
|
|
453
|
+
description: "retries the current loop iteration.",
|
|
454
|
+
examples: [
|
|
455
|
+
"[1].each { retry if false }",
|
|
456
|
+
"while false { retry }",
|
|
457
|
+
"[1, 2].each { |value| retry if value == 0 }"
|
|
458
|
+
]
|
|
459
|
+
},
|
|
460
|
+
"return" => {
|
|
461
|
+
name: "return",
|
|
462
|
+
description: "exits the current function and returns an optional value.",
|
|
463
|
+
examples: [
|
|
464
|
+
"() => { return }",
|
|
465
|
+
"() => { return 1 }",
|
|
466
|
+
"f = () => { return :done } f()"
|
|
467
|
+
]
|
|
468
|
+
}
|
|
469
|
+
}.freeze
|
|
470
|
+
|
|
471
|
+
def self.functions
|
|
472
|
+
Object.sorted_dictionary(FUNCTIONS)
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def self.classes
|
|
476
|
+
Object.sorted_dictionary(
|
|
477
|
+
documented_classes.to_h do |name, klass|
|
|
478
|
+
[name, Object.documentation_for(klass)]
|
|
479
|
+
end
|
|
480
|
+
)
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def self.documented_classes
|
|
484
|
+
{
|
|
485
|
+
"Base64" => Object::Base64,
|
|
486
|
+
"Boolean" => Boolean,
|
|
487
|
+
"Class" => Class,
|
|
488
|
+
"Code" => Code,
|
|
489
|
+
"Context" => Context,
|
|
490
|
+
"Cryptography" => Cryptography,
|
|
491
|
+
"Date" => Date,
|
|
492
|
+
"Decimal" => Decimal,
|
|
493
|
+
"Dictionary" => Dictionary,
|
|
494
|
+
"Duration" => Duration,
|
|
495
|
+
"Function" => Function,
|
|
496
|
+
"Html" => Html,
|
|
497
|
+
"Http" => Http,
|
|
498
|
+
"Ics" => Ics,
|
|
499
|
+
"IdentifierList" => IdentifierList,
|
|
500
|
+
"Integer" => Integer,
|
|
501
|
+
"Json" => Json,
|
|
502
|
+
"List" => List,
|
|
503
|
+
"Nothing" => Nothing,
|
|
504
|
+
"Number" => Number,
|
|
505
|
+
"Object" => Object,
|
|
506
|
+
"Parameter" => Parameter,
|
|
507
|
+
"Range" => Range,
|
|
508
|
+
"Smtp" => Smtp,
|
|
509
|
+
"String" => String,
|
|
510
|
+
"Time" => Time,
|
|
511
|
+
"Url" => Url
|
|
512
|
+
}
|
|
513
|
+
end
|
|
514
|
+
|
|
6
515
|
def call(**args)
|
|
7
516
|
code_operator = args.fetch(:operator, nil).to_code
|
|
8
517
|
code_arguments = args.fetch(:arguments, []).to_code
|
|
@@ -12,6 +521,21 @@ class Code
|
|
|
12
521
|
code_value = code_arguments.code_first
|
|
13
522
|
globals = multi_fetch(args, *GLOBALS)
|
|
14
523
|
|
|
524
|
+
if code_context.code_has_key?(code_operator).truthy?
|
|
525
|
+
code_result = code_context.code_fetch(code_operator)
|
|
526
|
+
|
|
527
|
+
if code_result.is_a?(Super) ||
|
|
528
|
+
(
|
|
529
|
+
code_result.is_a?(Function) &&
|
|
530
|
+
args.fetch(:explicit_arguments, false)
|
|
531
|
+
)
|
|
532
|
+
return code_result.call(**args, operator: nil)
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
sig(args)
|
|
536
|
+
return code_result
|
|
537
|
+
end
|
|
538
|
+
|
|
15
539
|
case code_operator.to_s
|
|
16
540
|
when "Boolean"
|
|
17
541
|
sig(args) { Object.repeat }
|
|
@@ -73,6 +597,12 @@ class Code
|
|
|
73
597
|
else
|
|
74
598
|
Class.new(Function)
|
|
75
599
|
end
|
|
600
|
+
when "globals"
|
|
601
|
+
sig(args)
|
|
602
|
+
self.class.functions
|
|
603
|
+
when "classes"
|
|
604
|
+
sig(args)
|
|
605
|
+
self.class.classes
|
|
76
606
|
when "Integer"
|
|
77
607
|
sig(args) { Object.repeat }
|
|
78
608
|
if code_arguments.any?
|
|
@@ -92,7 +622,7 @@ class Code
|
|
|
92
622
|
end
|
|
93
623
|
when "context"
|
|
94
624
|
sig(args)
|
|
95
|
-
code_context
|
|
625
|
+
code_context.code_deep_duplicate
|
|
96
626
|
when "Object"
|
|
97
627
|
sig(args)
|
|
98
628
|
if code_arguments.any?
|
|
@@ -173,6 +703,9 @@ class Code
|
|
|
173
703
|
when "evaluate"
|
|
174
704
|
sig(args) { Object }
|
|
175
705
|
Code.code_evaluate(code_value.code_to_string, **globals)
|
|
706
|
+
when "getting_started"
|
|
707
|
+
sig(args)
|
|
708
|
+
GETTING_STARTED.to_code
|
|
176
709
|
when "p"
|
|
177
710
|
sig(args) { Object.repeat }
|
|
178
711
|
output.puts(*code_arguments.raw.map(&:inspect))
|