rpl 0.12.0 → 0.13.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/README.md +74 -0
- data/bin/rpl +8 -10
- data/lib/rpl/dictionary.rb +12 -12
- data/lib/rpl/interpreter.rb +4 -4
- data/lib/rpl/words/branch.rb +39 -39
- data/lib/rpl/words/display.rb +12 -12
- data/lib/rpl/words/filesystem.rb +25 -25
- data/lib/rpl/words/general.rb +32 -32
- data/lib/rpl/words/list.rb +34 -34
- data/lib/rpl/words/logarithm.rb +21 -21
- data/lib/rpl/words/mode.rb +24 -24
- data/lib/rpl/words/operations-complexes.rb +53 -53
- data/lib/rpl/words/operations-reals-complexes.rb +185 -185
- data/lib/rpl/words/operations-reals.rb +105 -105
- data/lib/rpl/words/program.rb +19 -19
- data/lib/rpl/words/repl.rb +65 -65
- data/lib/rpl/words/stack.rb +133 -133
- data/lib/rpl/words/store.rb +74 -74
- data/lib/rpl/words/string-list.rb +11 -11
- data/lib/rpl/words/string.rb +73 -73
- data/lib/rpl/words/test.rb +103 -103
- data/lib/rpl/words/time-date.rb +20 -20
- data/lib/rpl/words/trig.rb +47 -47
- data/lib/rpl.rb +3 -3
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81bb665b199a735ae446f0c00d77ca0d7f0e7d0ee2a6ca676f7c3dc159501fbb
|
4
|
+
data.tar.gz: 9b4bbb9d917e49d34d14a2457cf665fe4e701ed9bc89334c076c8c7fca0f1937
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddd530974f32189a9b76ea9bb932e8452eb6ccdeb88f06754bae7c085289bb2989e2fd165c8d234056657b91d8575ab388e6d19f32163e589033f4949eeb20bb
|
7
|
+
data.tar.gz: 6e64d40c9a72f72dce91254b450d53ab1a204a503599a7b92bf8c6ee1148c0ca6049bdcda9b611289d06aa34b9364f6a86832e20641d8acd44522276b715ad10
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# rpl.rb
|
2
|
+
|
3
|
+
Reverse-Polish-Lisp inspired language in ruby
|
4
|
+
|
5
|
+
# Install
|
6
|
+
`gem install rpl`
|
7
|
+
|
8
|
+
# Usage
|
9
|
+
* `rpl --help`
|
10
|
+
* run RPL: `rpl`
|
11
|
+
* by default rpl persists its state in ~/.local/state/rpl.rb/machine which is created if needed
|
12
|
+
|
13
|
+
# Development
|
14
|
+
To run REPL locally: `rake run`
|
15
|
+
|
16
|
+
To run the test suite: `rake test`
|
17
|
+
|
18
|
+
To build gem: `rake gem`
|
19
|
+
|
20
|
+
# known bugs
|
21
|
+
-
|
22
|
+
|
23
|
+
# TODO-list
|
24
|
+
* Language:
|
25
|
+
* pseudo filesystem: subdir/namespace for variables
|
26
|
+
. 'a dir' crdir 'a dir' cd vars
|
27
|
+
* SDL-based graphic environment/API
|
28
|
+
|
29
|
+
# Not yet implemented
|
30
|
+
```sh
|
31
|
+
$ grep "# @dictionary.add_word" ./lib/rpl/words/*.rb
|
32
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['ln'],
|
33
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['lnp1'],
|
34
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['exp'],
|
35
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['expm'],
|
36
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['log10'],
|
37
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['alog10'],
|
38
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['log2'],
|
39
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['alog2'],
|
40
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['sinh'],
|
41
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['asinh'],
|
42
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['cosh'],
|
43
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['acosh'],
|
44
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['tanh'],
|
45
|
+
./lib/rpl/words/logarithm.rb: # @dictionary.add_word!( ['atanh'],
|
46
|
+
./lib/rpl/words/mode.rb: # @dictionary.add_word!( ['std'],
|
47
|
+
./lib/rpl/words/mode.rb: # @dictionary.add_word!( ['fix'],
|
48
|
+
./lib/rpl/words/mode.rb: # @dictionary.add_word!( ['sci'],
|
49
|
+
./lib/rpl/words/mode.rb: # @dictionary.add_word!( ['round'],
|
50
|
+
./lib/rpl/words/operations-complexes.rb: # @dictionary.add_word!( ['p→r', 'p->r'],
|
51
|
+
./lib/rpl/words/operations-complexes.rb: # @dictionary.add_word!( ['r→p', 'r->p'],
|
52
|
+
```
|
53
|
+
|
54
|
+
# No implementation planned
|
55
|
+
* use IFT, IFTE instead of
|
56
|
+
. if
|
57
|
+
. then
|
58
|
+
. else
|
59
|
+
. end
|
60
|
+
* use LOOP, TIMES instead of
|
61
|
+
. start
|
62
|
+
. for
|
63
|
+
. next
|
64
|
+
. step
|
65
|
+
. do
|
66
|
+
. until
|
67
|
+
. while
|
68
|
+
. repeat
|
69
|
+
* use LSTO instead of
|
70
|
+
. ->, →
|
71
|
+
|
72
|
+
# inspirations and references
|
73
|
+
* https://en.wikipedia.org/wiki/RPL_(programming_language)
|
74
|
+
* https://github.com/louisrubet/rpn/
|
data/bin/rpl
CHANGED
@@ -19,7 +19,7 @@ class RplRepl
|
|
19
19
|
@interpreter = interpreter
|
20
20
|
end
|
21
21
|
|
22
|
-
def run
|
22
|
+
def run!
|
23
23
|
print_stack unless @interpreter.stack.empty?
|
24
24
|
|
25
25
|
Reline.completion_proc = proc do |s|
|
@@ -48,13 +48,13 @@ class RplRepl
|
|
48
48
|
prefill = @interpreter.stack.pop.to_s
|
49
49
|
elsif input.strip == 'history'
|
50
50
|
history = Reline::HISTORY.map { |line| "\"#{line}\"" }.join(' ')
|
51
|
-
@interpreter.run( "{ #{history} }" )
|
51
|
+
@interpreter.run!( "{ #{history} }" )
|
52
52
|
elsif input.empty?
|
53
53
|
# Remove blank lines from history
|
54
54
|
Reline::HISTORY.pop
|
55
55
|
else
|
56
56
|
begin
|
57
|
-
@interpreter.run( input )
|
57
|
+
@interpreter.run!( input )
|
58
58
|
rescue ArgumentError => e
|
59
59
|
pp e
|
60
60
|
end
|
@@ -117,17 +117,15 @@ interpreter = Rpl.new( persistence_filename: options[:persistence_filename],
|
|
117
117
|
|
118
118
|
# first run provided files if any
|
119
119
|
options[:files].each do |filename|
|
120
|
-
interpreter.run "\"#{File.expand_path( filename )}\" feval"
|
120
|
+
interpreter.run!( "\"#{File.expand_path( filename )}\" feval" )
|
121
121
|
end
|
122
122
|
|
123
123
|
# second run provided code if any
|
124
124
|
options[:programs].each do |program|
|
125
|
-
interpreter.run program
|
125
|
+
interpreter.run!( program )
|
126
126
|
end
|
127
127
|
|
128
128
|
# third launch REPL if (explicitely or implicitely) asked
|
129
|
-
if options[:run_REPL]
|
130
|
-
|
131
|
-
|
132
|
-
interpreter.persist_state
|
133
|
-
end
|
129
|
+
RplRepl.new( interpreter: interpreter ).run! if options[:run_REPL]
|
130
|
+
|
131
|
+
interpreter.persist_state
|
data/lib/rpl/dictionary.rb
CHANGED
@@ -11,7 +11,7 @@ class Dictionary
|
|
11
11
|
@local_vars_layers = []
|
12
12
|
end
|
13
13
|
|
14
|
-
def add_word( names, category, help, implementation )
|
14
|
+
def add_word!( names, category, help, implementation )
|
15
15
|
names.each do |name|
|
16
16
|
@words[ name ] = { category: category,
|
17
17
|
help: help,
|
@@ -19,43 +19,43 @@ class Dictionary
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def add_var( name, implementation )
|
22
|
+
def add_var!( name, implementation )
|
23
23
|
@vars[ name ] = implementation
|
24
24
|
end
|
25
25
|
|
26
|
-
def remove_vars( names )
|
26
|
+
def remove_vars!( names )
|
27
27
|
names.each do |name|
|
28
28
|
@vars.delete( name )
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def remove_var( name )
|
33
|
-
remove_vars( [name] )
|
32
|
+
def remove_var!( name )
|
33
|
+
remove_vars!( [name] )
|
34
34
|
end
|
35
35
|
|
36
|
-
def remove_all_vars
|
36
|
+
def remove_all_vars!
|
37
37
|
@vars = {}
|
38
38
|
end
|
39
39
|
|
40
|
-
def add_local_vars_layer
|
40
|
+
def add_local_vars_layer!
|
41
41
|
@local_vars_layers << {}
|
42
42
|
end
|
43
43
|
|
44
|
-
def add_local_var( name, implementation )
|
44
|
+
def add_local_var!( name, implementation )
|
45
45
|
@local_vars_layers.last[ name ] = implementation
|
46
46
|
end
|
47
47
|
|
48
|
-
def remove_local_vars( names )
|
48
|
+
def remove_local_vars!( names )
|
49
49
|
names.each do |name|
|
50
50
|
@local_vars_layers.last.delete( name )
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def remove_local_var( name )
|
54
|
+
def remove_local_var!( name )
|
55
55
|
remove_local_vars( [name] )
|
56
56
|
end
|
57
57
|
|
58
|
-
def remove_local_vars_layer
|
58
|
+
def remove_local_vars_layer!
|
59
59
|
@local_vars_layers.pop
|
60
60
|
end
|
61
61
|
|
@@ -68,7 +68,7 @@ class Dictionary
|
|
68
68
|
word ||= @vars[ name ]
|
69
69
|
|
70
70
|
# or is it a core word
|
71
|
-
word ||= @words[ name ].nil? ? nil : @words[ name ][:implementation]
|
71
|
+
word ||= @words[ name.downcase ].nil? ? nil : @words[ name.downcase ][:implementation]
|
72
72
|
|
73
73
|
word
|
74
74
|
end
|
data/lib/rpl/interpreter.rb
CHANGED
@@ -47,8 +47,8 @@ class Interpreter
|
|
47
47
|
@frame_buffer = BitArray.new
|
48
48
|
end
|
49
49
|
|
50
|
-
def run( input )
|
51
|
-
@dictionary.add_local_vars_layer
|
50
|
+
def run!( input )
|
51
|
+
@dictionary.add_local_vars_layer!
|
52
52
|
|
53
53
|
Parser.parse( input.to_s ).each do |elt|
|
54
54
|
if elt.instance_of?( RplName )
|
@@ -64,7 +64,7 @@ class Interpreter
|
|
64
64
|
elsif command.is_a?( Proc )
|
65
65
|
command.call
|
66
66
|
elsif command.instance_of?( RplProgram )
|
67
|
-
run( command.value )
|
67
|
+
run!( command.value )
|
68
68
|
else
|
69
69
|
@stack << command
|
70
70
|
end
|
@@ -74,7 +74,7 @@ class Interpreter
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
@dictionary.remove_local_vars_layer
|
77
|
+
@dictionary.remove_local_vars_layer!
|
78
78
|
|
79
79
|
# superfluous but feels nice
|
80
80
|
@stack
|
data/lib/rpl/words/branch.rb
CHANGED
@@ -10,45 +10,45 @@ module RplLang
|
|
10
10
|
|
11
11
|
category = 'Branch'
|
12
12
|
|
13
|
-
@dictionary.add_word( ['ift'],
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@dictionary.add_word( ['ifte'],
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@dictionary.add_word( ['times'],
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@dictionary.add_word( ['loop'],
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
13
|
+
@dictionary.add_word!( ['ift'],
|
14
|
+
category,
|
15
|
+
'( t pt -- … ) eval pt or not based on the value of boolean t',
|
16
|
+
Types.new_object( RplProgram, '« « nop » ifte »' ) )
|
17
|
+
|
18
|
+
@dictionary.add_word!( ['ifte'],
|
19
|
+
category,
|
20
|
+
'( t pt pf -- … ) eval pt or pf based on the value of boolean t',
|
21
|
+
proc do
|
22
|
+
args = stack_extract( [:any, :any, [RplBoolean]] )
|
23
|
+
|
24
|
+
run!( args[ args[2].value ? 1 : 0 ].value )
|
25
|
+
end )
|
26
|
+
|
27
|
+
@dictionary.add_word!( ['times'],
|
28
|
+
category,
|
29
|
+
'( p n -- … ) eval p n times while pushing counter on stack before',
|
30
|
+
proc do
|
31
|
+
args = stack_extract( [[RplNumeric], :any] )
|
32
|
+
|
33
|
+
args[0].value.to_i.times do |counter|
|
34
|
+
@stack << Types.new_object( RplNumeric, counter )
|
35
|
+
|
36
|
+
run!( args[1].value )
|
37
|
+
end
|
38
|
+
end )
|
39
|
+
|
40
|
+
@dictionary.add_word!( ['loop'],
|
41
|
+
category,
|
42
|
+
'( p n1 n2 -- … ) eval p looping from n1 to n2 while pushing counter on stack before',
|
43
|
+
proc do
|
44
|
+
args = stack_extract( [[RplNumeric], [RplNumeric], :any] )
|
45
|
+
|
46
|
+
((args[1].value.to_i)..(args[0].value.to_i)).each do |counter|
|
47
|
+
@stack << Types.new_object( RplNumeric, counter )
|
48
|
+
|
49
|
+
run!( args[2].value )
|
50
|
+
end
|
51
|
+
end )
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/rpl/words/display.rb
CHANGED
@@ -10,19 +10,19 @@ module RplLang
|
|
10
10
|
|
11
11
|
category = 'Display'
|
12
12
|
|
13
|
-
@dictionary.add_word( ['erase'],
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
@dictionary.add_word!( ['erase'],
|
14
|
+
category,
|
15
|
+
'( -- ) erase display',
|
16
|
+
proc do
|
17
|
+
initialize_frame_buffer
|
18
|
+
end )
|
19
19
|
|
20
|
-
@dictionary.add_word( ['display→', 'display->'],
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
@dictionary.add_word!( ['display→', 'display->'],
|
21
|
+
category,
|
22
|
+
'( -- pict ) put current display state on stack',
|
23
|
+
proc do
|
24
|
+
@stack << @frame_buffer # FIXME: RplPict type
|
25
|
+
end )
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
data/lib/rpl/words/filesystem.rb
CHANGED
@@ -10,31 +10,31 @@ module RplLang
|
|
10
10
|
|
11
11
|
category = 'Filesystem'
|
12
12
|
|
13
|
-
@dictionary.add_word( ['fread'],
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@dictionary.add_word( ['feval'],
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@dictionary.add_word( ['fwrite'],
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
13
|
+
@dictionary.add_word!( ['fread'],
|
14
|
+
category,
|
15
|
+
'( filename -- content ) read file and put content on stack as string',
|
16
|
+
proc do
|
17
|
+
args = stack_extract( [[RplString]] )
|
18
|
+
|
19
|
+
path = File.expand_path( args[0].value )
|
20
|
+
|
21
|
+
@stack << Types.new_object( RplString, "\"#{File.read( path )}\"" )
|
22
|
+
end )
|
23
|
+
|
24
|
+
@dictionary.add_word!( ['feval'],
|
25
|
+
category,
|
26
|
+
'( filename -- … ) read and run file',
|
27
|
+
Types.new_object( RplProgram, '« fread eval »' ) )
|
28
|
+
|
29
|
+
@dictionary.add_word!( ['fwrite'],
|
30
|
+
category,
|
31
|
+
'( content filename -- ) write content into filename',
|
32
|
+
proc do
|
33
|
+
args = stack_extract( [[RplString], :any] )
|
34
|
+
|
35
|
+
File.write( File.expand_path( args[0].value ),
|
36
|
+
args[1].value )
|
37
|
+
end )
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
data/lib/rpl/words/general.rb
CHANGED
@@ -10,38 +10,38 @@ module RplLang
|
|
10
10
|
|
11
11
|
category = 'General'
|
12
12
|
|
13
|
-
@dictionary.add_word( ['nop'],
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@dictionary.add_word( ['help'],
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@dictionary.add_word( ['quit'],
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@dictionary.add_word( ['version'],
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@dictionary.add_word( ['uname'],
|
42
|
-
|
43
|
-
|
44
|
-
|
13
|
+
@dictionary.add_word!( ['nop'],
|
14
|
+
category,
|
15
|
+
'( -- ) no operation',
|
16
|
+
proc {} )
|
17
|
+
|
18
|
+
@dictionary.add_word!( ['help'],
|
19
|
+
category,
|
20
|
+
'( w -- s ) pop help string of the given word',
|
21
|
+
proc do
|
22
|
+
args = stack_extract( [[RplName]] )
|
23
|
+
|
24
|
+
word = @dictionary.words[ args[0].value ]
|
25
|
+
|
26
|
+
@stack << Types.new_object( RplString, "\"#{args[0].value}: #{word.nil? ? 'not a core word' : word[:help]}\"" )
|
27
|
+
end )
|
28
|
+
|
29
|
+
@dictionary.add_word!( ['quit'],
|
30
|
+
category,
|
31
|
+
'( -- ) Stop and quit interpreter',
|
32
|
+
proc {} )
|
33
|
+
|
34
|
+
@dictionary.add_word!( ['version'],
|
35
|
+
category,
|
36
|
+
'( -- n ) Pop the interpreter\'s version number',
|
37
|
+
proc do
|
38
|
+
@stack << Types.new_object( RplString, "\"#{Rpl::VERSION}\"" )
|
39
|
+
end )
|
40
|
+
|
41
|
+
@dictionary.add_word!( ['uname'],
|
42
|
+
category,
|
43
|
+
'( -- s ) Pop the interpreter\'s complete indentification string',
|
44
|
+
Types.new_object( RplProgram, '« "Rpl Interpreter version " version + »' ) )
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/lib/rpl/words/list.rb
CHANGED
@@ -10,40 +10,40 @@ module RplLang
|
|
10
10
|
|
11
11
|
category = 'Lists'
|
12
12
|
|
13
|
-
@dictionary.add_word( ['→list', '->list'],
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@dictionary.add_word( ['list→', 'list->'],
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@dictionary.add_word( ['dolist'],
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
13
|
+
@dictionary.add_word!( ['→list', '->list'],
|
14
|
+
category,
|
15
|
+
'( … x -- […] ) pack x stacks levels into a list',
|
16
|
+
proc do
|
17
|
+
args = stack_extract( [[RplNumeric]] )
|
18
|
+
args = stack_extract( %i[any] * args[0].value )
|
19
|
+
|
20
|
+
@stack << Types.new_object( RplList, args.reverse )
|
21
|
+
end )
|
22
|
+
|
23
|
+
@dictionary.add_word!( ['list→', 'list->'],
|
24
|
+
category,
|
25
|
+
'( […] -- … ) unpack list on stack',
|
26
|
+
proc do
|
27
|
+
args = stack_extract( [[RplList]] )
|
28
|
+
|
29
|
+
args[0].value.each do |elt|
|
30
|
+
@stack << elt
|
31
|
+
end
|
32
|
+
end )
|
33
|
+
|
34
|
+
@dictionary.add_word!( ['dolist'],
|
35
|
+
category,
|
36
|
+
'( […] prg -- … ) run prg on each element of a list',
|
37
|
+
proc do
|
38
|
+
args = stack_extract( [[RplProgram], [RplList]] )
|
39
|
+
|
40
|
+
args[1].value.each do |elt|
|
41
|
+
@stack << elt
|
42
|
+
run!( args[0].value )
|
43
|
+
end
|
44
|
+
|
45
|
+
run!( "#{args[1].value.length} →list" )
|
46
|
+
end )
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|