fOOrth 0.5.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 +7 -0
- data/.gitignore +21 -0
- data/.rdoc_options +17 -0
- data/Gemfile +4 -0
- data/README.md +67 -0
- data/bin/fOOrth +8 -0
- data/demo.rb +24 -0
- data/fOOrth.gemspec +40 -0
- data/fOOrth.reek +109 -0
- data/integration/README.md +12 -0
- data/integration/_FILE_test.foorth +5 -0
- data/integration/array_lib_tests.rb +360 -0
- data/integration/class_lib_tests.rb +116 -0
- data/integration/clone_lib_tests.rb +108 -0
- data/integration/comparison_tests.rb +132 -0
- data/integration/compile_lib_tests.rb +190 -0
- data/integration/ctrl_struct_lib_tests.rb +80 -0
- data/integration/data_ref_lib_tests.rb +43 -0
- data/integration/exception_lib_tests.rb +86 -0
- data/integration/fiber_bundle_tests.rb +380 -0
- data/integration/hash_lib_tests.rb +120 -0
- data/integration/in_stream_test_1.txt +4 -0
- data/integration/load_test_one.foorth +6 -0
- data/integration/load_test_two.foorth +4 -0
- data/integration/numeric_lib_tests.rb +321 -0
- data/integration/object_lib_tests.rb +38 -0
- data/integration/procedure_lib_tests.rb +40 -0
- data/integration/queue_lib_tests.rb +66 -0
- data/integration/stack_lib_tests.rb +70 -0
- data/integration/standard_lib_tests.rb +208 -0
- data/integration/stdio_lib_tests.rb +52 -0
- data/integration/stream_lib_tests.rb +196 -0
- data/integration/string_lib_tests.rb +217 -0
- data/integration/support/foorth_testing.rb +135 -0
- data/integration/thread_lib_tests.rb +83 -0
- data/integration/time_lib_tests.rb +791 -0
- data/integration/vm_lib_tests.rb +38 -0
- data/lib/fOOrth.rb +57 -0
- data/lib/fOOrth/compiler.rb +78 -0
- data/lib/fOOrth/compiler/context.rb +49 -0
- data/lib/fOOrth/compiler/context/locals.rb +34 -0
- data/lib/fOOrth/compiler/context/map_name.rb +92 -0
- data/lib/fOOrth/compiler/context/tags.rb +48 -0
- data/lib/fOOrth/compiler/modes.rb +32 -0
- data/lib/fOOrth/compiler/modes/compiled.rb +41 -0
- data/lib/fOOrth/compiler/modes/deferred.rb +57 -0
- data/lib/fOOrth/compiler/modes/delayed.rb +40 -0
- data/lib/fOOrth/compiler/modes/nested.rb +34 -0
- data/lib/fOOrth/compiler/modes/suspend.rb +32 -0
- data/lib/fOOrth/compiler/parser.rb +26 -0
- data/lib/fOOrth/compiler/parser/get_string.rb +71 -0
- data/lib/fOOrth/compiler/parser/normal.rb +53 -0
- data/lib/fOOrth/compiler/parser/skip.rb +50 -0
- data/lib/fOOrth/compiler/parser/special.rb +42 -0
- data/lib/fOOrth/compiler/process.rb +47 -0
- data/lib/fOOrth/compiler/process/generate.rb +24 -0
- data/lib/fOOrth/compiler/process/get_token.rb +23 -0
- data/lib/fOOrth/compiler/process/procedure.rb +55 -0
- data/lib/fOOrth/compiler/process/string.rb +20 -0
- data/lib/fOOrth/compiler/source.rb +51 -0
- data/lib/fOOrth/compiler/source/console.rb +70 -0
- data/lib/fOOrth/compiler/source/file_source.rb +37 -0
- data/lib/fOOrth/compiler/source/read_point.rb +46 -0
- data/lib/fOOrth/compiler/source/string_source.rb +28 -0
- data/lib/fOOrth/compiler/token.rb +37 -0
- data/lib/fOOrth/compiler/word_specs.rb +178 -0
- data/lib/fOOrth/core.rb +27 -0
- data/lib/fOOrth/core/class.rb +116 -0
- data/lib/fOOrth/core/object.rb +78 -0
- data/lib/fOOrth/core/virtual_machine.rb +28 -0
- data/lib/fOOrth/debug.rb +13 -0
- data/lib/fOOrth/debug/context_dump.rb +31 -0
- data/lib/fOOrth/debug/dbg_puts.rb +17 -0
- data/lib/fOOrth/debug/display_abort.rb +37 -0
- data/lib/fOOrth/debug/vm_dump.rb +27 -0
- data/lib/fOOrth/initialize.rb +83 -0
- data/lib/fOOrth/interpreter.rb +24 -0
- data/lib/fOOrth/interpreter/add_to_hash.rb +17 -0
- data/lib/fOOrth/interpreter/data_stack.rb +125 -0
- data/lib/fOOrth/interpreter/do_loop.rb +55 -0
- data/lib/fOOrth/interpreter/squash.rb +25 -0
- data/lib/fOOrth/library.rb +38 -0
- data/lib/fOOrth/library/array_library.rb +577 -0
- data/lib/fOOrth/library/bundle_library.rb +112 -0
- data/lib/fOOrth/library/class_library.rb +90 -0
- data/lib/fOOrth/library/clone_library.rb +72 -0
- data/lib/fOOrth/library/command_library.rb +205 -0
- data/lib/fOOrth/library/compile_library.rb +181 -0
- data/lib/fOOrth/library/complex_library.rb +81 -0
- data/lib/fOOrth/library/ctrl_struct_library.rb +116 -0
- data/lib/fOOrth/library/data_ref_library.rb +100 -0
- data/lib/fOOrth/library/duration/arithmetic.rb +114 -0
- data/lib/fOOrth/library/duration/formatter.rb +152 -0
- data/lib/fOOrth/library/duration/intervals.rb +233 -0
- data/lib/fOOrth/library/duration/make.rb +75 -0
- data/lib/fOOrth/library/duration_library.rb +52 -0
- data/lib/fOOrth/library/fiber_library.rb +120 -0
- data/lib/fOOrth/library/hash_library.rb +203 -0
- data/lib/fOOrth/library/in_stream_library.rb +81 -0
- data/lib/fOOrth/library/integer_library.rb +104 -0
- data/lib/fOOrth/library/mutex_library.rb +31 -0
- data/lib/fOOrth/library/numeric_library.rb +380 -0
- data/lib/fOOrth/library/object_library.rb +80 -0
- data/lib/fOOrth/library/other_value_types_library.rb +96 -0
- data/lib/fOOrth/library/out_stream_library.rb +146 -0
- data/lib/fOOrth/library/procedure_library.rb +65 -0
- data/lib/fOOrth/library/queue_library.rb +47 -0
- data/lib/fOOrth/library/rational_library.rb +90 -0
- data/lib/fOOrth/library/stack_library.rb +56 -0
- data/lib/fOOrth/library/stdio_library.rb +56 -0
- data/lib/fOOrth/library/string_library.rb +285 -0
- data/lib/fOOrth/library/stubs.rb +76 -0
- data/lib/fOOrth/library/sync_bundle_library.rb +50 -0
- data/lib/fOOrth/library/thread_library.rb +73 -0
- data/lib/fOOrth/library/time_library.rb +302 -0
- data/lib/fOOrth/library/vm_library.rb +105 -0
- data/lib/fOOrth/main.rb +125 -0
- data/lib/fOOrth/monkey_patch.rb +14 -0
- data/lib/fOOrth/monkey_patch/complex.rb +30 -0
- data/lib/fOOrth/monkey_patch/exceptions.rb +154 -0
- data/lib/fOOrth/monkey_patch/false.rb +11 -0
- data/lib/fOOrth/monkey_patch/float.rb +22 -0
- data/lib/fOOrth/monkey_patch/integer.rb +22 -0
- data/lib/fOOrth/monkey_patch/nil.rb +11 -0
- data/lib/fOOrth/monkey_patch/numeric.rb +33 -0
- data/lib/fOOrth/monkey_patch/object.rb +43 -0
- data/lib/fOOrth/monkey_patch/rational.rb +31 -0
- data/lib/fOOrth/monkey_patch/string.rb +51 -0
- data/lib/fOOrth/symbol_map.rb +82 -0
- data/lib/fOOrth/version.rb +7 -0
- data/license.txt +21 -0
- data/rakefile.rb +65 -0
- data/reek.txt +1 -0
- data/sire.rb +132 -0
- data/t.txt +3 -0
- data/test.foorth +5 -0
- data/tests/compiler/context_tests.rb +180 -0
- data/tests/compiler/file_source_test_one.txt +1 -0
- data/tests/compiler/file_source_test_three.txt +3 -0
- data/tests/compiler/file_source_test_two.txt +3 -0
- data/tests/compiler/file_source_tests.rb +130 -0
- data/tests/compiler/mode_tests.rb +45 -0
- data/tests/compiler/parser_tests.rb +116 -0
- data/tests/compiler/spec_tests.rb +113 -0
- data/tests/compiler/string_source_tests.rb +128 -0
- data/tests/core_tests.rb +138 -0
- data/tests/interpreter/data_stack_tests.rb +119 -0
- data/tests/monkey_patch/coerce_test.rb +131 -0
- data/tests/monkey_patch/complex_test.rb +25 -0
- data/tests/monkey_patch/numeric_test.rb +62 -0
- data/tests/monkey_patch/object_test.rb +49 -0
- data/tests/monkey_patch/rational_test.rb +57 -0
- data/tests/monkey_patch/string_test.rb +53 -0
- data/tests/symbol_map_tests.rb +53 -0
- metadata +366 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/fOOrth'
|
|
4
|
+
require_relative 'support/foorth_testing'
|
|
5
|
+
gem 'minitest'
|
|
6
|
+
require 'minitest/autorun'
|
|
7
|
+
require 'minitest_visible'
|
|
8
|
+
|
|
9
|
+
#Test the standard fOOrth library.
|
|
10
|
+
class InOutStreamLibraryTester < Minitest::Test
|
|
11
|
+
|
|
12
|
+
include XfOOrthTestExtensions
|
|
13
|
+
|
|
14
|
+
#Track mini-test progress.
|
|
15
|
+
include MinitestVisible
|
|
16
|
+
|
|
17
|
+
# **** In Streams ****
|
|
18
|
+
|
|
19
|
+
$isfn = '"integration/in_stream_test_1.txt" '
|
|
20
|
+
|
|
21
|
+
def test_that_class_exists
|
|
22
|
+
foorth_equal('InStream', [XfOOrth::XfOOrth_InStream])
|
|
23
|
+
foorth_equal('InStream .name', ['InStream'])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_that_new_is_a_stub
|
|
27
|
+
foorth_raises('InStream .new')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_opening_and_reading_a_character
|
|
31
|
+
foorth_equal($isfn + 'InStream .open dup .getc swap .close', ['T'])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_opening_and_reading_a_line
|
|
35
|
+
foorth_equal($isfn + 'InStream .open dup .gets swap .close', ['Test 1 2 3'])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_open_block_and_reading_a_character
|
|
39
|
+
foorth_equal($isfn + 'InStream .open{{ ~getc }}', ['T'])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_open_block_and_reading_a_line
|
|
43
|
+
foorth_equal($isfn + 'InStream .open{{ ~gets }}', ['Test 1 2 3'])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_opening_and_reading_all_lines
|
|
47
|
+
all_lines = ["Test 1 2 3",
|
|
48
|
+
"Test 4 5 6",
|
|
49
|
+
"ABCDEFG",
|
|
50
|
+
"Eric the Half a Bee"]
|
|
51
|
+
|
|
52
|
+
foorth_equal($isfn + 'InStream .get_all', [all_lines])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# **** Out Streams ****
|
|
56
|
+
|
|
57
|
+
$osfn = '"integration/out_stream_test_1.txt" '
|
|
58
|
+
|
|
59
|
+
def test_that_class_exists
|
|
60
|
+
foorth_equal('OutStream', [XfOOrth::XfOOrth_OutStream])
|
|
61
|
+
foorth_equal('OutStream .name', ['OutStream'])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_that_new_is_a_stub
|
|
65
|
+
foorth_raises('OutStream .new')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_that_we_can_write
|
|
70
|
+
foorth_equal($osfn + 'OutStream .create .close')
|
|
71
|
+
assert(File.exists?($osfn[1...-2]))
|
|
72
|
+
do_cleanup
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_that_we_can_write_block
|
|
76
|
+
foorth_equal($osfn + 'OutStream .create{{ }}')
|
|
77
|
+
assert(File.exists?($osfn[1...-2]))
|
|
78
|
+
do_cleanup
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_that_we_can_write_stuff
|
|
83
|
+
foorth_equal($osfn + 'OutStream .create dup 42 swap . .close')
|
|
84
|
+
assert_equal(["42"], IO.readlines($osfn[1...-2]))
|
|
85
|
+
do_cleanup
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_that_we_can_write_block_stuff
|
|
89
|
+
foorth_equal($osfn + 'OutStream .create{{ 42 ~ }}')
|
|
90
|
+
assert_equal(["42"], IO.readlines($osfn[1...-2]))
|
|
91
|
+
do_cleanup
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_that_we_can_write_stuff_too
|
|
96
|
+
foorth_run($osfn + 'OutStream .create dup .with{{ ~"Hello World" }} .close')
|
|
97
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
98
|
+
do_cleanup
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_that_we_can_write_block_stuff_too
|
|
102
|
+
foorth_equal($osfn + 'OutStream .create{{ ~"Hello World" }}')
|
|
103
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
104
|
+
do_cleanup
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_that_we_can_write_a_character
|
|
109
|
+
foorth_equal($osfn + 'OutStream .create 65 over .emit .close')
|
|
110
|
+
assert_equal(["A"], IO.readlines($osfn[1...-2]))
|
|
111
|
+
do_cleanup
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_that_we_can_write_block_a_character
|
|
115
|
+
foorth_equal($osfn + 'OutStream .create{{ 65 ~emit }}')
|
|
116
|
+
assert_equal(["A"], IO.readlines($osfn[1...-2]))
|
|
117
|
+
do_cleanup
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def test_that_we_can_write_out_lines
|
|
122
|
+
foorth_run($osfn + 'OutStream .create .with{{ ~"Hello" ~cr ~"World" self .close }}')
|
|
123
|
+
assert_equal(["Hello\n", "World"], IO.readlines($osfn[1...-2]))
|
|
124
|
+
do_cleanup
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_that_we_can_block_write_out_lines
|
|
128
|
+
foorth_equal($osfn + 'OutStream .create{{ ~"Hello" ~cr ~"World" }}', [])
|
|
129
|
+
assert_equal(["Hello\n", "World"], IO.readlines($osfn[1...-2]))
|
|
130
|
+
do_cleanup
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_that_we_can_write_out_a_space
|
|
135
|
+
foorth_run($osfn + 'OutStream .create .with{{ ~"Hello" self .space ~"World" self .close }}')
|
|
136
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
137
|
+
do_cleanup
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_that_we_can_block_write_out_a_space
|
|
141
|
+
foorth_equal($osfn + 'OutStream .create{{ ~"Hello" ~space ~"World" }}', [])
|
|
142
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
143
|
+
do_cleanup
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_that_we_can_write_out_spaces
|
|
148
|
+
foorth_run($osfn + 'OutStream .create .with{{ ~"Hello" 3 self .spaces ~"World" self .close }}')
|
|
149
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
150
|
+
do_cleanup
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_that_we_can_block_write_out_spaces
|
|
154
|
+
foorth_equal($osfn + 'OutStream .create{{ ~"Hello" 3 ~spaces ~"World" }}', [])
|
|
155
|
+
assert_equal(["Hello World"], IO.readlines($osfn[1...-2]))
|
|
156
|
+
do_cleanup
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_that_we_can_append_a_character
|
|
161
|
+
foorth_equal($osfn + 'OutStream .create 65 over .emit .close')
|
|
162
|
+
assert_equal(["A"], IO.readlines($osfn[1...-2]))
|
|
163
|
+
|
|
164
|
+
foorth_equal($osfn + 'OutStream .append 66 over .emit .close')
|
|
165
|
+
assert_equal(["AB"], IO.readlines($osfn[1...-2]))
|
|
166
|
+
|
|
167
|
+
do_cleanup
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_that_we_can_block_append_a_character
|
|
171
|
+
foorth_equal($osfn + 'OutStream .create 65 over .emit .close')
|
|
172
|
+
assert_equal(["A"], IO.readlines($osfn[1...-2]))
|
|
173
|
+
|
|
174
|
+
foorth_equal($osfn + 'OutStream .append{{ 66 ~emit }} ')
|
|
175
|
+
assert_equal(["AB"], IO.readlines($osfn[1...-2]))
|
|
176
|
+
|
|
177
|
+
do_cleanup
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_put_and_append_all
|
|
181
|
+
foorth_equal('[ "A" "B" "C" ] ' + $osfn + 'OutStream .put_all')
|
|
182
|
+
assert_equal(["A\n", "B\n", "C\n"], IO.readlines($osfn[1...-2]))
|
|
183
|
+
|
|
184
|
+
foorth_equal('[ "D" "E" "F" ] ' + $osfn + 'OutStream .append_all')
|
|
185
|
+
assert_equal(["A\n", "B\n", "C\n", "D\n", "E\n", "F\n"], IO.readlines($osfn[1...-2]))
|
|
186
|
+
|
|
187
|
+
do_cleanup
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def do_cleanup
|
|
192
|
+
name = $osfn[1...-2]
|
|
193
|
+
system("rm #{name}")
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/fOOrth'
|
|
4
|
+
require_relative 'support/foorth_testing'
|
|
5
|
+
gem 'minitest'
|
|
6
|
+
require 'minitest/autorun'
|
|
7
|
+
require 'minitest_visible'
|
|
8
|
+
|
|
9
|
+
#Test the standard fOOrth library.
|
|
10
|
+
class StringLibraryTester < Minitest::Test
|
|
11
|
+
|
|
12
|
+
include XfOOrthTestExtensions
|
|
13
|
+
|
|
14
|
+
#Track mini-test progress.
|
|
15
|
+
include MinitestVisible
|
|
16
|
+
|
|
17
|
+
def test_string_literals
|
|
18
|
+
foorth_equal(' "" ', [""])
|
|
19
|
+
foorth_equal(' "\"" ', ["\""])
|
|
20
|
+
foorth_equal(' "\"hello\"" ', ["\"hello\""])
|
|
21
|
+
foorth_equal(' "abc" ', ["abc"])
|
|
22
|
+
foorth_equal(' "a\\\\c" ', ["a\\c"])
|
|
23
|
+
foorth_equal(' "a\\nb" ', ["a\nb"])
|
|
24
|
+
|
|
25
|
+
test_src1 = <<-'ONE'
|
|
26
|
+
"abc\
|
|
27
|
+
def"
|
|
28
|
+
ONE
|
|
29
|
+
|
|
30
|
+
assert_equal(" \"abc\\\n def\"\n", test_src1)
|
|
31
|
+
foorth_equal(test_src1, ["abcdef"])
|
|
32
|
+
|
|
33
|
+
test_src2 = <<-'TWO'
|
|
34
|
+
"abc
|
|
35
|
+
TWO
|
|
36
|
+
|
|
37
|
+
assert_equal(" \"abc\n", test_src2)
|
|
38
|
+
foorth_equal(test_src2, ["abc"])
|
|
39
|
+
|
|
40
|
+
foorth_equal(' "a\\x55b" ', ["aUb"])
|
|
41
|
+
foorth_equal(' "a\\u5555b" ', ["a\u5555b"])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_file_loading
|
|
45
|
+
foorth_equal('"integration/load_test_one.foorth" .load ', [42])
|
|
46
|
+
foorth_equal('4 double ', [8])
|
|
47
|
+
foorth_equal('"integration/load_test_one" .load ', [42])
|
|
48
|
+
|
|
49
|
+
foorth_equal('load"integration/load_test_one.foorth"', [42])
|
|
50
|
+
foorth_equal('load"integration/load_test_one"', [42])
|
|
51
|
+
|
|
52
|
+
#foorth_equal(')load"integration/load_test_one.foorth"', [42])
|
|
53
|
+
#foorth_equal(')load"integration/load_test_one"', [42])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_split_strings
|
|
57
|
+
foorth_equal('load"integration/load_test_two"', ["foo "])
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_for_lines
|
|
61
|
+
foorth_equal(' "abc\\ndef\\n123" .lines ', [["abc", "def", "123"]])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_for_split
|
|
65
|
+
foorth_equal(' "abc def 123" .split ', [["abc", "def", "123"]])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_for_call
|
|
69
|
+
foorth_equal(' " 5 " .call ', [5])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_some_string_basics
|
|
73
|
+
foorth_equal('String .new', [""])
|
|
74
|
+
foorth_equal('"abcdefg" .length ', [7])
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_left_justification
|
|
78
|
+
foorth_equal('5 "a" .ljust ', ['a '])
|
|
79
|
+
foorth_equal('5 "too long" .ljust ', ['too long'])
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_center_justification
|
|
83
|
+
foorth_equal('5 "a" .cjust ', [' a '])
|
|
84
|
+
foorth_equal('5 "too long" .cjust ', ['too long'])
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_right_justification
|
|
88
|
+
foorth_equal('5 "a" .rjust ', [' a'])
|
|
89
|
+
foorth_equal('5 "too long" .rjust ', ['too long'])
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_left_strip
|
|
93
|
+
foorth_equal('" a " .lstrip ', ["a "])
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_center_strip
|
|
97
|
+
foorth_equal('" a " .strip ', ["a"])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_right_strip
|
|
101
|
+
foorth_equal('" a " .rstrip ', [" a"])
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_formatted_strings
|
|
105
|
+
foorth_equal('5 "%03d" format ', ['005'])
|
|
106
|
+
foorth_equal('5 f"%03d" ', ['005'])
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_left_copy_paste_and_cut
|
|
110
|
+
foorth_equal('2 "abcdefgh" .left ', ['ab'])
|
|
111
|
+
foorth_equal('2 "123" "abcdefgh" .+left ', ['123cdefgh'])
|
|
112
|
+
foorth_equal('2 "abcdefgh" .-left ', ['cdefgh'])
|
|
113
|
+
foorth_equal('"abc" "abcdefgh" .left? ', [true])
|
|
114
|
+
foorth_equal('"abx" "abcdefgh" .left? ', [false])
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_right_copy_paste_and_cut
|
|
118
|
+
foorth_equal('2 "abcdefgh" .right ', ['gh'])
|
|
119
|
+
foorth_equal('2 "123" "abcdefgh" .+right ', ['abcdef123'])
|
|
120
|
+
foorth_equal('2 "abcdefgh" .-right ', ['abcdef'])
|
|
121
|
+
foorth_equal('"fgh" "abcdefgh" .right? ', [true])
|
|
122
|
+
foorth_equal('"fgx" "abcdefgh" .right? ', [false])
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_mid_copy_paste_and_cut
|
|
126
|
+
foorth_equal('2 4 "abcdefgh" .mid ', ['cdef'])
|
|
127
|
+
foorth_equal('2 4 "abcdefgh" .-mid ', ['abgh'])
|
|
128
|
+
foorth_equal('2 4 "123" "abcdefgh" .+mid ', ['ab123gh'])
|
|
129
|
+
foorth_equal('2 0 "123" "abcdefgh" .+mid ', ['ab123cdefgh'])
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_mid_find
|
|
133
|
+
foorth_equal('2 "cde" "abcdefgh" .mid? ', [true])
|
|
134
|
+
foorth_equal('3 "cde" "abcdefgh" .mid? ', [false])
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_midlr_copy_paste_and_cut
|
|
138
|
+
foorth_equal('2 2 "abcdefgh" .midlr ', ['cdef'])
|
|
139
|
+
foorth_equal('2 2 "abcdefgh" .-midlr ', ['abgh'])
|
|
140
|
+
foorth_equal('2 2 "123" "abcdefgh" .+midlr ', ['ab123gh'])
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def test_string_contains
|
|
144
|
+
foorth_equal('"cde" "abcdefgh" .contains? ', [true])
|
|
145
|
+
foorth_equal('"cdx" "abcdefgh" .contains? ', [false])
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_string_posn
|
|
149
|
+
foorth_equal('"cde" "abcdefgh" .posn ', [2])
|
|
150
|
+
foorth_equal('"cdx" "abcdefgh" .posn ', [nil])
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_replication
|
|
154
|
+
foorth_equal('"abc" 0 *', [''])
|
|
155
|
+
foorth_equal('"abc" 1 *', ['abc'])
|
|
156
|
+
foorth_equal('"abc" 2 *', ['abcabc'])
|
|
157
|
+
foorth_equal('"abc" 3 *', ['abcabcabc'])
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_concatenation
|
|
161
|
+
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])
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_case_changing
|
|
172
|
+
foorth_equal('"abcDEF" .to_upper', ['ABCDEF'])
|
|
173
|
+
foorth_equal('"abcDEF" .to_lower', ['abcdef'])
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_reversing
|
|
177
|
+
foorth_equal('"stressed" .reverse', ['desserts'])
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_the_each
|
|
181
|
+
foorth_equal('"abc" .each{{ v x 1+ * }} ', ['a', 'bb', 'ccc'])
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def test_calling_a_string
|
|
185
|
+
foorth_equal('"1 2 +" .call ', [3])
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def test_capturing_shell_output
|
|
189
|
+
foorth_equal('"ls" .shell_out .class ', [String])
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def test_parsing_some_strings
|
|
193
|
+
foorth_equal('"1 2 3" p"%d %d %d"', [[1,2,3]])
|
|
194
|
+
foorth_equal('"1 2 3" "%d %d %d" parse', [[1,2,3]])
|
|
195
|
+
|
|
196
|
+
foorth_equal('"12 34 -56" p"%d %2d %4d"', [[12, 34, -56]])
|
|
197
|
+
foorth_equal('"255 0b11111111 0377 0xFF 0 " p"%i %i %i %i %i"', [[255, 255, 255, 255, 0]])
|
|
198
|
+
foorth_equal('"7 10 377" p"%o %o %o"', [[7, 8, 255]])
|
|
199
|
+
foorth_equal('"10 10011 11110000" p"%b %b %b"',[[2, 19, 240]])
|
|
200
|
+
foorth_equal('"0 F FF FFF FFFF" p"%x %x %x %x %x"', [[0, 15, 255, 4095, 65535]])
|
|
201
|
+
foorth_equal('"Hello Silly World" p"%s %*s %s"', [["Hello", "World"]])
|
|
202
|
+
foorth_equal('"Hello Silly World" p"%5c %*5c %5c"', [["Hello", "World"]])
|
|
203
|
+
foorth_equal('"42 The secret is X" p"%i %-1c"', [[42, "The secret is X"]])
|
|
204
|
+
foorth_equal('"42 The secret is X" p"%i %-2c%c"', [[42, "The secret is ", "X"]])
|
|
205
|
+
foorth_equal('"42 The secret is X" p"%i %*-2c%c"', [[42, "X"]])
|
|
206
|
+
foorth_equal('"9.99 1.234e56 -1e100" p"%f %f %f"', [[9.99, 1.234e56, -1e100]])
|
|
207
|
+
foorth_equal('"85% 75%" p"%f%% %f%%"', [[85, 75]])
|
|
208
|
+
foorth_equal('"12 34 -56" p"%u %u %u"', [[12, 34]])
|
|
209
|
+
foorth_equal('"1/2 3/4r -5/6" p"%r %r %r"', [['1/2'.to_r, '3/4'.to_r, '-5/6'.to_r]])
|
|
210
|
+
foorth_equal('"1+2i 3+4j -5e10-6.2i" p"%j %j %j"',
|
|
211
|
+
[[Complex('1+2i'), Complex('3+4j'), Complex('-5e10-6.2i')]])
|
|
212
|
+
s = "\"'quote' 'silly' \\\"un quote\\\" 'a \\\\'' \" p\"%q %*q %q %q\" "
|
|
213
|
+
foorth_equal(s, [["quote", "un quote", "a '"]])
|
|
214
|
+
foorth_equal('"a b c" p"%[a] %[b] %[c]"', [["a", "b", "c"]])
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#A small group of extensions to facilitate testing in fOOrth.
|
|
4
|
+
module XfOOrthTestExtensions
|
|
5
|
+
|
|
6
|
+
#When the source is executed, does it raise err?
|
|
7
|
+
#<br>Parameters:
|
|
8
|
+
#* source - A string containing fOOrth source code to execute.
|
|
9
|
+
#* err - The type of exception expected during execution.
|
|
10
|
+
#* debug - Set to true to display debug info.
|
|
11
|
+
def foorth_run(source, debug=false)
|
|
12
|
+
vm = Thread.current[:vm]
|
|
13
|
+
vm.debug = debug
|
|
14
|
+
vm.process_string(source)
|
|
15
|
+
ensure
|
|
16
|
+
vm.debug = false
|
|
17
|
+
vm.interpreter_reset
|
|
18
|
+
vm.compiler_reset
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#When the source is executed, is the stack as expected?
|
|
22
|
+
#<br>Parameters:
|
|
23
|
+
#* source - A string containing fOOrth source code to execute.
|
|
24
|
+
#* remainder - An array with the expected stack contents after execution.
|
|
25
|
+
#* debug - Set to true to display debug info.
|
|
26
|
+
def foorth_equal(source, remainder=[], debug=false)
|
|
27
|
+
self.assertions += 1
|
|
28
|
+
vm = Thread.current[:vm]
|
|
29
|
+
vm.debug = debug
|
|
30
|
+
vm.process_string(source)
|
|
31
|
+
|
|
32
|
+
unless remainder == vm.data_stack
|
|
33
|
+
msg = "Expected: #{remainder.inspect}\n Actual: #{vm.data_stack.inspect}"
|
|
34
|
+
raise MiniTest::Assertion, msg, caller
|
|
35
|
+
end
|
|
36
|
+
ensure
|
|
37
|
+
vm.debug = false
|
|
38
|
+
vm.interpreter_reset
|
|
39
|
+
vm.compiler_reset
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#When the source is executed, does it raise err?
|
|
43
|
+
#<br>Parameters:
|
|
44
|
+
#* source - A string containing fOOrth source code to execute.
|
|
45
|
+
#* err - The type of exception expected during execution.
|
|
46
|
+
#* debug - Set to true to display debug info.
|
|
47
|
+
def foorth_raises(source, err=XfOOrth::XfOOrthError, debug=false)
|
|
48
|
+
self.assertions += 1
|
|
49
|
+
vm = Thread.current[:vm]
|
|
50
|
+
vm.debug = debug
|
|
51
|
+
failed, msg = false, ""
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
vm.process_string(source)
|
|
55
|
+
msg = "Expected: #{err}\n Actual: No exception raised."
|
|
56
|
+
failed = true
|
|
57
|
+
|
|
58
|
+
rescue Exception => e
|
|
59
|
+
unless e.class == err
|
|
60
|
+
msg = "Expected: #{err}\n Actual: #{e.class}"
|
|
61
|
+
failed = true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
raise MiniTest::Assertion, msg, caller if failed
|
|
66
|
+
|
|
67
|
+
ensure
|
|
68
|
+
vm.debug = false
|
|
69
|
+
vm.interpreter_reset
|
|
70
|
+
vm.compiler_reset
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#When the source is executed, does the stdout match?
|
|
74
|
+
#<br>Parameters:
|
|
75
|
+
#* source - A string containing fOOrth source code to execute.
|
|
76
|
+
#* expected - A string with the expected console output.
|
|
77
|
+
def foorth_output(source, expected)
|
|
78
|
+
self.assertions += 1
|
|
79
|
+
failed, msg = false, ""
|
|
80
|
+
vm = Thread.current[:vm]
|
|
81
|
+
|
|
82
|
+
actual, _nc = capture_io do
|
|
83
|
+
vm.process_string(source)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if expected != actual
|
|
87
|
+
msg = "Expected: #{expected.inspect}\n Actual: #{actual.inspect}"
|
|
88
|
+
raise MiniTest::Assertion, msg, caller
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
ensure
|
|
92
|
+
vm.interpreter_reset
|
|
93
|
+
vm.compiler_reset
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#Copied here for study
|
|
97
|
+
def capture_foorth_io
|
|
98
|
+
require 'stringio'
|
|
99
|
+
|
|
100
|
+
orig_stdout = $stdout
|
|
101
|
+
|
|
102
|
+
(s_o = StringIO.new).set_encoding 'UTF-8'
|
|
103
|
+
captured_stdout = s_o
|
|
104
|
+
$stdout = captured_stdout
|
|
105
|
+
|
|
106
|
+
yield
|
|
107
|
+
|
|
108
|
+
return captured_stdout.string.bytes.to_a
|
|
109
|
+
ensure
|
|
110
|
+
$stdout = orig_stdout
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#When the source is executed, does the stdout match? Forces UTF-8 encoding.
|
|
114
|
+
#<br>Parameters:
|
|
115
|
+
#* source - A string containing fOOrth source code to execute.
|
|
116
|
+
#* expected - An array of bytes expected for the console.
|
|
117
|
+
def foorth_utf8_output(source, expected)
|
|
118
|
+
self.assertions += 1
|
|
119
|
+
vm = Thread.current[:vm]
|
|
120
|
+
|
|
121
|
+
actual = capture_foorth_io do
|
|
122
|
+
vm.process_string(source)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if expected != actual
|
|
126
|
+
msg = "Expected: #{expected.inspect}\n Actual: #{actual.inspect}"
|
|
127
|
+
raise MiniTest::Assertion, msg, caller
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
ensure
|
|
131
|
+
vm.interpreter_reset
|
|
132
|
+
vm.compiler_reset
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end
|