livetext 0.9.26 → 0.9.27
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/lib/livetext/funcall.rb +13 -94
- data/lib/livetext/lineparser.rb +165 -31
- data/lib/livetext/parser/string.rb +14 -5
- data/lib/livetext/skeleton.rb +0 -4
- data/lib/livetext/standard.rb +2 -2
- data/lib/livetext/userapi.rb +0 -1
- data/lib/livetext/version.rb +1 -1
- data/lib/livetext.rb +0 -1
- data/test/snapshots/basic_formatting/actual-output.txt +8 -8
- data/test/snapshots/basic_formatting/out-sdiff.txt +8 -8
- data/test/snapshots/functions/actual-error.txt +19 -0
- data/test/snapshots/functions/actual-output.txt +0 -0
- data/test/snapshots/functions/err-sdiff.txt +20 -0
- data/test/snapshots/more_complex_vars/actual-error.txt +0 -0
- data/test/snapshots/more_complex_vars/actual-output.txt +4 -0
- data/test/snapshots/more_complex_vars/err-sdiff.txt +1 -0
- data/test/snapshots/more_complex_vars/out-sdiff.txt +5 -0
- data/test/snapshots/more_functions/actual-error.txt +19 -0
- data/test/snapshots/more_functions/actual-output.txt +0 -37
- data/test/snapshots/more_functions/err-sdiff.txt +19 -0
- data/test/snapshots/raw_lines/actual-error.txt +22 -0
- data/test/snapshots/raw_lines/actual-output.txt +0 -0
- data/test/snapshots/raw_lines/err-sdiff.txt +23 -0
- data/test/snapshots/simple_vars/actual-output.txt +2 -2
- data/test/snapshots/simple_vars/out-sdiff.txt +2 -2
- data/test/snapshots/var_into_func/actual-error.txt +19 -0
- data/test/snapshots/var_into_func/actual-output.txt +0 -16
- data/test/snapshots/var_into_func/err-sdiff.txt +19 -0
- data/test/unit/all.rb +0 -1
- data/test/unit/lineparser.rb +62 -353
- data/test/unit/new_lineparser.rb +359 -0
- data/test/unit/tokenizer.rb +2 -1
- metadata +13 -6
- data/lib/livetext/formatline.rb +0 -408
- data/test/snapshots/more_functions/out-sdiff.txt +0 -38
- data/test/testlines.rb +0 -37
- data/test/unit/formatline.rb +0 -638
data/lib/livetext/formatline.rb
DELETED
@@ -1,408 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative 'parsing'
|
3
|
-
require_relative 'funcall'
|
4
|
-
|
5
|
-
# Class FormatLine handles the parsing of comments, dot commands, and
|
6
|
-
# simple formatting characters.
|
7
|
-
|
8
|
-
class Livetext::FormatLine < StringParser
|
9
|
-
include Livetext::ParsingConstants
|
10
|
-
include Livetext::FormatLine::FunCall
|
11
|
-
|
12
|
-
attr_reader :out
|
13
|
-
attr_reader :tokenlist
|
14
|
-
|
15
|
-
def initialize(line)
|
16
|
-
super
|
17
|
-
@token = Null.dup
|
18
|
-
@tokenlist = []
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.parse!(line)
|
22
|
-
return nil if line.nil?
|
23
|
-
line.chomp!
|
24
|
-
x = self.new(line)
|
25
|
-
::Livetext::TTY.puts "\n-- string: #{line.inspect}" if $testme
|
26
|
-
t = x.tokenize
|
27
|
-
::Livetext::TTY.puts "\n-- Tokens: #{t.inspect}" if $testme
|
28
|
-
result = x.evaluate
|
29
|
-
::Livetext::TTY.puts "\n-- result: #{result.inspect}\n " if $testme
|
30
|
-
result
|
31
|
-
end
|
32
|
-
|
33
|
-
def tokenize
|
34
|
-
loop do
|
35
|
-
ch = peek
|
36
|
-
::Livetext::TTY.puts "\n-- #{__method__}: ch1 = #{ch.inspect}\n " if $testme
|
37
|
-
case ch
|
38
|
-
when Escape; grab; add peek; grab
|
39
|
-
when "$"
|
40
|
-
dollar
|
41
|
-
when "*", "_", "`", "~"
|
42
|
-
marker peek
|
43
|
-
add peek
|
44
|
-
when LF
|
45
|
-
break if eos?
|
46
|
-
when nil
|
47
|
-
break
|
48
|
-
else
|
49
|
-
add peek
|
50
|
-
end
|
51
|
-
ch = grab
|
52
|
-
# add ch
|
53
|
-
::Livetext::TTY.puts "\n-- #{__method__}: !!! ch2 = #{ch.inspect}\n " if $testme
|
54
|
-
end
|
55
|
-
add_token(:str)
|
56
|
-
@tokenlist
|
57
|
-
end
|
58
|
-
|
59
|
-
def parse_formatting
|
60
|
-
loop do
|
61
|
-
case peek
|
62
|
-
when Escape; grab; add peek; grab
|
63
|
-
when "*", "_", "`", "~"
|
64
|
-
marker peek
|
65
|
-
add peek
|
66
|
-
when LF
|
67
|
-
break if eos?
|
68
|
-
when nil
|
69
|
-
break
|
70
|
-
else
|
71
|
-
add peek
|
72
|
-
end
|
73
|
-
grab
|
74
|
-
end
|
75
|
-
add_token(:str)
|
76
|
-
@tokenlist
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.get_vars
|
80
|
-
grab
|
81
|
-
case peek
|
82
|
-
when LF, " ", nil
|
83
|
-
add "$"
|
84
|
-
add_token :str
|
85
|
-
when "$"; double_dollar
|
86
|
-
# when "."; dollar_dot
|
87
|
-
when /[A-Za-z]/
|
88
|
-
add_token :str
|
89
|
-
var = peek + grab_alpha_dot
|
90
|
-
add_token(:var, var)
|
91
|
-
else
|
92
|
-
add "$" + peek
|
93
|
-
add_token(:str)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def self.parse_var_func # FIXME Hmm...
|
98
|
-
loop do
|
99
|
-
case peek
|
100
|
-
when "$"
|
101
|
-
dollar
|
102
|
-
when LF
|
103
|
-
break if eos?
|
104
|
-
when nil
|
105
|
-
break
|
106
|
-
else
|
107
|
-
add peek
|
108
|
-
end
|
109
|
-
grab
|
110
|
-
end
|
111
|
-
add_token(:str)
|
112
|
-
@tokenlist
|
113
|
-
end
|
114
|
-
|
115
|
-
def terminate?(terminators, ch)
|
116
|
-
if terminators.is_a? Regexp
|
117
|
-
terminators === ch
|
118
|
-
else
|
119
|
-
terminators.include?(ch)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def var_func_parse
|
124
|
-
char = self.peek
|
125
|
-
loop do
|
126
|
-
char = self.grab
|
127
|
-
break if char == LF || char == nil
|
128
|
-
self.escaped if char == Escape
|
129
|
-
self.dollar if char == "$" # Could be $$
|
130
|
-
self.add char
|
131
|
-
end
|
132
|
-
self.add_token(:str)
|
133
|
-
result = self.evaluate
|
134
|
-
result
|
135
|
-
end
|
136
|
-
|
137
|
-
def self.var_func_parse(str)
|
138
|
-
return nil if str.nil?
|
139
|
-
x = self.new(str.chomp)
|
140
|
-
char = x.peek
|
141
|
-
loop do
|
142
|
-
char = x.grab
|
143
|
-
break if char == LF || char == nil
|
144
|
-
x.escaped if char == Escape
|
145
|
-
x.dollar if char == "$" # Could be $$
|
146
|
-
x.add char
|
147
|
-
end
|
148
|
-
x.add_token(:str)
|
149
|
-
result = x.evaluate
|
150
|
-
result
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.parse_variables(str)
|
154
|
-
return nil if str.nil?
|
155
|
-
x = self.new(str.chomp)
|
156
|
-
char = x.peek
|
157
|
-
loop do
|
158
|
-
char = x.grab
|
159
|
-
break if char == LF || char == nil
|
160
|
-
x.escaped if char == Escape
|
161
|
-
x.dollar if char == "$" # Could be $$
|
162
|
-
x.add char
|
163
|
-
end
|
164
|
-
x.add_token(:str)
|
165
|
-
result = x.evaluate
|
166
|
-
result
|
167
|
-
end
|
168
|
-
|
169
|
-
def embed(sym, str)
|
170
|
-
pre, post = SimpleFormats[sym]
|
171
|
-
pre + str + post
|
172
|
-
end
|
173
|
-
|
174
|
-
def evaluate(tokens = @tokenlist)
|
175
|
-
@out = ""
|
176
|
-
return "" if tokens.empty?
|
177
|
-
gen = tokens.each
|
178
|
-
token = gen.next
|
179
|
-
loop do
|
180
|
-
break if token.nil?
|
181
|
-
sym, val = *token
|
182
|
-
case sym
|
183
|
-
when :str; eval_str(val)
|
184
|
-
when :var; eval_var(val)
|
185
|
-
when :func; eval_func(val, gen)
|
186
|
-
when *BITS; eval_bits(sym, val)
|
187
|
-
else
|
188
|
-
add_token :str
|
189
|
-
end
|
190
|
-
token = gen.next
|
191
|
-
end
|
192
|
-
@out
|
193
|
-
end
|
194
|
-
|
195
|
-
def add(str)
|
196
|
-
@token << str unless str.nil?
|
197
|
-
end
|
198
|
-
|
199
|
-
def add_token(kind, token = @token)
|
200
|
-
return if token.nil?
|
201
|
-
@tokenlist << [kind, token] unless token.empty?
|
202
|
-
@token = Null.dup
|
203
|
-
end
|
204
|
-
|
205
|
-
def grab_alpha
|
206
|
-
str = Null.dup
|
207
|
-
grab
|
208
|
-
loop do
|
209
|
-
break if eos?
|
210
|
-
str << peek
|
211
|
-
break if terminate?(NoAlpha, lookahead)
|
212
|
-
grab
|
213
|
-
end
|
214
|
-
str
|
215
|
-
end
|
216
|
-
|
217
|
-
def grab_alpha_dot
|
218
|
-
str = Null.dup
|
219
|
-
grab
|
220
|
-
loop do
|
221
|
-
break if peek.nil? # eos?
|
222
|
-
str << peek
|
223
|
-
break if terminate?(NoAlphaDot, lookahead)
|
224
|
-
grab
|
225
|
-
end
|
226
|
-
str
|
227
|
-
end
|
228
|
-
|
229
|
-
def dollar
|
230
|
-
ch = grab # "$"
|
231
|
-
::Livetext::TTY.puts "\n-- #{__method__}: ch1 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
232
|
-
ch = peek
|
233
|
-
::Livetext::TTY.puts "\n-- #{__method__}: ch2 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
234
|
-
case ch
|
235
|
-
when " "
|
236
|
-
::Livetext::TTY.puts "\n-- #{__method__}: (space)" if $testme
|
237
|
-
add "$ "
|
238
|
-
add_token :str
|
239
|
-
when LF, nil
|
240
|
-
::Livetext::TTY.puts "\n-- #{__method__}: (LF/nil)" if $testme
|
241
|
-
add "$"
|
242
|
-
add_token :str
|
243
|
-
when "$"; double_dollar
|
244
|
-
# when "."; dollar_dot
|
245
|
-
when /[A-Za-z]/
|
246
|
-
::Livetext::TTY.puts "\n-- #{__method__}: (Alpha)" if $testme
|
247
|
-
add_token :str
|
248
|
-
var = peek + grab_alpha_dot
|
249
|
-
add_token(:var, var)
|
250
|
-
else
|
251
|
-
ch = grab # "$"
|
252
|
-
::Livetext::TTY.puts "\n-- ch3 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
253
|
-
add "$" + ch
|
254
|
-
add_token(:str)
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
# def dollar_dot
|
259
|
-
# add_token :ddot, @line[@i..-1]
|
260
|
-
# end
|
261
|
-
|
262
|
-
def marker(char)
|
263
|
-
add_token :str
|
264
|
-
sym = Syms[char]
|
265
|
-
if embedded?
|
266
|
-
# add char # ??? add_token "*", :string
|
267
|
-
return
|
268
|
-
end
|
269
|
-
|
270
|
-
grab
|
271
|
-
case peek
|
272
|
-
when Space
|
273
|
-
add char + " "
|
274
|
-
add_token :str
|
275
|
-
grab
|
276
|
-
when LF, nil
|
277
|
-
add char
|
278
|
-
add_token :str
|
279
|
-
when char; double_marker(char)
|
280
|
-
when LBrack; long_marker(char)
|
281
|
-
else
|
282
|
-
str = peek + collect!(sym, Blank)
|
283
|
-
add str
|
284
|
-
add_token sym, str
|
285
|
-
grab
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
def double_marker(char)
|
290
|
-
sym = Syms[char]
|
291
|
-
kind = sym
|
292
|
-
case lookahead # first char after **
|
293
|
-
when Space, LF, nil
|
294
|
-
pre, post = SimpleFormats[sym]
|
295
|
-
add_token kind
|
296
|
-
else
|
297
|
-
str = collect!(sym, Punc)
|
298
|
-
add_token kind, str
|
299
|
-
grab
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
def long_marker(char)
|
304
|
-
sym = Syms[char]
|
305
|
-
# grab # skip left bracket
|
306
|
-
kind = sym # "param_#{sym}".to_sym
|
307
|
-
arg = collect!(sym, Param, true)
|
308
|
-
add_token kind, arg
|
309
|
-
end
|
310
|
-
|
311
|
-
def collect_bracketed(sym, terminators)
|
312
|
-
str = Null.dup # next is not " ","*","["
|
313
|
-
grab # ZZZ
|
314
|
-
loop do
|
315
|
-
if peek == Escape
|
316
|
-
grab
|
317
|
-
str << grab
|
318
|
-
next
|
319
|
-
end
|
320
|
-
if terminate?(terminators, peek)
|
321
|
-
break
|
322
|
-
end
|
323
|
-
str << peek # not a terminator
|
324
|
-
grab
|
325
|
-
end
|
326
|
-
|
327
|
-
if peek == "]" # skip right bracket
|
328
|
-
grab
|
329
|
-
end
|
330
|
-
add str
|
331
|
-
str
|
332
|
-
rescue => err
|
333
|
-
::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
334
|
-
end
|
335
|
-
|
336
|
-
def escaped
|
337
|
-
grab # Eat the backslash
|
338
|
-
ch = grab # Take next char
|
339
|
-
ch
|
340
|
-
end
|
341
|
-
|
342
|
-
def collect!(sym, terminators, bracketed=nil)
|
343
|
-
return collect_bracketed(sym, terminators) if bracketed
|
344
|
-
|
345
|
-
str = Null.dup # next is not " ","*","["
|
346
|
-
grab # ZZZ
|
347
|
-
loop do
|
348
|
-
case
|
349
|
-
when peek.nil?
|
350
|
-
return str
|
351
|
-
when peek == Escape
|
352
|
-
str << escaped
|
353
|
-
next
|
354
|
-
when terminate?(terminators, peek)
|
355
|
-
break
|
356
|
-
else
|
357
|
-
str << peek # not a terminator
|
358
|
-
end
|
359
|
-
grab
|
360
|
-
end
|
361
|
-
ungrab
|
362
|
-
add str
|
363
|
-
str
|
364
|
-
rescue => err
|
365
|
-
::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
366
|
-
end
|
367
|
-
|
368
|
-
def varsub(name)
|
369
|
-
live = Livetext.new
|
370
|
-
value = live.vars[name]
|
371
|
-
result = value || "[#{name} is undefined]"
|
372
|
-
result
|
373
|
-
end
|
374
|
-
|
375
|
-
def embedded?
|
376
|
-
! (['"', "'", " ", nil].include? prev)
|
377
|
-
end
|
378
|
-
|
379
|
-
private
|
380
|
-
|
381
|
-
def eval_bits(sym, val)
|
382
|
-
val = Livetext.interpolate(val)
|
383
|
-
@out << embed(sym, val)
|
384
|
-
end
|
385
|
-
|
386
|
-
def eval_func(val, gen)
|
387
|
-
param = nil
|
388
|
-
arg = gen.peek rescue :bogus
|
389
|
-
unless arg == :bogus
|
390
|
-
if [:colon, :brackets].include? arg[0]
|
391
|
-
arg = gen.next # for real
|
392
|
-
param = arg[1]
|
393
|
-
# FIXME - unsure - interpolate again??
|
394
|
-
# param = Livetext.interpolate(param)
|
395
|
-
end
|
396
|
-
end
|
397
|
-
@out << funcall(val, param)
|
398
|
-
end
|
399
|
-
|
400
|
-
def eval_var(val)
|
401
|
-
@out << varsub(val)
|
402
|
-
end
|
403
|
-
|
404
|
-
def eval_str(val)
|
405
|
-
@out << val unless val == "\n" # BUG
|
406
|
-
end
|
407
|
-
|
408
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
ACTUAL | EXPECTED
|
2
|
-
Testing some more functions here... Testing some more functions here...
|
3
|
-
<p> <p>
|
4
|
-
|
5
|
-
Here I am calling a function with Here I am calling a function with
|
6
|
-
a colon parameter... a colon parameter...
|
7
|
-
<p> <p>
|
8
|
-
|
9
|
-
<p> <p>
|
10
|
-
|
11
|
-
Next let's <b>do</b>*something with our parameter: | Next let's <b>do</b> something with our parameter:
|
12
|
-
<p> <p>
|
13
|
-
|
14
|
-
I'll call these variants... I'll call these variants...
|
15
|
-
<p> <p>
|
16
|
-
|
17
|
-
"Motel" spelled backwards is letom :) "Motel" spelled backwards is letom :)
|
18
|
-
<p> <p>
|
19
|
-
|
20
|
-
"lamina" reversed is animal "lamina" reversed is animal
|
21
|
-
<p> <p>
|
22
|
-
|
23
|
-
I can also use the erutaef tekcarb here. I can also use the erutaef tekcarb here.
|
24
|
-
<p> <p>
|
25
|
-
|
26
|
-
If I don't use a parameter for [Error evaluating $$reverse( If I don't use a parameter for [Error evaluating $$reverse(
|
27
|
-
me an error. (Bug or feature??) me an error. (Bug or feature??)
|
28
|
-
<p> <p>
|
29
|
-
|
30
|
-
What if a function doesn't use parameters at all, but What if a function doesn't use parameters at all, but
|
31
|
-
we pass them? Hmm... we pass them? Hmm...
|
32
|
-
<p> <p>
|
33
|
-
|
34
|
-
Now we succeed and succeed some more Now we succeed and succeed some more
|
35
|
-
and finally we succeed in life. and finally we succeed in life.
|
36
|
-
<p> <p>
|
37
|
-
|
38
|
-
But can we succeed, when our beds are burning? But can we succeed, when our beds are burning?
|
data/test/testlines.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require '../lib/livetext'
|
2
|
-
require '../lib/formatline'
|
3
|
-
|
4
|
-
def red(str)
|
5
|
-
"[31m" + str + "[0m"
|
6
|
-
end
|
7
|
-
|
8
|
-
input = ARGV.first || "test/data/lines.txt"
|
9
|
-
data = File.readlines(input)
|
10
|
-
|
11
|
-
pass = fail = 0
|
12
|
-
data.each_slice(4).with_index do |lines, i|
|
13
|
-
title, input, expected, blank = *lines
|
14
|
-
lnum = i*4 + 1
|
15
|
-
input.chomp!
|
16
|
-
expected.chomp!
|
17
|
-
expected = eval(expected) if expected[0] == "/"
|
18
|
-
|
19
|
-
|
20
|
-
actual = FormatLine.parse!(input)
|
21
|
-
if expected === actual
|
22
|
-
pass += 1
|
23
|
-
# puts "PASS: #{title}"
|
24
|
-
next
|
25
|
-
end
|
26
|
-
|
27
|
-
fail += 1
|
28
|
-
puts "----------------------------- (line #{lnum})"
|
29
|
-
puts "Test: #{title}"
|
30
|
-
puts "Input: #{input}"
|
31
|
-
puts " #{red('FAIL Expected: ')} #{expected.inspect}"
|
32
|
-
puts " #{red(' Actual : ')} #{actual.inspect}"
|
33
|
-
puts
|
34
|
-
end
|
35
|
-
|
36
|
-
puts
|
37
|
-
puts "#{pass} passes #{fail} fails"
|