fOOrth 0.5.3 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 559890e4f92fd01b8c19f1da0906079b017f57b0
4
- data.tar.gz: ced8ded1201a853b006d486e4915c14b92decac0
3
+ metadata.gz: 1d0d6f091b373efebb5abe63ef8640ff9b6ccb19
4
+ data.tar.gz: ac4726f91899a582360c249d6a56fbdb5a392c6e
5
5
  SHA512:
6
- metadata.gz: 718ccfe382895223af46fdcf931cf02c24f5bde48594b825537d2cc53b218e52606792f063d8c3ced03d553a90797878214e44d4dff167cd52e1568c2f6195da
7
- data.tar.gz: 28afe39a7ccd28ee0c716bf54644a88a363d6830e81b9ab30801986ea38546c4df665be9fe3b43b8d0bfe0cf5086aee582bb6d9d9f4704d8edee04696bbbcf52
6
+ metadata.gz: 81570f5d034eb8507fb59a6121b0e205b3edcbfea451fcba3a49127a5a535ed92828b1fecd1da8a0359c802543f76830234201c38d9302dfe75024f489d8add5
7
+ data.tar.gz: 68e73dbaba411571709f779ba5b10f8af82a5d2a572be1fbc9b1bcf1a138c43cf02f344c91bf53f1dabd520699baee8d22ae754359dce8fb3c4976cd7982cf5f
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ InstalledFiles
11
11
  _yardoc
12
12
  coverage
13
13
  docs/.~lock.*
14
+ docs/The_fOOrth_User_Guide.pdf
14
15
  lib/bundler/man
15
16
  pkg
16
17
  rdoc
data/README.md CHANGED
@@ -7,6 +7,13 @@ past, but continued to grow and develop with the times. Above all this project
7
7
  is the result of nearly 30 years of thought on the design of threaded
8
8
  compilers and languages with simplified grammars and syntax.
9
9
 
10
+ ## Community
11
+
12
+ While it is still very much a work in progress, you are invited to see The
13
+ fOOrth Programming Language web site at:
14
+ <br>http://www.foorth.org/
15
+ <br>
16
+
10
17
  ## Usage
11
18
  Adding fOOrth can be as simple as:
12
19
 
@@ -45,7 +52,7 @@ version of fOOrth is made available, expect to see portable document format
45
52
 
46
53
  #### Plan A
47
54
 
