teepee 0.15.9 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/teepee/command-parser.rb +136 -121
- data/lib/teepee/commander-mixins/control.rb +58 -13
- data/lib/teepee/commander.rb +6 -1
- data/lib/teepee/paragraph-parser.rb +3 -2
- data/lib/teepee/scope.rb +88 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfbe38c9d41e1090be4155258a0c692d19b2211e
|
4
|
+
data.tar.gz: 4104b6609251e0e161cedc53238458c7a99ad7ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb999c5d27222263724daf030892b9811a64f339adecdaa4b9ffa22a1b18d61cf89c1809d81dfbaeb9b01dd22d06c0b0da9a3a6f4f757f057d50f570c187c6d0
|
7
|
+
data.tar.gz: 14fc26a02e2192279e319a3c9aef0161566921cf49bebf319b90be57323c29dc0d7c12a1b82648f00e02899bad1a9513ceb12391b625270e74f0392c11897cfb
|
@@ -46,12 +46,14 @@ require 'teepee/actionable-commander'
|
|
46
46
|
|
47
47
|
module Teepee
|
48
48
|
class CommandParser < ParserNode
|
49
|
-
attr_accessor :parser
|
49
|
+
attr_accessor :parser, :scope
|
50
50
|
attr_reader :command, :expressions
|
51
51
|
|
52
|
-
def initialize(parser, command, expressions)
|
52
|
+
def initialize(parser, scope, command, expressions)
|
53
53
|
@parser = parser
|
54
54
|
raise ArgumentError if not command.is_a? WordToken
|
55
|
+
@scope = scope
|
56
|
+
raise ArgumentError if not scope.is_a? Scope
|
55
57
|
@command = command
|
56
58
|
raise ArgumentError if not expressions.is_a? Array
|
57
59
|
expressions.each do |expression|
|
@@ -64,14 +66,24 @@ module Teepee
|
|
64
66
|
%{<span style="color: red">[#{message}]</span>}
|
65
67
|
end
|
66
68
|
|
69
|
+
def commander
|
70
|
+
@@commander.with_scope scope
|
71
|
+
end
|
72
|
+
|
73
|
+
def subscoped_commander
|
74
|
+
@@commander.with_scope scope.derive
|
75
|
+
end
|
76
|
+
|
67
77
|
def to_number
|
68
78
|
to_html.to_number
|
69
79
|
end
|
70
80
|
|
71
81
|
def to_html
|
72
|
-
|
73
|
-
if
|
74
|
-
@@commander.
|
82
|
+
commander.parser = @parser
|
83
|
+
if @@commander.scope.has_key? command.word
|
84
|
+
@@commander.scope[command.word]
|
85
|
+
elsif @parser.variables.include? command.word
|
86
|
+
commander.get_operator command.word
|
75
87
|
else
|
76
88
|
builtins
|
77
89
|
end
|
@@ -82,7 +94,7 @@ module Teepee
|
|
82
94
|
when "backslash",
|
83
95
|
"bslash",
|
84
96
|
"-/"
|
85
|
-
|
97
|
+
commander.backslash
|
86
98
|
when "left-brace",
|
87
99
|
"left_brace",
|
88
100
|
"leftbrace",
|
@@ -92,7 +104,7 @@ module Teepee
|
|
92
104
|
"openingbrace",
|
93
105
|
"obrace",
|
94
106
|
"-("
|
95
|
-
|
107
|
+
commander.left_brace
|
96
108
|
when "right-brace",
|
97
109
|
"right_brace",
|
98
110
|
"rightbrace",
|
@@ -102,7 +114,7 @@ module Teepee
|
|
102
114
|
"closingbrace",
|
103
115
|
"cbrace",
|
104
116
|
")-"
|
105
|
-
|
117
|
+
commander.right_brace
|
106
118
|
when "left-bracket",
|
107
119
|
"left_bracket",
|
108
120
|
"opening-bracket",
|
@@ -110,7 +122,7 @@ module Teepee
|
|
110
122
|
"lbracket",
|
111
123
|
"obracket",
|
112
124
|
"(("
|
113
|
-
|
125
|
+
commander.left_bracket
|
114
126
|
when "right-bracket",
|
115
127
|
"right_bracket",
|
116
128
|
"closing-bracket",
|
@@ -118,69 +130,69 @@ module Teepee
|
|
118
130
|
"rbracket",
|
119
131
|
"cbracket",
|
120
132
|
"))"
|
121
|
-
|
133
|
+
commander.right_bracket
|
122
134
|
when "pipe"
|
123
|
-
|
135
|
+
commander.pipe
|
124
136
|
when "backtick",
|
125
137
|
"backquote",
|
126
138
|
"'"
|
127
|
-
|
139
|
+
commander.backquote
|
128
140
|
when "squiggle",
|
129
141
|
"tilde"
|
130
|
-
|
142
|
+
commander.squiggle
|
131
143
|
when "dollar"
|
132
|
-
|
144
|
+
commander.dollar
|
133
145
|
when "_"
|
134
|
-
|
146
|
+
commander.nbsp optional_first_word_token
|
135
147
|
when "space"
|
136
|
-
|
148
|
+
commander.space
|
137
149
|
when "br", "newline"
|
138
|
-
|
150
|
+
commander.br
|
139
151
|
when "bold", "b", "textbf"
|
140
|
-
|
152
|
+
commander.b expressions
|
141
153
|
when "del",
|
142
154
|
"s",
|
143
155
|
"strike",
|
144
156
|
"strikethrough",
|
145
157
|
"strikeout"
|
146
|
-
|
158
|
+
commander.del expressions
|
147
159
|
when "italic",
|
148
160
|
"textit",
|
149
161
|
"it"
|
150
|
-
|
162
|
+
commander.it expressions
|
151
163
|
when "underline",
|
152
164
|
"u"
|
153
|
-
|
165
|
+
commander.u expressions
|
154
166
|
when "tt",
|
155
167
|
"texttt",
|
156
168
|
"teletype",
|
157
169
|
"typewriter"
|
158
|
-
|
170
|
+
commander.tt expressions
|
159
171
|
when "small"
|
160
|
-
|
172
|
+
commander.small expressions
|
161
173
|
when "big"
|
162
|
-
|
174
|
+
commander.big expressions
|
163
175
|
when "subscript",
|
164
176
|
"sub"
|
165
|
-
|
177
|
+
commander.sub expressions
|
166
178
|
when "superscript",
|
167
179
|
"sup"
|
168
|
-
|
180
|
+
commander.sup expressions
|
169
181
|
when "h1"
|
170
|
-
|
182
|
+
commander.h1 expressions
|
171
183
|
when "h2"
|
172
|
-
|
184
|
+
commander.h2 expressions
|
173
185
|
when "h3"
|
174
|
-
|
186
|
+
commander.h3 expressions
|
175
187
|
when "h4"
|
176
|
-
|
188
|
+
commander.h4 expressions
|
177
189
|
when "h5"
|
178
|
-
|
190
|
+
commander.h5 expressions
|
179
191
|
when "h6"
|
180
|
-
|
192
|
+
commander.h6 expressions
|
181
193
|
when "itemize",
|
182
194
|
"ul"
|
183
|
-
|
195
|
+
commander.itemize expressions
|
184
196
|
when "itemize-disc",
|
185
197
|
"ul-disc",
|
186
198
|
"itemize_disc",
|
@@ -189,32 +201,32 @@ module Teepee
|
|
189
201
|
"ul-disk",
|
190
202
|
"itemize_disk",
|
191
203
|
"ul_disk"
|
192
|
-
|
204
|
+
commander.itemize_disc expressions
|
193
205
|
when "itemize-circle",
|
194
206
|
"ul-circle",
|
195
207
|
"itemize_circle",
|
196
208
|
"ul_circle"
|
197
|
-
|
209
|
+
commander.itemize_circle expressions
|
198
210
|
when "itemize-square",
|
199
211
|
"ul-square",
|
200
212
|
"itemize_square",
|
201
213
|
"ul_square"
|
202
|
-
|
214
|
+
commander.itemize_square expressions
|
203
215
|
when "itemize-none",
|
204
216
|
"ul-none",
|
205
217
|
"itemize_none",
|
206
218
|
"ul_none"
|
207
|
-
|
219
|
+
commander.itemize_none expressions
|
208
220
|
when "enumerate",
|
209
221
|
"ol"
|
210
|
-
|
222
|
+
commander.enumerate expressions
|
211
223
|
when "enumerate-numeric",
|
212
224
|
"enumerate_numeric",
|
213
225
|
"enumerate-1",
|
214
226
|
"ol-1",
|
215
227
|
"enumerate_1",
|
216
228
|
"ol_1"
|
217
|
-
|
229
|
+
commander.enumerate_numeric expressions
|
218
230
|
when "enumerate-uppercase",
|
219
231
|
"enumerate_uppercase",
|
220
232
|
"enumerate-upcase",
|
@@ -223,7 +235,7 @@ module Teepee
|
|
223
235
|
"ol-A",
|
224
236
|
"enumerate_A",
|
225
237
|
"ol_A"
|
226
|
-
|
238
|
+
commander.enumerate_uppercase expressions
|
227
239
|
when "enumerate-lowercase",
|
228
240
|
"enumerate_lowercase",
|
229
241
|
"enumerate-downcase",
|
@@ -232,7 +244,7 @@ module Teepee
|
|
232
244
|
"ol-a",
|
233
245
|
"enumerate_a",
|
234
246
|
"ol_a"
|
235
|
-
|
247
|
+
commander.enumerate_lowercase expressions
|
236
248
|
when "enumerate-roman-uppercase",
|
237
249
|
"enumerate_roman_uppercase",
|
238
250
|
"enumerate-roman-upcase",
|
@@ -241,7 +253,7 @@ module Teepee
|
|
241
253
|
"ol-I",
|
242
254
|
"enumerate_I",
|
243
255
|
"ol_I"
|
244
|
-
|
256
|
+
commander.enumerate_roman_uppercase expressions
|
245
257
|
when "enumerate-roman-lowercase",
|
246
258
|
"enumerate_roman_lowercase",
|
247
259
|
"enumerate-roman-downcase",
|
@@ -250,60 +262,62 @@ module Teepee
|
|
250
262
|
"ol-i",
|
251
263
|
"enumerate_i",
|
252
264
|
"ol_i"
|
253
|
-
|
265
|
+
commander.enumerate_roman_lowercase expressions
|
254
266
|
when "item",
|
255
267
|
"li"
|
256
|
-
|
268
|
+
commander.item expressions
|
269
|
+
when "let1"
|
270
|
+
subscoped_commander.let1 expressions
|
257
271
|
when "table"
|
258
|
-
|
272
|
+
commander.table expressions
|
259
273
|
when "tr",
|
260
274
|
"table-row",
|
261
275
|
"table_row"
|
262
|
-
|
276
|
+
commander.table_row expressions
|
263
277
|
when "th",
|
264
278
|
"table-header",
|
265
279
|
"table_header"
|
266
|
-
|
280
|
+
commander.table_header expressions
|
267
281
|
when "td",
|
268
282
|
"table-data",
|
269
283
|
"table_data",
|
270
284
|
"table-cell",
|
271
285
|
"table_cell"
|
272
|
-
|
286
|
+
commander.table_data expressions
|
273
287
|
when "link",
|
274
288
|
"href",
|
275
289
|
"url"
|
276
|
-
|
290
|
+
commander.link expressions
|
277
291
|
when "email",
|
278
292
|
"email-address",
|
279
293
|
"email_address",
|
280
294
|
"mailto"
|
281
|
-
|
295
|
+
commander.mailto first_word_token
|
282
296
|
when "img",
|
283
297
|
"image"
|
284
|
-
|
298
|
+
commander.image expressions
|
285
299
|
when "user",
|
286
300
|
"user-id",
|
287
301
|
"user_id"
|
288
|
-
|
302
|
+
commander.user first_word_token
|
289
303
|
when "link-id",
|
290
304
|
"link_id"
|
291
|
-
|
305
|
+
commander.link_id first_word_token
|
292
306
|
when "keyword-id",
|
293
307
|
"keyword_id"
|
294
|
-
|
308
|
+
commander.keyword_id first_word_token
|
295
309
|
when "note-id",
|
296
310
|
"note_id"
|
297
|
-
|
311
|
+
commander.note_id first_word_token
|
298
312
|
when "tag-id",
|
299
313
|
"tag_id"
|
300
|
-
|
314
|
+
commander.tag_id first_word_token
|
301
315
|
when "forum-id",
|
302
316
|
"forum_id"
|
303
|
-
|
317
|
+
commander.forum_id first_word_token
|
304
318
|
when "folder-id",
|
305
319
|
"folder_id"
|
306
|
-
|
320
|
+
commander.folder_id first_word_token
|
307
321
|
when "bookmarks-folder-id",
|
308
322
|
"bookmarks_folder_id",
|
309
323
|
"bookmarks_folder-id",
|
@@ -312,148 +326,148 @@ module Teepee
|
|
312
326
|
"bookmark_folder_id",
|
313
327
|
"bookmark_folder-id",
|
314
328
|
"bookmark-folder_id"
|
315
|
-
|
329
|
+
commander.bookmarks_folder_id first_word_token
|
316
330
|
when "i" # sqrt(-1), not yet supported
|
317
|
-
|
331
|
+
commander.i
|
318
332
|
when "pi"
|
319
|
-
|
333
|
+
commander.pi
|
320
334
|
when "e"
|
321
|
-
|
335
|
+
commander.e
|
322
336
|
when "+"
|
323
|
-
|
337
|
+
commander.+ word_tokens
|
324
338
|
when "increment",
|
325
339
|
"inc"
|
326
|
-
|
340
|
+
commander.increment first_word_token
|
327
341
|
when "decrement",
|
328
342
|
"dec"
|
329
|
-
|
343
|
+
commander.decrement first_word_token
|
330
344
|
when "-"
|
331
|
-
|
345
|
+
commander.- word_tokens
|
332
346
|
when "*"
|
333
|
-
|
347
|
+
commander.* word_tokens
|
334
348
|
when "/",
|
335
349
|
"÷"
|
336
|
-
|
350
|
+
commander./ word_tokens
|
337
351
|
when "%"
|
338
|
-
|
352
|
+
commander.% word_tokens
|
339
353
|
when "+%"
|
340
|
-
|
354
|
+
commander.add_percentage word_tokens
|
341
355
|
when "-%"
|
342
|
-
|
356
|
+
commander.subtract_percentage word_tokens
|
343
357
|
when "%t",
|
344
358
|
"%total"
|
345
|
-
|
359
|
+
commander.percent_total word_tokens
|
346
360
|
when "floor"
|
347
|
-
|
361
|
+
commander.floor first_word_token
|
348
362
|
when "ceil",
|
349
363
|
"ciel",
|
350
364
|
"ceiling"
|
351
|
-
|
365
|
+
commander.ceiling first_word_token
|
352
366
|
when "round"
|
353
|
-
|
367
|
+
commander.round *word_tokens
|
354
368
|
when "mod",
|
355
369
|
"modulus",
|
356
370
|
"modulo"
|
357
|
-
|
371
|
+
commander.mod word_tokens
|
358
372
|
when "^", "**"
|
359
|
-
|
373
|
+
commander.** word_tokens
|
360
374
|
when "sin", "cos", "tan",
|
361
375
|
"asin", "acos", "atan",
|
362
376
|
"sinh", "cosh", "tanh",
|
363
377
|
"asinh", "acosh", "atanh",
|
364
378
|
"erf", "erfc",
|
365
379
|
"gamma", "log10", "sqrt"
|
366
|
-
|
380
|
+
commander.send command.word.to_sym, first_word_token
|
367
381
|
when "d2r",
|
368
382
|
"deg->rad",
|
369
383
|
"degrees->radians"
|
370
|
-
|
384
|
+
commander.degrees2radians first_word_token
|
371
385
|
when "r2d",
|
372
386
|
"rad->deg",
|
373
387
|
"radians->degrees"
|
374
|
-
|
388
|
+
commander.radians2degrees first_word_token
|
375
389
|
when "lgamma"
|
376
|
-
|
390
|
+
commander.lgamma first_word_token
|
377
391
|
when "ld",
|
378
392
|
"log2"
|
379
|
-
|
393
|
+
commander.ld first_word_token
|
380
394
|
when "ln"
|
381
|
-
|
395
|
+
commander.ln first_word_token
|
382
396
|
when "log"
|
383
397
|
base, number = word_tokens
|
384
|
-
|
398
|
+
commander.log base, number
|
385
399
|
when "ldexp"
|
386
400
|
fraction, exponent = word_tokens
|
387
|
-
|
401
|
+
commander.ldexp fraction, exponent
|
388
402
|
when "hypot"
|
389
|
-
|
403
|
+
commander.hypot word_tokens
|
390
404
|
when "true"
|
391
|
-
|
405
|
+
commander.true_constant
|
392
406
|
when "false"
|
393
|
-
|
407
|
+
commander.false_constant
|
394
408
|
when "not"
|
395
|
-
|
409
|
+
commander.boolean_not first_word_token
|
396
410
|
when "and"
|
397
|
-
|
411
|
+
commander.boolean_and expressions
|
398
412
|
when "or"
|
399
|
-
|
413
|
+
commander.boolean_or expressions
|
400
414
|
when "nand"
|
401
|
-
|
415
|
+
commander.boolean_nand expressions
|
402
416
|
when "nor"
|
403
|
-
|
417
|
+
commander.boolean_nor expressions
|
404
418
|
when "xor"
|
405
|
-
|
419
|
+
commander.boolean_xor expressions
|
406
420
|
when "xnor"
|
407
|
-
|
421
|
+
commander.boolean_xnor expressions
|
408
422
|
when "<"
|
409
|
-
|
423
|
+
commander.less_than word_tokens
|
410
424
|
when "<=",
|
411
425
|
"≤"
|
412
|
-
|
426
|
+
commander.less_than_or_equal word_tokens
|
413
427
|
when ">"
|
414
|
-
|
428
|
+
commander.greater_than word_tokens
|
415
429
|
when ">=",
|
416
430
|
"≥"
|
417
|
-
|
431
|
+
commander.greater_than_or_equal word_tokens
|
418
432
|
when "="
|
419
|
-
|
433
|
+
commander.equal word_tokens
|
420
434
|
when "!=",
|
421
435
|
"≠"
|
422
|
-
|
436
|
+
commander.not_equal word_tokens
|
423
437
|
when "if"
|
424
|
-
|
438
|
+
commander.if_operator expressions
|
425
439
|
when "when"
|
426
|
-
|
440
|
+
commander.when_operator expressions
|
427
441
|
when "unless"
|
428
|
-
|
442
|
+
commander.unless_operator expressions
|
429
443
|
when "comment",
|
430
444
|
"!--",
|
431
445
|
"#"
|
432
|
-
|
446
|
+
commander.comment expressions
|
433
447
|
when "span"
|
434
|
-
|
448
|
+
commander.span_operator expressions
|
435
449
|
when "prog1"
|
436
|
-
|
450
|
+
commander.prog1_operator expressions
|
437
451
|
when "progn"
|
438
|
-
|
452
|
+
commander.progn_operator expressions
|
439
453
|
when "prognil"
|
440
|
-
|
454
|
+
commander.prognil expressions
|
441
455
|
when "cond"
|
442
|
-
|
456
|
+
commander.cond_operator expressions
|
443
457
|
when "case"
|
444
|
-
|
458
|
+
commander.case_operator expressions
|
445
459
|
when "get"
|
446
|
-
|
460
|
+
commander.get_operator first_word_token
|
447
461
|
when "define",
|
448
462
|
"def"
|
449
|
-
|
463
|
+
commander.define expressions
|
450
464
|
when "undefine",
|
451
465
|
"undef"
|
452
|
-
|
466
|
+
commander.undefine expressions
|
453
467
|
when "defined?"
|
454
|
-
|
468
|
+
commander.is_defined? word_tokens
|
455
469
|
when "dotimes"
|
456
|
-
|
470
|
+
commander.dotimes expressions
|
457
471
|
else
|
458
472
|
command_error "unknown command #{command.to_html}"
|
459
473
|
end
|
@@ -484,8 +498,9 @@ module Teepee
|
|
484
498
|
@@action_view = nil
|
485
499
|
@@controller = nil
|
486
500
|
|
487
|
-
def parse(parser, tokens)
|
501
|
+
def parse(parser, scope, tokens)
|
488
502
|
@parser = parser
|
503
|
+
@scope = scope
|
489
504
|
expressions = []
|
490
505
|
rest = tokens
|
491
506
|
backslash, command, left_brace = rest.shift(3)
|
@@ -494,23 +509,23 @@ module Teepee
|
|
494
509
|
raise ParseError if not command.is_a? WordToken
|
495
510
|
if not left_brace.is_a? LeftBraceToken # A command with no interior.
|
496
511
|
rest.unshift left_brace if not left_brace.is_a? WhitespaceToken
|
497
|
-
return [CommandParser.new(parser, command, []), rest]
|
512
|
+
return [CommandParser.new(parser, scope, command, []), rest]
|
498
513
|
end
|
499
514
|
while rest.length > 0
|
500
515
|
if rest.first.is_a? WordToken or rest.first.is_a? WhitespaceToken or rest.first.is_a? PipeToken
|
501
516
|
expressions << rest.shift
|
502
517
|
elsif rest.first.is_a? BackslashToken
|
503
|
-
result, rest = CommandParser.parse(parser, rest)
|
518
|
+
result, rest = CommandParser.parse(parser, scope, rest)
|
504
519
|
expressions << result
|
505
520
|
elsif rest.first.is_a? RightBraceToken
|
506
521
|
right_brace = rest.shift
|
507
|
-
return [CommandParser.new(parser, command, expressions), rest]
|
522
|
+
return [CommandParser.new(parser, scope, command, expressions), rest]
|
508
523
|
else
|
509
524
|
raise ParseError
|
510
525
|
end
|
511
526
|
end
|
512
527
|
if right_brace.nil? # Allow a forgotten final right brace.
|
513
|
-
return [CommandParser.new(parser, command, expressions), rest]
|
528
|
+
return [CommandParser.new(parser, scope, command, expressions), rest]
|
514
529
|
end
|
515
530
|
end
|
516
531
|
|
@@ -59,19 +59,20 @@ module Teepee
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def cond_operator expressions
|
62
|
-
conditional, _, form, *
|
62
|
+
conditional, _, form, *body = strip expressions
|
63
63
|
if true_constant? conditional.to_html
|
64
64
|
form
|
65
|
-
elsif not
|
66
|
-
cond_operator
|
65
|
+
elsif not body.empty?
|
66
|
+
cond_operator body
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def decrement variable
|
71
|
-
|
72
|
-
|
71
|
+
k = variable.to_html
|
72
|
+
return variable_not_defined_error k if not is_defined? k
|
73
|
+
old_value = get_operator(k).to_number
|
73
74
|
return non_numeric_error old_value if not numeric? old_value
|
74
|
-
|
75
|
+
update_variable k, old_value - 1
|
75
76
|
end
|
76
77
|
|
77
78
|
def define expressions
|
@@ -85,13 +86,34 @@ module Teepee
|
|
85
86
|
def is_defined? variables
|
86
87
|
if not variables.is_a? Array
|
87
88
|
return is_defined? [variables]
|
88
|
-
elsif Set.new(variables.map(&:to_html)).subset? Set.new(@parser.variables.keys)
|
89
|
-
true_constant
|
90
89
|
else
|
91
|
-
|
90
|
+
Set.new(variables.map(&:to_html))
|
91
|
+
.subset? Set.new(scope.keys + @parser.variables.keys)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
+
def is_scoped? variables
|
96
|
+
if not variables.is_a? Array
|
97
|
+
return is_scoped? [variables]
|
98
|
+
else
|
99
|
+
Set.new(variables.map(&:to_html))
|
100
|
+
.subset? Set.new(scope.keys)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def update_variable variable, value
|
105
|
+
k = variable.to_html
|
106
|
+
value = value.to_html
|
107
|
+
if is_scoped? k
|
108
|
+
scope[k] = value
|
109
|
+
elsif is_defined? k
|
110
|
+
@parser.variables[k] = value
|
111
|
+
else
|
112
|
+
variable_not_defined_error k
|
113
|
+
end
|
114
|
+
value
|
115
|
+
end
|
116
|
+
|
95
117
|
def dotimes expressions
|
96
118
|
n = expressions.first.to_number
|
97
119
|
return "" if n.nil? or n < 1
|
@@ -109,7 +131,14 @@ module Teepee
|
|
109
131
|
end
|
110
132
|
|
111
133
|
def get_operator variable
|
112
|
-
|
134
|
+
key = variable.to_html
|
135
|
+
if scope.has_key? key
|
136
|
+
scope[key]
|
137
|
+
elsif @parser.variables.has_key? key
|
138
|
+
@parser.variables[key].to_html
|
139
|
+
else
|
140
|
+
variable_not_defined_error key
|
141
|
+
end
|
113
142
|
end
|
114
143
|
|
115
144
|
def if_operator expressions
|
@@ -123,10 +152,26 @@ module Teepee
|
|
123
152
|
end
|
124
153
|
|
125
154
|
def increment variable
|
126
|
-
|
127
|
-
|
155
|
+
k = variable.to_html
|
156
|
+
return variable_not_defined_error k if not is_defined? k
|
157
|
+
old_value = get_operator(k).to_number
|
128
158
|
return non_numeric_error old_value if not numeric? old_value
|
129
|
-
|
159
|
+
update_variable k, old_value + 1
|
160
|
+
end
|
161
|
+
|
162
|
+
def update_scope body
|
163
|
+
body.map do |clause|
|
164
|
+
if clause.kind_of? CommandParser
|
165
|
+
clause.scope = scope
|
166
|
+
end
|
167
|
+
end
|
168
|
+
body
|
169
|
+
end
|
170
|
+
|
171
|
+
def let1 expressions
|
172
|
+
variable, _, value, _, *body = expressions
|
173
|
+
scope[variable.to_html] = value.to_html
|
174
|
+
update_scope(body).map(&:to_html)
|
130
175
|
end
|
131
176
|
|
132
177
|
def not_equal numbers
|
data/lib/teepee/commander.rb
CHANGED
@@ -49,12 +49,17 @@ module Teepee
|
|
49
49
|
include CommanderMixins::Mathematics
|
50
50
|
include CommanderMixins::ThinkingBicycleModels
|
51
51
|
|
52
|
-
attr_accessor :parser
|
52
|
+
attr_accessor :parser, :scope
|
53
53
|
|
54
54
|
def initialize params
|
55
55
|
# We don't use the params in the base class, but might in derived classes.
|
56
56
|
end
|
57
57
|
|
58
|
+
def with_scope scope
|
59
|
+
@scope = scope
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
58
63
|
def valid_uri? uri
|
59
64
|
(!! (u = URI.parse(uri))) and not u.scheme.nil?
|
60
65
|
rescue URI::InvalidURIError
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
# -*- mode: Ruby -*-
|
3
3
|
|
4
|
-
# Copyright © 2013-
|
4
|
+
# Copyright © 2013-2016, Christopher Mark Gore,
|
5
5
|
# Soli Deo Gloria,
|
6
6
|
# All rights reserved.
|
7
7
|
#
|
@@ -39,6 +39,7 @@ require 'teepee/parser-node'
|
|
39
39
|
require 'teepee/token'
|
40
40
|
require 'teepee/commander'
|
41
41
|
require 'teepee/actionable-commander'
|
42
|
+
require 'teepee/scope'
|
42
43
|
require 'teepee/single-character-token'
|
43
44
|
require 'teepee/string-token'
|
44
45
|
require 'teepee/number-token'
|
@@ -66,7 +67,7 @@ module Teepee
|
|
66
67
|
elsif rest.first.is_a? WhitespaceToken
|
67
68
|
@expressions << rest.shift
|
68
69
|
elsif rest.first.is_a? BackslashToken
|
69
|
-
command, rest = CommandParser.parse(@parser, rest)
|
70
|
+
command, rest = CommandParser.parse(@parser, Scope.new, rest)
|
70
71
|
@expressions << command
|
71
72
|
else
|
72
73
|
return self
|
data/lib/teepee/scope.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# -*- mode: Ruby -*-
|
3
|
+
|
4
|
+
# Copyright © 2013-2016, Christopher Mark Gore,
|
5
|
+
# Soli Deo Gloria,
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# 2317 South River Road, Saint Charles, Missouri 63303 USA.
|
9
|
+
# Web: http://cgore.com
|
10
|
+
# Email: cgore@cgore.com
|
11
|
+
#
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
14
|
+
#
|
15
|
+
# * Redistributions of source code must retain the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer.
|
17
|
+
#
|
18
|
+
# * Redistributions in binary form must reproduce the above copyright
|
19
|
+
# notice, this list of conditions and the following disclaimer in the
|
20
|
+
# documentation and/or other materials provided with the distribution.
|
21
|
+
#
|
22
|
+
# * Neither the name of Christopher Mark Gore nor the names of other
|
23
|
+
# contributors may be used to endorse or promote products derived from
|
24
|
+
# this software without specific prior written permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
module Teepee
|
39
|
+
class Scope
|
40
|
+
attr_accessor :father, :variables
|
41
|
+
|
42
|
+
def initialize father = nil
|
43
|
+
@father = father
|
44
|
+
@variables = Hash.new
|
45
|
+
end
|
46
|
+
|
47
|
+
def orphan?
|
48
|
+
not father or father.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def keys
|
52
|
+
variables.keys
|
53
|
+
end
|
54
|
+
|
55
|
+
def has_key? key
|
56
|
+
variables.has_key?(key) or
|
57
|
+
(not orphan? and father.has_key?(key))
|
58
|
+
end
|
59
|
+
|
60
|
+
def [](key)
|
61
|
+
if variables.has_key? key
|
62
|
+
variables[key]
|
63
|
+
elsif father
|
64
|
+
father[key]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def []=(key, value)
|
69
|
+
variables[key] = value
|
70
|
+
end
|
71
|
+
|
72
|
+
def scope_for key
|
73
|
+
if variables.has_key? key
|
74
|
+
self
|
75
|
+
else
|
76
|
+
father.scope_for key
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def shadow? key
|
81
|
+
has_key?(key) and not orphan? and father.has_key?(key)
|
82
|
+
end
|
83
|
+
|
84
|
+
def derive
|
85
|
+
self.class.new self
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teepee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Mark Gore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/teepee/paragraph-parser.rb
|
60
60
|
- lib/teepee/parser-node.rb
|
61
61
|
- lib/teepee/parser.rb
|
62
|
+
- lib/teepee/scope.rb
|
62
63
|
- lib/teepee/single-character-token.rb
|
63
64
|
- lib/teepee/string-token.rb
|
64
65
|
- lib/teepee/token.rb
|