fOOrth 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|