48
- 1. Fork it
55
+ 1. Fork it ( https://github.com/PeterCamilleri/fOOrth/fork )
49
56
  2. Switch to the development branch ('git branch development')
50
57
  3. Create your feature branch ('git checkout -b my-new-feature')
51
58
  4. Commit your changes ('git commit -am "Add some feature"')
@@ -60,7 +67,4 @@ http://nvie.com/posts/a-successful-git-branching-model/
60
67
  #### Plan B
61
68
 
62
69
  Go to the GitHub repository and raise an issue calling attention to some
63
- aspect that could use some TLC or a suggestion or an idea. Apply labels
64
- to the issue that match the point you are trying to make. Then follow
65
- your issue and keep up-to-date as it is worked on. All input are greatly
66
- appreciated.
70
+ aspect that could use some TLC or a suggestion or an idea.
@@ -283,6 +283,8 @@ class ArrayLibraryTester < Minitest::Test
283
283
  foorth_equal('[ 9 3 5 ] [ 4 1 ] << ', [[9,3,5,[4,1]]])
284
284
  foorth_equal('[ 9 3 5 ] [ 4 1 ] << ', [[9,3,5,[4,1]]])
285
285
 
286
+ foorth_equal('[ 9 3 5 ] 0 >> ', [[0,9,3,5]])
287
+
286
288
  foorth_equal('[ 9 3 5 ] 0 + ', [[9,3,5,0]])
287
289
  foorth_equal('[ 9 3 5 ] [ 0 ] + ', [[9,3,5,0]])
288
290
  foorth_equal('[ 9 3 5 ] { } + ', [[9,3,5,{}]])
@@ -21,20 +21,27 @@ class CloneLibraryTester < Minitest::Test
21
21
  foorth_equal("33 clone identical?", [true])
22
22
  foorth_equal("33 clone distinct?", [false])
23
23
 
24
- foorth_equal('"33" clone identical?', [false])
25
- foorth_equal('"33" clone distinct?', [true])
24
+ foorth_equal('"33" clone identical?', [true])
25
+ foorth_equal('"33" clone distinct?', [false])
26
26
 
27
- foorth_equal('"33" dup .clone identical?', [false])
28
- foorth_equal('"33" dup .clone distinct?', [true])
27
+ foorth_equal('"33"* clone identical?', [false])
28
+ foorth_equal('"33"* clone distinct?', [true])
29
+
30
+ foorth_equal('"33" dup .clone identical?', [true])
31
+ foorth_equal('"33" dup .clone distinct?', [false])
32
+
33
+ foorth_equal('"33"* dup .clone identical?', [false])
34
+ foorth_equal('"33"* dup .clone distinct?', [true])
29
35
 
30
36
  foorth_equal('[ "33" ] clone distinct?', [true])
31
- foorth_equal('[ "33" ] clone @ swap @ distinct?', [true])
37
+ foorth_equal('[ "33" ] clone @ swap @ distinct?', [false])
38
+ foorth_equal('[ "33"* ] clone @ swap @ distinct?', [true])
32
39
 
33
40
  end
34
41
 
35
42
  def test_some_clone_exclusion
36
43
  foorth_run('class: Tscx')
37
- foorth_run('Tscx .: .init "a" val@: @a "b" val@: @b ;')
44
+ foorth_run('Tscx .: .init "a"* val@: @a "b"* val@: @b ;')
38
45
  foorth_run('Tscx .: .a @a ;')
39
46
  foorth_run('Tscx .: .b @b ;')
40
47
  foorth_run('Tscx .: .clone_exclude [ "@b" ] ;')
@@ -59,7 +66,7 @@ class CloneLibraryTester < Minitest::Test
59
66
  end
60
67
 
61
68
  def test_array_clone_exclusion
62
- foorth_run('[ "a" "b" ] val$: $tacx1')
69
+ foorth_run('[ "a"* "b"* ] val$: $tacx1')
63
70
  foorth_run('$tacx1 .:: .clone_exclude [ 1 ] ;')
64
71
  foorth_run('$tacx1 .clone val$: $tacx2')
65
72
 
@@ -77,7 +84,7 @@ class CloneLibraryTester < Minitest::Test
77
84
  end
78
85
 
79
86
  def test_hash_clone_exclusion
80
- foorth_run('{ 0 "a" -> 1 "b" -> } val$: $thcx1')
87
+ foorth_run('{ 0 "a"* -> 1 "b"* -> } val$: $thcx1')
81
88
  foorth_run('$thcx1 .:: .clone_exclude [ 1 ] ;')
82
89
  foorth_run('$thcx1 .clone val$: $thcx2')
83
90
 
@@ -98,11 +105,14 @@ class CloneLibraryTester < Minitest::Test
98
105
  foorth_equal("33 copy", [33,33])
99
106
  foorth_equal("33 .copy", [33])
100
107
 
101
- foorth_equal('"33" copy identical?', [false])
102
- foorth_equal('"33" copy distinct?', [true])
108
+ foorth_equal('"33" copy identical?', [true])
109
+ foorth_equal('"33" copy distinct?', [false])
110
+
111
+ foorth_equal('"33"* copy identical?', [false])
112
+ foorth_equal('"33"* copy distinct?', [true])
103
113
 
104
114
  foorth_equal('[ "33" ] copy distinct?', [true])
105
115
  foorth_equal('[ "33" ] copy @ swap @ distinct?', [false])
106
116
  end
107
117
 
108
- end
118
+ end
@@ -86,12 +86,15 @@ class StandardLibraryTester < Minitest::Test
86
86
  foorth_equal("33 33 identical?", [true])
87
87
  foorth_equal("33 33 distinct?", [false])
88
88
 
89
- foorth_equal('"33" "33" identical?', [false])
90
- foorth_equal('"33" "33" distinct?', [true])
89
+ foorth_equal('"33" "33" identical?', [true])
90
+ foorth_equal('"33" "33" distinct?', [false])
91
91
 
92
92
  foorth_equal('"33" dup identical?', [true])
93
93
  foorth_equal('"33" dup distinct?', [false])
94
94
 
95
+ foorth_equal('"33"* "33"* identical?', [false])
96
+ foorth_equal('"33"* "33"* distinct?', [true])
97
+
95
98
  end
96
99
 
97
100
  def test_dyadic_error_recovery
@@ -14,6 +14,25 @@ class StringLibraryTester < Minitest::Test
14
14
  #Track mini-test progress.
15
15
  include MinitestVisible
16
16
 
17
+ def test_string_classes
18
+ foorth_equal('String ', [String])
19
+ foorth_equal('"A" .class ', [String])
20
+ foorth_equal('"A" .to_s* .class', [StringBuffer])
21
+
22
+ foorth_equal('StringBuffer ', [StringBuffer])
23
+ foorth_equal('"A"* .class ', [StringBuffer])
24
+ foorth_equal('"A"* .to_s .class ', [String])
25
+
26
+ foorth_equal('String .new ', [""])
27
+ foorth_equal('StringBuffer .new ', [""])
28
+
29
+ foorth_equal('String .new .class', [String])
30
+ foorth_equal('StringBuffer .new .class', [StringBuffer])
31
+
32
+ foorth_equal('String .new .mutable?', [false])
33
+ foorth_equal('StringBuffer .new .mutable?', [true])
34
+ end
35
+
17
36
  def test_string_literals
18
37
  foorth_equal(' "" ', [""])
19
38
  foorth_equal(' "\"" ', ["\""])
@@ -39,6 +58,18 @@ class StringLibraryTester < Minitest::Test
39
58
 
40
59
  foorth_equal(' "a\\x55b" ', ["aUb"])
41
60
  foorth_equal(' "a\\u5555b" ', ["a\u5555b"])
61
+
62
+ foorth_equal('"A" .mutable?', [false])
63
+ foorth_equal('"A"* .mutable?', [true])
64
+ end
65
+
66
+ def test_that_strings_are_immutable
67
+ foorth_raises('"A" "B" <<')
68
+ end
69
+
70
+ def test_that_string_buffers_are_not
71
+ foorth_equal('"A"* "B" <<', ["AB"])
72
+ foorth_equal('"A"* "B" >>', ["BA"])
42
73
  end
43
74
 
44
75
  def test_file_loading
@@ -77,77 +108,257 @@ class StringLibraryTester < Minitest::Test
77
108
  def test_left_justification
78
109
  foorth_equal('5 "a" .ljust ', ['a '])
79
110
  foorth_equal('5 "too long" .ljust ', ['too long'])
111
+
112
+ foorth_equal('5 "a" .ljust .mutable?', [false])
113
+ foorth_equal('5 "a"* .ljust .class', [String])
80
114
  end
81
115
 
82
116
  def test_center_justification
83
117
  foorth_equal('5 "a" .cjust ', [' a '])
84
118
  foorth_equal('5 "too long" .cjust ', ['too long'])
119
+
120
+ foorth_equal('5 "a" .cjust .mutable?', [false])
121
+ foorth_equal('5 "a"* .cjust .class', [String])
85
122
  end
86
123
 
87
124
  def test_right_justification
88
125
  foorth_equal('5 "a" .rjust ', [' a'])
89
126
  foorth_equal('5 "too long" .rjust ', ['too long'])
127
+
128
+ foorth_equal('5 "a" .rjust .mutable?', [false])
129
+ foorth_equal('5 "a"* .rjust .class', [String])
90
130
  end
91
131
 
92
132
  def test_left_strip
93
133
  foorth_equal('" a " .lstrip ', ["a "])
134
+
135
+ foorth_equal('" a " .lstrip .mutable?', [false])
136
+ foorth_equal('" a " .lstrip .class', [String])
137
+
138
+ foorth_equal('" a "* .lstrip ', ["a "])
139
+ foorth_equal('" a "* .lstrip .class', [String])
140
+
141
+ foorth_run('" abc "* val$: $tls1')
142
+ foorth_equal('$tls1', [" abc "])
143
+ foorth_equal('$tls1 .lstrip*', [])
144
+ foorth_equal('$tls1 dup .class', ["abc ", StringBuffer])
94
145
  end
95
146
 
96
147
  def test_center_strip
97
148
  foorth_equal('" a " .strip ', ["a"])
149
+
150
+ foorth_equal('" a " .strip .mutable?', [false])
151
+ foorth_equal('" a " .strip .class', [String])
152
+
153
+ foorth_equal('" a "* .strip ', ["a"])
154
+ foorth_equal('" a "* .strip .class', [String])
155
+
156
+ foorth_run('" abc "* val$: $tcs1')
157
+ foorth_equal('$tcs1', [" abc "])
158
+ foorth_equal('$tcs1 .strip*', [])
159
+ foorth_equal('$tcs1 dup .class', ["abc", StringBuffer])
98
160
  end
99
161
 
100
162
  def test_right_strip
101
163
  foorth_equal('" a " .rstrip ', [" a"])
164
+
165
+ foorth_equal('" a " .rstrip .mutable?', [false])
166
+ foorth_equal('" a " .rstrip .class', [String])
167
+
168
+ foorth_equal('" a "* .rstrip ', [" a"])
169
+ foorth_equal('" a "* .rstrip .class', [String])
170
+
171
+ foorth_run('" abc "* val$: $trs1')
172
+ foorth_equal('$trs1', [" abc "])
173
+ foorth_equal('$trs1 .rstrip*', [])
174
+ foorth_equal('$trs1 dup .class', [" abc", StringBuffer])
102
175
  end
103
176
 
104
177
  def test_formatted_strings
105
178
  foorth_equal('5 "%03d" format ', ['005'])
106
179
  foorth_equal('5 f"%03d" ', ['005'])
180
+
181
+ foorth_equal('5 f"%03d" .mutable?', [false])
107
182
  end
108
183
 
109
184
  def test_left_copy_paste_and_cut
110
185
  foorth_equal('2 "abcdefgh" .left ', ['ab'])
186
+ foorth_equal('2 "abcdefgh"* .left ', ['ab'])
187
+ foorth_equal('2 "abcdefgh" .left .mutable?', [false])
188
+ foorth_equal('2 "abcdefgh"* .left .mutable?', [false])
189
+ foorth_equal('2 "abcdefgh" .left .class', [String])
190
+ foorth_equal('2 "abcdefgh"* .left .class', [String])
191
+
111
192
  foorth_equal('2 "123" "abcdefgh" .+left ', ['123cdefgh'])
193
+ foorth_equal('2 "123" "abcdefgh"* .+left ', ['123cdefgh'])
194
+ foorth_equal('2 "123" "abcdefgh" .+left .mutable?', [false])
195
+ foorth_equal('2 "123" "abcdefgh"* .+left .mutable?', [false])
196
+ foorth_equal('2 "123" "abcdefgh" .+left .class', [String])
197
+ foorth_equal('2 "123" "abcdefgh"* .+left .class', [String])
198
+
112
199
  foorth_equal('2 "abcdefgh" .-left ', ['cdefgh'])
200
+ foorth_equal('2 "abcdefgh"* .-left ', ['cdefgh'])
201
+ foorth_equal('2 "abcdefgh" .-left .mutable?', [false])
202
+ foorth_equal('2 "abcdefgh"* .-left .mutable?', [false])
203
+ foorth_equal('2 "abcdefgh" .-left .class', [String])
204
+ foorth_equal('2 "abcdefgh"* .-left .class', [String])
205
+
113
206
  foorth_equal('"abc" "abcdefgh" .left? ', [true])
114
207
  foorth_equal('"abx" "abcdefgh" .left? ', [false])
208
+ foorth_equal('"abc" "abcdefgh"* .left? ', [true])
209
+ foorth_equal('"abx" "abcdefgh"* .left? ', [false])
210
+ foorth_equal('"abc"* "abcdefgh" .left? ', [true])
211
+ foorth_equal('"abx"* "abcdefgh" .left? ', [false])
212
+ foorth_equal('"abc"* "abcdefgh"* .left? ', [true])
213
+ foorth_equal('"abx"* "abcdefgh"* .left? ', [false])
115
214
  end
116
215
 
117
216
  def test_right_copy_paste_and_cut
118
217
  foorth_equal('2 "abcdefgh" .right ', ['gh'])
218
+ foorth_equal('2 "abcdefgh"* .right ', ['gh'])
219
+ foorth_equal('2 "abcdefgh" .right .mutable?', [false])
220
+ foorth_equal('2 "abcdefgh"* .right .mutable?', [false])
221
+ foorth_equal('2 "abcdefgh" .right .class', [String])
222
+ foorth_equal('2 "abcdefgh"* .right .class', [String])
223
+
119
224
  foorth_equal('2 "123" "abcdefgh" .+right ', ['abcdef123'])
225
+ foorth_equal('2 "123" "abcdefgh"* .+right ', ['abcdef123'])
226
+ foorth_equal('2 "123" "abcdefgh" .+right .mutable?', [false])
227
+ foorth_equal('2 "123" "abcdefgh"* .+right .mutable?', [false])
228
+ foorth_equal('2 "123" "abcdefgh" .+right .class', [String])
229
+ foorth_equal('2 "123" "abcdefgh"* .+right .class', [String])
230
+
120
231
  foorth_equal('2 "abcdefgh" .-right ', ['abcdef'])
232
+ foorth_equal('2 "abcdefgh"* .-right ', ['abcdef'])
233
+ foorth_equal('2 "abcdefgh" .-right .mutable?', [false])
234
+ foorth_equal('2 "abcdefgh"* .-right .mutable?', [false])
235
+ foorth_equal('2 "abcdefgh" .-right .class', [String])
236
+ foorth_equal('2 "abcdefgh"* .-right .class', [String])
237
+
121
238
  foorth_equal('"fgh" "abcdefgh" .right? ', [true])
122
239
  foorth_equal('"fgx" "abcdefgh" .right? ', [false])
240
+ foorth_equal('"fgh" "abcdefgh"* .right? ', [true])
241
+ foorth_equal('"fgx" "abcdefgh"* .right? ', [false])
242
+ foorth_equal('"fgh"* "abcdefgh" .right? ', [true])
243
+ foorth_equal('"fgx"* "abcdefgh" .right? ', [false])
244
+ foorth_equal('"fgh"* "abcdefgh"* .right? ', [true])
245
+ foorth_equal('"fgx"* "abcdefgh"* .right? ', [false])
123
246
  end
124
247
 
125
248
  def test_mid_copy_paste_and_cut
126
249
  foorth_equal('2 4 "abcdefgh" .mid ', ['cdef'])
250
+ foorth_equal('2 4 "abcdefgh"* .mid ', ['cdef'])
251
+ foorth_equal('2 4 "abcdefgh" .mid .mutable?', [false])
252
+ foorth_equal('2 4 "abcdefgh"* .mid .mutable?', [false])
253
+ foorth_equal('2 4 "abcdefgh" .mid .class', [String])
254
+ foorth_equal('2 4 "abcdefgh"* .mid .class', [String])
255
+
127
256
  foorth_equal('2 4 "abcdefgh" .-mid ', ['abgh'])
257
+ foorth_equal('2 4 "abcdefgh"* .-mid ', ['abgh'])
258
+ foorth_equal('2 4 "abcdefgh" .-mid .mutable?', [false])
259
+ foorth_equal('2 4 "abcdefgh"* .-mid .mutable?', [false])
260
+ foorth_equal('2 4 "abcdefgh" .-mid .class', [String])
261
+ foorth_equal('2 4 "abcdefgh"* .-mid .class', [String])
262
+
128
263
  foorth_equal('2 4 "123" "abcdefgh" .+mid ', ['ab123gh'])
129
264
  foorth_equal('2 0 "123" "abcdefgh" .+mid ', ['ab123cdefgh'])
265
+ foorth_equal('2 4 "123" "abcdefgh"* .+mid ', ['ab123gh'])
266
+ foorth_equal('2 0 "123" "abcdefgh"* .+mid ', ['ab123cdefgh'])
267
+ foorth_equal('2 4 "123"* "abcdefgh" .+mid ', ['ab123gh'])
268
+ foorth_equal('2 0 "123"* "abcdefgh" .+mid ', ['ab123cdefgh'])
269
+ foorth_equal('2 4 "123"* "abcdefgh"* .+mid ', ['ab123gh'])
270
+ foorth_equal('2 0 "123"* "abcdefgh"* .+mid ', ['ab123cdefgh'])
271
+
272
+ foorth_equal('2 4 "123" "abcdefgh" .+mid .mutable?', [false])
273
+ foorth_equal('2 0 "123" "abcdefgh" .+mid .mutable?', [false])
274
+ foorth_equal('2 4 "123" "abcdefgh"* .+mid .mutable?', [false])
275
+ foorth_equal('2 0 "123" "abcdefgh"* .+mid .mutable?', [false])
276
+ foorth_equal('2 4 "123"* "abcdefgh" .+mid .mutable?', [false])
277
+ foorth_equal('2 0 "123"* "abcdefgh" .+mid .mutable?', [false])
278
+ foorth_equal('2 4 "123"* "abcdefgh"* .+mid .mutable?', [false])
279
+ foorth_equal('2 0 "123"* "abcdefgh"* .+mid .mutable?', [false])
280
+
281
+ foorth_equal('2 4 "123" "abcdefgh" .+mid .class', [String])
282
+ foorth_equal('2 0 "123" "abcdefgh" .+mid .class', [String])
283
+ foorth_equal('2 4 "123" "abcdefgh"* .+mid .class', [String])
284
+ foorth_equal('2 0 "123" "abcdefgh"* .+mid .class', [String])
285
+ foorth_equal('2 4 "123"* "abcdefgh" .+mid .class', [String])
286
+ foorth_equal('2 0 "123"* "abcdefgh" .+mid .class', [String])
287
+ foorth_equal('2 4 "123"* "abcdefgh"* .+mid .class', [String])
288
+ foorth_equal('2 0 "123"* "abcdefgh"* .+mid .class', [String])
130
289
  end
131
290
 
132
291
  def test_mid_find
133
292
  foorth_equal('2 "cde" "abcdefgh" .mid? ', [true])
134
293
  foorth_equal('3 "cde" "abcdefgh" .mid? ', [false])
294
+
295
+ foorth_equal('2 "cde"* "abcdefgh" .mid? ', [true])
296
+ foorth_equal('3 "cde"* "abcdefgh" .mid? ', [false])
297
+
298
+ foorth_equal('2 "cde" "abcdefgh"* .mid? ', [true])
299
+ foorth_equal('3 "cde" "abcdefgh"* .mid? ', [false])
300
+
301
+ foorth_equal('2 "cde"* "abcdefgh"* .mid? ', [true])
302
+ foorth_equal('3 "cde"* "abcdefgh"* .mid? ', [false])
135
303
  end
136
304
 
137
305
  def test_midlr_copy_paste_and_cut
138
306
  foorth_equal('2 2 "abcdefgh" .midlr ', ['cdef'])
307
+ foorth_equal('2 2 "abcdefgh"* .midlr ', ['cdef'])
308
+ foorth_equal('2 2 "abcdefgh" .midlr .mutable?', [false])
309
+ foorth_equal('2 2 "abcdefgh"* .midlr .mutable?', [false])
310
+ foorth_equal('2 2 "abcdefgh" .midlr .class', [String])
311
+ foorth_equal('2 2 "abcdefgh"* .midlr .class', [String])
312
+
139
313
  foorth_equal('2 2 "abcdefgh" .-midlr ', ['abgh'])
314
+ foorth_equal('2 2 "abcdefgh"* .-midlr ', ['abgh'])
315
+ foorth_equal('2 2 "abcdefgh" .-midlr .mutable?', [false])
316
+ foorth_equal('2 2 "abcdefgh"* .-midlr .mutable?', [false])
317
+ foorth_equal('2 2 "abcdefgh" .-midlr .class', [String])
318
+ foorth_equal('2 2 "abcdefgh"* .-midlr .class', [String])
319
+
140
320
  foorth_equal('2 2 "123" "abcdefgh" .+midlr ', ['ab123gh'])
321
+ foorth_equal('2 2 "123" "abcdefgh"*.+midlr ', ['ab123gh'])
322
+ foorth_equal('2 2 "123"* "abcdefgh" .+midlr ', ['ab123gh'])
323
+ foorth_equal('2 2 "123"* "abcdefgh"*.+midlr ', ['ab123gh'])
324
+
325
+ foorth_equal('2 2 "123" "abcdefgh" .+midlr .mutable?', [false])
326
+ foorth_equal('2 2 "123" "abcdefgh"*.+midlr .mutable?', [false])
327
+ foorth_equal('2 2 "123"* "abcdefgh" .+midlr .mutable?', [false])
328
+ foorth_equal('2 2 "123"* "abcdefgh"*.+midlr .mutable?', [false])
329
+
330
+ foorth_equal('2 2 "123" "abcdefgh" .+midlr .class', [String])
331
+ foorth_equal('2 2 "123" "abcdefgh"*.+midlr .class', [String])
332
+ foorth_equal('2 2 "123"* "abcdefgh" .+midlr .class', [String])
333
+ foorth_equal('2 2 "123"* "abcdefgh"*.+midlr .class', [String])
141
334
  end
142
335
 
143
336
  def test_string_contains
144
- foorth_equal('"cde" "abcdefgh" .contains? ', [true])
145
- foorth_equal('"cdx" "abcdefgh" .contains? ', [false])
337
+ foorth_equal('"cde" "abcdefgh" .contains? ', [true])
338
+ foorth_equal('"cdx" "abcdefgh" .contains? ', [false])
339
+
340
+ foorth_equal('"cde" "abcdefgh"* .contains? ', [true])
341
+ foorth_equal('"cdx" "abcdefgh"* .contains? ', [false])
342
+
343
+ foorth_equal('"cde"* "abcdefgh" .contains? ', [true])
344
+ foorth_equal('"cdx"* "abcdefgh" .contains? ', [false])
345
+
346
+ foorth_equal('"cde"* "abcdefgh"* .contains? ', [true])
347
+ foorth_equal('"cdx"* "abcdefgh"* .contains? ', [false])
146
348
  end
147
349
 
148
350
  def test_string_posn
149
- foorth_equal('"cde" "abcdefgh" .posn ', [2])
150
- foorth_equal('"cdx" "abcdefgh" .posn ', [nil])
351
+ foorth_equal('"cde" "abcdefgh" .posn ', [2])
352
+ foorth_equal('"cdx" "abcdefgh" .posn ', [nil])
353
+
354
+ foorth_equal('"cde" "abcdefgh"* .posn ', [2])
355
+ foorth_equal('"cdx" "abcdefgh"* .posn ', [nil])
356
+
357
+ foorth_equal('"cde"* "abcdefgh" .posn ', [2])
358
+ foorth_equal('"cdx"* "abcdefgh" .posn ', [nil])
359
+
360
+ foorth_equal('"cde"* "abcdefgh"* .posn ', [2])
361
+ foorth_equal('"cdx"* "abcdefgh"* .posn ', [nil])
151
362
  end
152
363
 
153
364
  def test_replication
@@ -155,30 +366,107 @@ class StringLibraryTester < Minitest::Test
155
366
  foorth_equal('"abc" 1 *', ['abc'])
156
367
  foorth_equal('"abc" 2 *', ['abcabc'])
157
368
  foorth_equal('"abc" 3 *', ['abcabcabc'])
369
+
370
+ foorth_equal('"abc"* 0 *', [''])
371
+ foorth_equal('"abc"* 1 *', ['abc'])
372
+ foorth_equal('"abc"* 2 *', ['abcabc'])
373
+ foorth_equal('"abc"* 3 *', ['abcabcabc'])
374
+
375
+ foorth_equal('"abc" 0 * .mutable?', [false])
376
+ foorth_equal('"abc" 1 * .mutable?', [false])
377
+ foorth_equal('"abc" 2 * .mutable?', [false])
378
+ foorth_equal('"abc" 3 * .mutable?', [false])
379
+
380
+ foorth_equal('"abc"* 0 * .mutable?', [false])
381
+ foorth_equal('"abc"* 1 * .mutable?', [false])
382
+ foorth_equal('"abc"* 2 * .mutable?', [false])
383
+ foorth_equal('"abc"* 3 * .mutable?', [false])
384
+
385
+ foorth_equal('"abc" 0 * .class', [String])
386
+ foorth_equal('"abc" 1 * .class', [String])
387
+ foorth_equal('"abc" 2 * .class', [String])
388
+ foorth_equal('"abc" 3 * .class', [String])
389
+
390
+ foorth_equal('"abc"* 0 * .class', [String])
391
+ foorth_equal('"abc"* 1 * .class', [String])
392
+ foorth_equal('"abc"* 2 * .class', [String])
393
+ foorth_equal('"abc"* 3 * .class', [String])
158
394
  end
159
395
 
160
396
  def test_concatenation
161
397
  foorth_equal('"abc" 0 +', ['abc0'])
162
- foorth_equal('"abc" "def" + ', ['abcdef'])
163
-
164
- foorth_equal('"abc" 0 <<', ['abc0'])
165
- foorth_equal('"abc" "def" << ', ['abcdef'])
166
-
167
- foorth_equal('"abc" dup "def" + distinct?', [true])
168
- foorth_equal('"abc" dup "def" << distinct?', [false])
398
+ foorth_equal('"abc"* 0 +', ['abc0'])
399
+ foorth_equal('"abc" 0 + .mutable?', [false])
400
+ foorth_equal('"abc"* 0 + .mutable?', [false])
401
+ foorth_equal('"abc" 0 + .class', [String])
402
+ foorth_equal('"abc"* 0 + .class', [String])
403
+
404
+ foorth_equal('"abc" "def" + ', ['abcdef'])
405
+ foorth_equal('"abc" "def"* + ', ['abcdef'])
406
+ foorth_equal('"abc"* "def" + ', ['abcdef'])
407
+ foorth_equal('"abc"* "def"* + ', ['abcdef'])
408
+
409
+ foorth_equal('"abc" "def" + .mutable?', [false])
410
+ foorth_equal('"abc" "def"* + .mutable?', [false])
411
+ foorth_equal('"abc"* "def" + .mutable?', [false])
412
+ foorth_equal('"abc"* "def"* + .mutable?', [false])
413
+
414
+ foorth_equal('"abc" "def" + .class', [String])
415
+ foorth_equal('"abc" "def"* + .class', [String])
416
+ foorth_equal('"abc"* "def" + .class', [String])
417
+ foorth_equal('"abc"* "def"* + .class', [String])
418
+
419
+ foorth_equal('"abc"* 0 <<', ['abc0'])
420
+ foorth_equal('"abc"* "def" << ', ['abcdef'])
421
+ foorth_equal('"abc"* "def"* << ', ['abcdef'])
422
+
423
+ foorth_equal(' "abc" dup "def" + distinct?', [true])
424
+ foorth_equal('"abc"* dup "def" << distinct?', [false])
169
425
  end
170
426
 
171
427
  def test_case_changing
172
- foorth_equal('"abcDEF" .to_upper', ['ABCDEF'])
173
- foorth_equal('"abcDEF" .to_lower', ['abcdef'])
428
+ foorth_equal('"abcDEF" .to_upper', ['ABCDEF'])
429
+ foorth_equal('"abcDEF"* .to_upper', ['ABCDEF'])
430
+ foorth_equal('"abcDEF" .to_upper .mutable?', [false])
431
+ foorth_equal('"abcDEF"* .to_upper .mutable?', [false])
432
+ foorth_equal('"abcDEF" .to_upper .class', [String])
433
+ foorth_equal('"abcDEF"* .to_upper .class', [String])
434
+
435
+ foorth_raises('"abcDEF" .to_upper*')
436
+ foorth_equal('"abcDEF"* dup .to_upper*', ['ABCDEF'])
437
+ foorth_equal('"abcDEF"* dup .to_upper* .mutable?', [true])
438
+ foorth_equal('"abcDEF"* dup .to_upper* .class', [StringBuffer])
439
+
440
+ foorth_equal('"abcDEF" .to_lower', ['abcdef'])
441
+ foorth_equal('"abcDEF"* .to_lower', ['abcdef'])
442
+ foorth_equal('"abcDEF" .to_lower .mutable?', [false])
443
+ foorth_equal('"abcDEF"* .to_lower .mutable?', [false])
444
+ foorth_equal('"abcDEF" .to_lower .class', [String])
445
+ foorth_equal('"abcDEF"* .to_lower .class', [String])
446
+
447
+ foorth_raises('"abcDEF" .to_lower*')
448
+ foorth_equal('"abcDEF"* dup .to_lower*', ['abcdef'])
449
+ foorth_equal('"abcDEF"* dup .to_lower* .mutable?', [true])
450
+ foorth_equal('"abcDEF"* dup .to_lower* .class', [StringBuffer])
174
451
  end
175
452
 
176
453
  def test_reversing
177
- foorth_equal('"stressed" .reverse', ['desserts'])
454
+ foorth_equal('"stressed" .reverse ', ['desserts'])
455
+ foorth_equal('"stressed"* .reverse ', ['desserts'])
456
+ foorth_equal('"stressed" .reverse .mutable?', [false])
457
+ foorth_equal('"stressed"* .reverse .mutable?', [false])
458
+ foorth_equal('"stressed" .reverse .class', [String])
459
+ foorth_equal('"stressed"* .reverse .class', [String])
460
+
461
+ foorth_raises('"stressed" .reverse*')
462
+ foorth_equal('"stressed"* dup .reverse* ', ['desserts'])
463
+ foorth_equal('"stressed"* dup .reverse* .mutable?', [true])
464
+ foorth_equal('"stressed"* dup .reverse* .class', [StringBuffer])
178
465
  end
179
466
 
180
467
  def test_the_each
181
468
  foorth_equal('"abc" .each{{ v x 1+ * }} ', ['a', 'bb', 'ccc'])
469
+ foorth_equal('"abc" .each{{ v .mutable? }} ', [false, false, false])
182
470
  end
183
471
 
184
472
  def test_calling_a_string
@@ -212,6 +500,8 @@ class StringLibraryTester < Minitest::Test
212
500
  s = "\"'quote' 'silly' \\\"un quote\\\" 'a \\\\'' \" p\"%q %*q %q %q\" "
213
501
  foorth_equal(s, [["quote", "un quote", "a '"]])
214
502
  foorth_equal('"a b c" p"%[a] %[b] %[c]"', [["a", "b", "c"]])
503
+
504
+ foorth_equal('"Hello World" p"%s %s" .map{{ v .mutable? }}', [[false, false]])
215
505
  end
216
506
 
217
507
  end