fOOrth 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rdoc_options +17 -0
  4. data/Gemfile +4 -0
  5. data/README.md +67 -0
  6. data/bin/fOOrth +8 -0
  7. data/demo.rb +24 -0
  8. data/fOOrth.gemspec +40 -0
  9. data/fOOrth.reek +109 -0
  10. data/integration/README.md +12 -0
  11. data/integration/_FILE_test.foorth +5 -0
  12. data/integration/array_lib_tests.rb +360 -0
  13. data/integration/class_lib_tests.rb +116 -0
  14. data/integration/clone_lib_tests.rb +108 -0
  15. data/integration/comparison_tests.rb +132 -0
  16. data/integration/compile_lib_tests.rb +190 -0
  17. data/integration/ctrl_struct_lib_tests.rb +80 -0
  18. data/integration/data_ref_lib_tests.rb +43 -0
  19. data/integration/exception_lib_tests.rb +86 -0
  20. data/integration/fiber_bundle_tests.rb +380 -0
  21. data/integration/hash_lib_tests.rb +120 -0
  22. data/integration/in_stream_test_1.txt +4 -0
  23. data/integration/load_test_one.foorth +6 -0
  24. data/integration/load_test_two.foorth +4 -0
  25. data/integration/numeric_lib_tests.rb +321 -0
  26. data/integration/object_lib_tests.rb +38 -0
  27. data/integration/procedure_lib_tests.rb +40 -0
  28. data/integration/queue_lib_tests.rb +66 -0
  29. data/integration/stack_lib_tests.rb +70 -0
  30. data/integration/standard_lib_tests.rb +208 -0
  31. data/integration/stdio_lib_tests.rb +52 -0
  32. data/integration/stream_lib_tests.rb +196 -0
  33. data/integration/string_lib_tests.rb +217 -0
  34. data/integration/support/foorth_testing.rb +135 -0
  35. data/integration/thread_lib_tests.rb +83 -0
  36. data/integration/time_lib_tests.rb +791 -0
  37. data/integration/vm_lib_tests.rb +38 -0
  38. data/lib/fOOrth.rb +57 -0
  39. data/lib/fOOrth/compiler.rb +78 -0
  40. data/lib/fOOrth/compiler/context.rb +49 -0
  41. data/lib/fOOrth/compiler/context/locals.rb +34 -0
  42. data/lib/fOOrth/compiler/context/map_name.rb +92 -0
  43. data/lib/fOOrth/compiler/context/tags.rb +48 -0
  44. data/lib/fOOrth/compiler/modes.rb +32 -0
  45. data/lib/fOOrth/compiler/modes/compiled.rb +41 -0
  46. data/lib/fOOrth/compiler/modes/deferred.rb +57 -0
  47. data/lib/fOOrth/compiler/modes/delayed.rb +40 -0
  48. data/lib/fOOrth/compiler/modes/nested.rb +34 -0
  49. data/lib/fOOrth/compiler/modes/suspend.rb +32 -0
  50. data/lib/fOOrth/compiler/parser.rb +26 -0
  51. data/lib/fOOrth/compiler/parser/get_string.rb +71 -0
  52. data/lib/fOOrth/compiler/parser/normal.rb +53 -0
  53. data/lib/fOOrth/compiler/parser/skip.rb +50 -0
  54. data/lib/fOOrth/compiler/parser/special.rb +42 -0
  55. data/lib/fOOrth/compiler/process.rb +47 -0
  56. data/lib/fOOrth/compiler/process/generate.rb +24 -0
  57. data/lib/fOOrth/compiler/process/get_token.rb +23 -0
  58. data/lib/fOOrth/compiler/process/procedure.rb +55 -0
  59. data/lib/fOOrth/compiler/process/string.rb +20 -0
  60. data/lib/fOOrth/compiler/source.rb +51 -0
  61. data/lib/fOOrth/compiler/source/console.rb +70 -0
  62. data/lib/fOOrth/compiler/source/file_source.rb +37 -0
  63. data/lib/fOOrth/compiler/source/read_point.rb +46 -0
  64. data/lib/fOOrth/compiler/source/string_source.rb +28 -0
  65. data/lib/fOOrth/compiler/token.rb +37 -0
  66. data/lib/fOOrth/compiler/word_specs.rb +178 -0
  67. data/lib/fOOrth/core.rb +27 -0
  68. data/lib/fOOrth/core/class.rb +116 -0
  69. data/lib/fOOrth/core/object.rb +78 -0
  70. data/lib/fOOrth/core/virtual_machine.rb +28 -0
  71. data/lib/fOOrth/debug.rb +13 -0
  72. data/lib/fOOrth/debug/context_dump.rb +31 -0
  73. data/lib/fOOrth/debug/dbg_puts.rb +17 -0
  74. data/lib/fOOrth/debug/display_abort.rb +37 -0
  75. data/lib/fOOrth/debug/vm_dump.rb +27 -0
  76. data/lib/fOOrth/initialize.rb +83 -0
  77. data/lib/fOOrth/interpreter.rb +24 -0
  78. data/lib/fOOrth/interpreter/add_to_hash.rb +17 -0
  79. data/lib/fOOrth/interpreter/data_stack.rb +125 -0
  80. data/lib/fOOrth/interpreter/do_loop.rb +55 -0
  81. data/lib/fOOrth/interpreter/squash.rb +25 -0
  82. data/lib/fOOrth/library.rb +38 -0
  83. data/lib/fOOrth/library/array_library.rb +577 -0
  84. data/lib/fOOrth/library/bundle_library.rb +112 -0
  85. data/lib/fOOrth/library/class_library.rb +90 -0
  86. data/lib/fOOrth/library/clone_library.rb +72 -0
  87. data/lib/fOOrth/library/command_library.rb +205 -0
  88. data/lib/fOOrth/library/compile_library.rb +181 -0
  89. data/lib/fOOrth/library/complex_library.rb +81 -0
  90. data/lib/fOOrth/library/ctrl_struct_library.rb +116 -0
  91. data/lib/fOOrth/library/data_ref_library.rb +100 -0
  92. data/lib/fOOrth/library/duration/arithmetic.rb +114 -0
  93. data/lib/fOOrth/library/duration/formatter.rb +152 -0
  94. data/lib/fOOrth/library/duration/intervals.rb +233 -0
  95. data/lib/fOOrth/library/duration/make.rb +75 -0
  96. data/lib/fOOrth/library/duration_library.rb +52 -0
  97. data/lib/fOOrth/library/fiber_library.rb +120 -0
  98. data/lib/fOOrth/library/hash_library.rb +203 -0
  99. data/lib/fOOrth/library/in_stream_library.rb +81 -0
  100. data/lib/fOOrth/library/integer_library.rb +104 -0
  101. data/lib/fOOrth/library/mutex_library.rb +31 -0
  102. data/lib/fOOrth/library/numeric_library.rb +380 -0
  103. data/lib/fOOrth/library/object_library.rb +80 -0
  104. data/lib/fOOrth/library/other_value_types_library.rb +96 -0
  105. data/lib/fOOrth/library/out_stream_library.rb +146 -0
  106. data/lib/fOOrth/library/procedure_library.rb +65 -0
  107. data/lib/fOOrth/library/queue_library.rb +47 -0
  108. data/lib/fOOrth/library/rational_library.rb +90 -0
  109. data/lib/fOOrth/library/stack_library.rb +56 -0
  110. data/lib/fOOrth/library/stdio_library.rb +56 -0
  111. data/lib/fOOrth/library/string_library.rb +285 -0
  112. data/lib/fOOrth/library/stubs.rb +76 -0
  113. data/lib/fOOrth/library/sync_bundle_library.rb +50 -0
  114. data/lib/fOOrth/library/thread_library.rb +73 -0
  115. data/lib/fOOrth/library/time_library.rb +302 -0
  116. data/lib/fOOrth/library/vm_library.rb +105 -0
  117. data/lib/fOOrth/main.rb +125 -0
  118. data/lib/fOOrth/monkey_patch.rb +14 -0
  119. data/lib/fOOrth/monkey_patch/complex.rb +30 -0
  120. data/lib/fOOrth/monkey_patch/exceptions.rb +154 -0
  121. data/lib/fOOrth/monkey_patch/false.rb +11 -0
  122. data/lib/fOOrth/monkey_patch/float.rb +22 -0
  123. data/lib/fOOrth/monkey_patch/integer.rb +22 -0
  124. data/lib/fOOrth/monkey_patch/nil.rb +11 -0
  125. data/lib/fOOrth/monkey_patch/numeric.rb +33 -0
  126. data/lib/fOOrth/monkey_patch/object.rb +43 -0
  127. data/lib/fOOrth/monkey_patch/rational.rb +31 -0
  128. data/lib/fOOrth/monkey_patch/string.rb +51 -0
  129. data/lib/fOOrth/symbol_map.rb +82 -0
  130. data/lib/fOOrth/version.rb +7 -0
  131. data/license.txt +21 -0
  132. data/rakefile.rb +65 -0
  133. data/reek.txt +1 -0
  134. data/sire.rb +132 -0
  135. data/t.txt +3 -0
  136. data/test.foorth +5 -0
  137. data/tests/compiler/context_tests.rb +180 -0
  138. data/tests/compiler/file_source_test_one.txt +1 -0
  139. data/tests/compiler/file_source_test_three.txt +3 -0
  140. data/tests/compiler/file_source_test_two.txt +3 -0
  141. data/tests/compiler/file_source_tests.rb +130 -0
  142. data/tests/compiler/mode_tests.rb +45 -0
  143. data/tests/compiler/parser_tests.rb +116 -0
  144. data/tests/compiler/spec_tests.rb +113 -0
  145. data/tests/compiler/string_source_tests.rb +128 -0
  146. data/tests/core_tests.rb +138 -0
  147. data/tests/interpreter/data_stack_tests.rb +119 -0
  148. data/tests/monkey_patch/coerce_test.rb +131 -0
  149. data/tests/monkey_patch/complex_test.rb +25 -0
  150. data/tests/monkey_patch/numeric_test.rb +62 -0
  151. data/tests/monkey_patch/object_test.rb +49 -0
  152. data/tests/monkey_patch/rational_test.rb +57 -0
  153. data/tests/monkey_patch/string_test.rb +53 -0
  154. data/tests/symbol_map_tests.rb +53 -0
  155. metadata +366 -0
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+
3
+ require 'thread'
4
+
5
+ #* library/queue_library.rb - The Queue support fOOrth library.
6
+ module XfOOrth
7
+
8
+ #Connect the Queue class to the fOOrth class system.
9
+ stack = Object.create_foorth_subclass('Stack').new_class
10
+
11
+ #Uses the default implementation of the .new method.
12
+
13
+ #Initialize the Stack object.
14
+ stack.create_shared_method('.init', TosSpec, [], &lambda {|vm|
15
+ @data = []
16
+ })
17
+
18
+ #Clear the Stack object.
19
+ stack.create_shared_method('.clear', TosSpec, [], &lambda {|vm|
20
+ @data.clear
21
+ })
22
+
23
+ #[v stack] .push []; pushes the v onto the stack.
24
+ stack.create_shared_method('.push', TosSpec, [], &lambda {|vm|
25
+ @data << vm.pop
26
+ })
27
+
28
+ #[stack] .pop [v]; pops the v from the stack.
29
+ stack.create_shared_method('.pop', TosSpec, [], &lambda {|vm|
30
+ if @data.length > 0
31
+ vm.push(@data.pop)
32
+ else
33
+ error "F31: Stack Underflow: .pop"
34
+ end
35
+ })
36
+
37
+ #[stack] .peek [v]; sneaks a peek at the top item of the stack.
38
+ stack.create_shared_method('.peek', TosSpec, [], &lambda {|vm|
39
+ if @data.length > 0
40
+ vm.push(@data[-1])
41
+ else
42
+ error "F31: Stack Underflow: .peek"
43
+ end
44
+ })
45
+
46
+ #[stack] .empty? [a_boolean]
47
+ stack.create_shared_method('.empty?', TosSpec, [], &lambda {|vm|
48
+ vm.push(@data.empty?)
49
+ })
50
+
51
+ #[stack] .length [an_integer]
52
+ stack.create_shared_method('.length', TosSpec, [], &lambda {|vm|
53
+ vm.push(@data.length)
54
+ })
55
+
56
+ end
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+
3
+ #* library/stdio_library.rb - The standard I/O fOOrth library.
4
+ module XfOOrth
5
+
6
+ # Some basic console I/O words.
7
+ #[obj] . []; print out the object as a string.
8
+ Object.create_shared_method('.', TosSpec, [], &lambda {|vm|
9
+ self.to_foorth_s(vm)
10
+ print vm.pop
11
+ })
12
+
13
+ #Print out a string.
14
+ # [] ."string" []; prints out the string.
15
+ String.create_shared_method('."', TosSpec, [], &lambda {|vm|
16
+ print self
17
+ })
18
+
19
+ #Force a new line.
20
+ # [] cr []; prints a new line.
21
+ VirtualMachine.create_shared_method('cr', MacroSpec,
22
+ [:macro, "puts; "])
23
+
24
+ #Force a space.
25
+ # [] space []; prints a space
26
+ VirtualMachine.create_shared_method('space', MacroSpec,
27
+ [:macro, "print ' '; "])
28
+
29
+ #Force multiple spaces.
30
+ # [n] spaces []; prints n spaces.
31
+ VirtualMachine.create_shared_method('spaces', MacroSpec,
32
+ [:macro, "print ' ' * Integer.foorth_coerce(vm.pop()); "])
33
+
34
+ #Print out a single character.
35
+ #[obj] .emit []; print out the object as a character.
36
+ Numeric.create_shared_method('.emit', TosSpec, [],
37
+ &lambda {|vm| print self.to_foorth_c})
38
+ String.create_shared_method('.emit', TosSpec, [],
39
+ &lambda {|vm| print self.to_foorth_c})
40
+ Complex.create_shared_method('.emit', TosSpec, [:stub])
41
+
42
+ #Get a string from the console.
43
+ # [] accept [string]; gets a string from the console.
44
+ VirtualMachine.create_shared_method('accept', VmSpec, [],
45
+ &lambda {|vm| push(MiniReadline.readline('? ', true)); })
46
+
47
+ #Get a string from the console.
48
+ # [] accept"prompt" [string]; gets a string from the console.
49
+ VirtualMachine.create_shared_method('accept"', VmSpec, [],
50
+ &lambda {|vm| poke(MiniReadline.readline(peek.to_s, true)); })
51
+
52
+ #Get a string from the console.
53
+ # "prompt" [] .accept [string]; gets a string from the console.
54
+ String.create_shared_method('.accept', TosSpec, [],
55
+ &lambda{|vm| vm.push(MiniReadline.readline(self, true))})
56
+ end
@@ -0,0 +1,285 @@
1
+ # coding: utf-8
2
+
3
+ #* library/string_library.rb - String support for the fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the String class to the fOOrth class system.
7
+ String.create_foorth_proxy
8
+
9
+ # A no operation place holder for string literals
10
+ VirtualMachine.create_shared_method('"', MacroSpec, [:macro, " "])
11
+
12
+ # [string] .each{{ ... }} [unspecified]
13
+ String.create_shared_method('.each{{', NosSpec, [], &lambda { |vm|
14
+ block, idx = vm.pop, 0
15
+ self.chars { |val| block.call(vm, val, idx); idx += 1 }
16
+ })
17
+
18
+ #Some comparison operators
19
+ # [b,a] > if b > a then [true] else [false]
20
+ String.create_shared_method('>', NosSpec, [],
21
+ &lambda {|vm| vm.poke(self > vm.peek.to_s); })
22
+
23
+ # [b,a] < if b < a then [true] else [false]
24
+ String.create_shared_method('<', NosSpec, [],
25
+ &lambda {|vm| vm.poke(self < vm.peek.to_s); })
26
+
27
+ # [b,a] >= if b >= a then [true] else [false]
28
+ String.create_shared_method('>=', NosSpec, [],
29
+ &lambda {|vm| vm.poke(self >= vm.peek.to_s); })
30
+
31
+ # [b,a] <= if b <= a then [true] else [false]
32
+ String.create_shared_method('<=', NosSpec, [],
33
+ &lambda {|vm| vm.poke(self <= vm.peek.to_s); })
34
+
35
+ # [b,a] <=> if b <=> a then [true] else [false]
36
+ String.create_shared_method('<=>', NosSpec, [],
37
+ &lambda {|vm| vm.poke(self <=> vm.peek.to_s); })
38
+
39
+
40
+ #Some string manipulation methods.
41
+ # [n a] .ljust ['a ']; left justify
42
+ String.create_shared_method('.ljust', TosSpec, [],
43
+ &lambda {|vm| vm.poke(self.ljust(Integer.foorth_coerce(vm.peek))); })
44
+
45
+ # [n a] .cjust [' a ']; center justify
46
+ String.create_shared_method('.cjust', TosSpec, [],
47
+ &lambda {|vm| vm.poke(self.center(Integer.foorth_coerce(vm.peek))); })
48
+
49
+ # [n a] .rjust [' a']; right justify
50
+ String.create_shared_method('.rjust', TosSpec, [],
51
+ &lambda {|vm| vm.poke(self.rjust(Integer.foorth_coerce(vm.peek))); })
52
+
53
+ # [" a "] .lstrip ["a "]; left strip
54
+ String.create_shared_method('.lstrip', TosSpec, [],
55
+ &lambda {|vm| vm.push(self.lstrip); })
56
+
57
+ # [" a "] .strip ["a"]; left and right strip
58
+ String.create_shared_method('.strip', TosSpec, [],
59
+ &lambda {|vm| vm.push(self.strip); })
60
+
61
+ # [" a "] .rstrip [" a"]; right strip
62
+ String.create_shared_method('.rstrip', TosSpec, [],
63
+ &lambda {|vm| vm.push(self.rstrip); })
64
+
65
+ format_action = lambda do |vm|
66
+ begin
67
+ vm.poke(vm.peek % self.in_array)
68
+ rescue => err
69
+ vm.data_stack.pop
70
+ error "F40: Formating error: #{err.message}."
71
+ end
72
+ end
73
+
74
+ # [object_or_array fmt_str] format ['a formatted string']
75
+ Object.create_shared_method('format', NosSpec, [], &format_action)
76
+
77
+ # [object_or_array] f"fmt_str" ['a formatted string']
78
+ Object.create_shared_method('f"', NosSpec, [], &format_action)
79
+
80
+ parse_action = lambda {|vm| vm.poke(self.sscanf(vm.peek))}
81
+
82
+ # [a_str fmt_str] parse [result_array]
83
+ String.create_shared_method('parse', NosSpec, [], &parse_action)
84
+
85
+ # [a_str] p"fmt_str" [result_array]
86
+ String.create_shared_method('p"', NosSpec, [], &parse_action)
87
+
88
+
89
+ #LEFT Group
90
+
91
+ # [w 'abcdefgh'] .left ['ab'] // Assumes w = 2
92
+ String.create_shared_method('.left', TosSpec, [],
93
+ &lambda {|vm| vm.poke(self[0...(Integer.foorth_coerce(vm.peek))]); })
94
+
95
+ # [w 'abcdefgh'] .-left ['cdefgh'] // Assumes w = 2
96
+ String.create_shared_method('.-left', TosSpec, [],
97
+ &lambda {|vm| vm.poke(self[(Integer.foorth_coerce(vm.peek))..-1]); })
98
+
99
+ # [w '123''abcdefgh'] .+left ['123cdefgh'] // Assumes w = 2
100
+ String.create_shared_method('.+left', TosSpec, [], &lambda {|vm|
101
+ ins = vm.pop.to_s
102
+ vm.poke(ins + self[(Integer.foorth_coerce(vm.peek))..-1])
103
+ })
104
+
105
+ # ['abc' 'abcdefgh'] .left? [boolean]
106
+ String.create_shared_method('.left?', TosSpec, [],
107
+ &lambda {|vm| vm.poke(self.start_with?(vm.peek)); })
108
+
109
+
110
+ #MID Group
111
+
112
+ # [n w 'abcdefgh'] .mid ['cdef'] // Assumes n = 2, w = 4
113
+ String.create_shared_method('.mid', TosSpec, [], &lambda {|vm|
114
+ width = Integer.foorth_coerce(vm.pop)
115
+ posn = Integer.foorth_coerce(vm.pop)
116
+ vm.push(self[posn...(posn+width)])
117
+ })
118
+
119
+ # [n w 'abcdefgh'] .-mid ['abgh'] // Assumes n = 2, w = 4
120
+ String.create_shared_method('.-mid', TosSpec, [], &lambda {|vm|
121
+ width = Integer.foorth_coerce(vm.pop)
122
+ posn = Integer.foorth_coerce(vm.pop)
123
+ vm.push(self[0...posn] + self[(posn+width)..-1])
124
+ })
125
+
126
+ # [n w "123" "abcdefgh"] .+mid ["ab123gh"] // Assumes n = 2, w = 4
127
+ String.create_shared_method('.+mid', TosSpec, [], &lambda {|vm|
128
+ ins = vm.pop.to_s
129
+ width = Integer.foorth_coerce(vm.pop)
130
+ posn = Integer.foorth_coerce(vm.pop)
131
+ vm.push(self[0...posn] + ins + self[(posn+width)..-1])
132
+ })
133
+
134
+ # [n 'cde' 'abcdefgh'] .mid? [true] // Assumes n = 2
135
+ String.create_shared_method('.mid?', TosSpec, [], &lambda {|vm|
136
+ search = vm.pop.to_s
137
+ width = search.length
138
+ posn = Integer.foorth_coerce(vm.pop)
139
+ vm.push(self[posn...(posn+width)] == search)
140
+ })
141
+
142
+
143
+ #MIDLR Group
144
+
145
+ # [l r 'abcdefgh'] .midlr ['bcdefg'] // Assumes l = 1, r = 1
146
+ String.create_shared_method('.midlr', TosSpec, [], &lambda {|vm|
147
+ right = Integer.foorth_coerce(vm.pop)
148
+ left = Integer.foorth_coerce(vm.pop)
149
+ vm.push(self[left...(0-right)])
150
+ })
151
+
152
+ # [l r 'abcdefgh'] .-midlr ['ah'] // Assumes l = 1, r = 1
153
+ String.create_shared_method('.-midlr', TosSpec, [], &lambda {|vm|
154
+ right = Integer.foorth_coerce(vm.pop)
155
+ left = Integer.foorth_coerce(vm.pop)
156
+ vm.push(self[0...left] + self[((0-right))..-1])
157
+ })
158
+
159
+ # [l r "123" 'abcdefgh'] .+midlr ['a123h'] // Assumes l = 1, r = 1
160
+ String.create_shared_method('.+midlr', TosSpec, [], &lambda {|vm|
161
+ ins = vm.pop.to_s
162
+ right = Integer.foorth_coerce(vm.pop)
163
+ left = Integer.foorth_coerce(vm.pop)
164
+ vm.push(self[0...left] + ins + self[((0-right))..-1])
165
+ })
166
+
167
+ #RIGHT Group
168
+
169
+ # [w 'abcdefgh'] .right ['gh'] // Assumes w = 2
170
+ String.create_shared_method('.right', TosSpec, [],
171
+ &lambda {|vm| vm.poke(self[(0-(Integer.foorth_coerce(vm.peek)))..-1]); })
172
+
173
+ # [w 'abcdefgh'] .-right ['abcdef'] // Assumes w = 2
174
+ String.create_shared_method('.-right', TosSpec, [],
175
+ &lambda {|vm| vm.poke(self[0...(0-(Integer.foorth_coerce(vm.peek)))]); })
176
+
177
+ # [w "123" 'abcdefgh'] .+right ['abcdef123'] // Assumes w = 2
178
+ String.create_shared_method('.+right', TosSpec, [], &lambda {|vm|
179
+ ins = vm.pop.to_s
180
+ width = Integer.foorth_coerce(vm.pop)
181
+ vm.push(self[0...(0-width)] + ins)
182
+ })
183
+
184
+ # ['fgh' 'abcdefgh'] .right? [boolean]
185
+ String.create_shared_method('.right?', TosSpec, [],
186
+ &lambda {|vm| vm.poke(self.end_with?(vm.peek)); })
187
+
188
+ #Other String Methods
189
+
190
+ # ['cde' 'abcdefgh'] .contains? [boolean]
191
+ String.create_shared_method('.contains?', TosSpec, [],
192
+ &lambda {|vm| vm.poke(self.index(vm.peek).to_foorth_b); })
193
+
194
+ # ['cde' 'abcdefgh'] .posn [position or nil]
195
+ String.create_shared_method('.posn', TosSpec, [],
196
+ &lambda {|vm| vm.poke(self.index(vm.peek)); })
197
+
198
+ # ["a"] .length [n]
199
+ String.create_shared_method('.length', TosSpec, [],
200
+ &lambda {|vm| vm.push(self.length); })
201
+
202
+ # ["b", a] + ["ba"]; "ba" is a new object, distinct from "b"
203
+ String.create_shared_method('+', NosSpec, [],
204
+ &lambda {|vm| vm.poke(self + vm.peek.to_s); })
205
+
206
+ # ["b", a] << ["ba"]; "ba" is the same object as "b"
207
+ String.create_shared_method('<<', NosSpec, [],
208
+ &lambda {|vm| vm.poke(self << vm.peek.to_s); })
209
+
210
+ # ["b", n] * ["bbb..."]
211
+ String.create_shared_method('*', NosSpec, [], &lambda {|vm|
212
+ begin
213
+ vm.poke(self * Integer.foorth_coerce(vm.peek))
214
+ rescue
215
+ vm.data_stack.pop
216
+ raise
217
+ end
218
+ })
219
+
220
+ # ["abCD"] .to_upper ["ABCD"]
221
+ String.create_shared_method('.to_upper', TosSpec, [],
222
+ &lambda {|vm| vm.push(self.upcase); })
223
+
224
+ # ["abCD"] .to_lower ["abcd"]
225
+ String.create_shared_method('.to_lower', TosSpec, [],
226
+ &lambda {|vm| vm.push(self.downcase); })
227
+
228
+ # ["stressed"] .reverse ["desserts"]
229
+ String.create_shared_method('.reverse', TosSpec, [],
230
+ &lambda {|vm| vm.push(self.reverse); })
231
+
232
+ # ["abc\\ndef\\n123"] .lines [["abc", "def", "123"]]
233
+ String.create_shared_method('.lines', TosSpec, [],
234
+ &lambda {|vm| vm.push(self.lines.to_a.collect {|line| line.chomp}) })
235
+
236
+ # ["abc def 123"] .split [["abc", "def", "123"]]
237
+ String.create_shared_method('.split', TosSpec, [],
238
+ &lambda {|vm| vm.push(self.split(' ')) })
239
+
240
+ # [file_name_string] .load [undefined]; load the file as source code.
241
+ String.create_shared_method('.load', TosSpec, [], &lambda {|vm|
242
+ if File.extname(self) == '' && !self.end_with?('.')
243
+ file_name = self + '.foorth'
244
+ else
245
+ file_name = self
246
+ end
247
+
248
+ unless File.exists?(file_name)
249
+ error "F50: Unable to locate file #{file_name}"
250
+ end
251
+
252
+ vm.process_file(file_name)
253
+ })
254
+
255
+ # [] .load"file_name_string" [undefined]; load the file as source code.
256
+ VirtualMachine.create_shared_method('load"', VmSpec, [], &lambda{|vm|
257
+ vm.pop.foorth_load_file(vm)
258
+ })
259
+
260
+ # ["a_string"] .call [unspecified]; Execute the string as source code.
261
+ String.create_shared_method('.call', TosSpec, [], &lambda {|vm|
262
+ vm.process_string(self)
263
+ })
264
+
265
+ # ["Error message"] .throw []; Raises an exception.
266
+ String.create_shared_method('.throw', TosSpec, [], &lambda {|vm|
267
+ raise XfOOrth::XfOOrthError, self, caller
268
+ })
269
+
270
+ # [] throw"Error message" []; Raises an exception.
271
+ VirtualMachine.create_shared_method('throw"', VmSpec, [], &lambda {|vm|
272
+ raise XfOOrth::XfOOrthError, vm.pop.to_s, caller
273
+ })
274
+
275
+ # [a_string] .shell []
276
+ String.create_shared_method('.shell', TosSpec, [], &lambda {|vm|
277
+ system(self)
278
+ })
279
+
280
+ # [a_string] .shell_out [a_string]
281
+ String.create_shared_method('.shell_out', TosSpec, [], &lambda {|vm|
282
+ IO.popen(self, "r") {|io| vm.push(io.read) }
283
+ })
284
+
285
+ end
@@ -0,0 +1,76 @@
1
+ # coding: utf-8
2
+
3
+ #* library/stubs.rb - The standard fOOrth library.
4
+ module XfOOrth
5
+
6
+ # Some comparison words. See numeric_library.rb and string_library.rb
7
+ Object.create_shared_method('>', NosSpec, [:stub])
8
+ Object.create_shared_method('<', NosSpec, [:stub])
9
+ Object.create_shared_method('>=', NosSpec, [:stub])
10
+ Object.create_shared_method('<=', NosSpec, [:stub])
11
+ Object.create_shared_method('<=>', NosSpec, [:stub])
12
+
13
+ # Some comparison with zero words. See numeric_library.rb
14
+ Object.create_shared_method('0=', TosSpec, [:stub])
15
+ Object.create_shared_method('0<>', TosSpec, [:stub])
16
+ Object.create_shared_method('0>', TosSpec, [:stub])
17
+ Object.create_shared_method('0<', TosSpec, [:stub])
18
+ Object.create_shared_method('0>=', TosSpec, [:stub])
19
+ Object.create_shared_method('0<=', TosSpec, [:stub])
20
+ Object.create_shared_method('0<=>', TosSpec, [:stub])
21
+
22
+ # Stubs for the stack arithmetic words. See numeric_library.rb
23
+ Object.create_shared_method('+', NosSpec, [:stub])
24
+ Object.create_shared_method('-', NosSpec, [:stub])
25
+ Object.create_shared_method('*', NosSpec, [:stub])
26
+ Object.create_shared_method('**', NosSpec, [:stub])
27
+ Object.create_shared_method('/', NosSpec, [:stub])
28
+ Object.create_shared_method('mod', NosSpec, [:stub])
29
+ Object.create_shared_method('neg', TosSpec, [:stub])
30
+
31
+ Object.create_shared_method('1+', TosSpec, [:stub])
32
+ Object.create_shared_method('1-', TosSpec, [:stub])
33
+ Object.create_shared_method('2+', TosSpec, [:stub])
34
+ Object.create_shared_method('2-', TosSpec, [:stub])
35
+ Object.create_shared_method('2*', TosSpec, [:stub])
36
+ Object.create_shared_method('2/', TosSpec, [:stub])
37
+
38
+ Object.create_shared_method(')stubs', TosSpec, [:stub])
39
+
40
+ # Some bitwise operation stubs. See numeric_library.rb
41
+ Object.create_shared_method('and', NosSpec, [:stub])
42
+ Object.create_shared_method('or', NosSpec, [:stub])
43
+ Object.create_shared_method('xor', NosSpec, [:stub])
44
+ Object.create_shared_method('com', TosSpec, [:stub])
45
+ Object.create_shared_method('<<', NosSpec, [:stub])
46
+ Object.create_shared_method('>>', NosSpec, [:stub])
47
+
48
+ Object.create_shared_method('@', TosSpec, [:stub])
49
+ Object.create_shared_method('!', TosSpec, [:stub])
50
+
51
+ Object.create_shared_method('parse', NosSpec, [:stub])
52
+ Object.create_shared_method('parse!', NosSpec, [:stub])
53
+ Object.create_shared_method('p"', NosSpec, [:stub])
54
+ Object.create_shared_method('p!"', NosSpec, [:stub])
55
+
56
+ #Procedure literal stubs.
57
+ Object.create_shared_method('.each{{', NosSpec, [:stub])
58
+ Object.create_shared_method('.new{{', NosSpec, [:stub])
59
+ Object.create_shared_method('.map{{', NosSpec, [:stub])
60
+ Object.create_shared_method('.select{{', NosSpec, [:stub])
61
+ Object.create_shared_method('.open{{', NosSpec, [:stub])
62
+ Object.create_shared_method('.create{{', NosSpec, [:stub])
63
+ Object.create_shared_method('.append{{', NosSpec, [:stub])
64
+ Object.create_shared_method('.do{{', NosSpec, [:stub])
65
+ Object.create_shared_method('.default{{', NosSpec, [:stub])
66
+ Object.create_shared_method('.new_default{{', NosSpec, [:stub])
67
+
68
+ #Define some "crossover" symbols.
69
+ SymbolMap.add_entry('.is_class?', "foorth_is_class?".to_sym)
70
+ SymbolMap.add_entry('.to_s', :to_foorth_s)
71
+ SymbolMap.add_entry('.strlen', :foorth_strlen)
72
+ SymbolMap.add_entry('.strmax', :foorth_strmax)
73
+ SymbolMap.add_entry('.strmax2', :foorth_strmax2)
74
+ SymbolMap.add_entry('.pp', :foorth_pretty)
75
+ SymbolMap.add_entry('.load', :foorth_load_file)
76
+ end