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.
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,80 @@
1
+ # coding: utf-8
2
+
3
+ #* library/object_library.rb - The fOOrth Object class library.
4
+ module XfOOrth
5
+
6
+ #The .class method. This allows the class of any object to be determined.
7
+ # [obj] .class [class_of(obj)]
8
+ Object.create_shared_method('.class', TosSpec, [],
9
+ &lambda {|vm| vm.push(self.class)})
10
+
11
+ # Some basic "constant" value words.
12
+ #The self method.
13
+ # [] self [self]
14
+ VirtualMachine.create_shared_method('self', MacroSpec, [:macro, "vm.push(self); "])
15
+
16
+ #Get the name of an object or class.
17
+ # [obj] .with{{ ... }} [] Execute the block with self set to obj
18
+ Object.create_shared_method('.with{{', NosSpec, [], &lambda {|vm|
19
+ block = vm.pop
20
+ self.instance_exec(vm, nil, nil, &block)
21
+ })
22
+
23
+ #Get the name of an object or class.
24
+ # [obj] .name ["name of obj"]
25
+ Object.create_shared_method('.name', TosSpec, [],
26
+ &lambda {|vm| vm.push(self.foorth_name)})
27
+
28
+ #Get the object as a string.
29
+ # [obj] .to_s ["obj as a string"]
30
+ Object.create_shared_method('.to_s', TosSpec, [],
31
+ &lambda {|vm| vm.push(self.to_s)})
32
+
33
+ #Get the length of the object as a string.
34
+ # [obj] .strlen [n]; the length of the object's to_s string
35
+ Object.create_shared_method('.strlen', TosSpec, [],
36
+ &lambda {|vm| self.to_foorth_s(vm); vm.poke(vm.peek.length)})
37
+
38
+ # Some comparison words.
39
+ # [b,a] = if b == a then [true] else [false]
40
+ Object.create_shared_method('=', NosSpec, [],
41
+ &lambda {|vm| vm.poke(self == vm.peek); })
42
+
43
+ # [b,a] <> if b != a then [true] else [false]
44
+ Object.create_shared_method('<>', NosSpec, [],
45
+ &lambda {|vm| vm.poke(self != vm.peek); })
46
+
47
+
48
+ # Some identity comparison words.
49
+ # [b,a] identical? if b.object_id == a.object_id then [true] else [false]
50
+ Object.create_shared_method('identical?', NosSpec, [],
51
+ &lambda {|vm| vm.poke(self.object_id == vm.peek.object_id); })
52
+
53
+ # [b,a] distinct? if b.object_id != a.object_id then [true] else [false]
54
+ Object.create_shared_method('distinct?', NosSpec, [],
55
+ &lambda {|vm| vm.poke(self.object_id != vm.peek.object_id); })
56
+
57
+
58
+ # [b,a] max [max(b,a)]
59
+ Object.create_shared_method('max', NosSpec, [], &lambda {|vm|
60
+ begin
61
+ other = vm.peek
62
+ vm.poke((self > self.foorth_coerce(other)) ? self : other)
63
+ rescue
64
+ vm.data_stack.pop
65
+ raise
66
+ end
67
+ })
68
+
69
+ # [b,a] min [min(b,a)]
70
+ Object.create_shared_method('min', NosSpec, [], &lambda {|vm|
71
+ begin
72
+ other = vm.peek
73
+ vm.poke((self < self.foorth_coerce(other)) ? self : other)
74
+ rescue
75
+ vm.data_stack.pop
76
+ raise
77
+ end
78
+ })
79
+
80
+ end
@@ -0,0 +1,96 @@
1
+ # coding: utf-8
2
+
3
+ #* library/other_value_types_library.rb - Support for true, false, and nil in
4
+ # the fOOrth library.
5
+ module XfOOrth
6
+
7
+ # Connect the TrueClass class to the fOOrth class system.
8
+ TrueClass.create_foorth_proxy('True')
9
+
10
+ # [] true [true]
11
+ VirtualMachine.create_shared_method('true', MacroSpec, [:macro, "vm.push(true); "])
12
+
13
+ #Connect the FalseClass class to the fOOrth class system.
14
+ FalseClass.create_foorth_proxy('False')
15
+
16
+ # [] false [false]
17
+ VirtualMachine.create_shared_method('false', MacroSpec, [:macro, "vm.push(false); "])
18
+
19
+ # Connect the NilClass class to the fOOrth class system.
20
+ NilClass.create_foorth_proxy('Nil')
21
+
22
+ # [] nil [nil]
23
+ VirtualMachine.create_shared_method('nil', MacroSpec, [:macro, "vm.push(nil); "])
24
+
25
+
26
+ # Some boolean operation words.
27
+
28
+ # [b,a] && [b&a]
29
+ Object.create_shared_method('&&', TosSpec, [],
30
+ &lambda {|vm| vm.poke(vm.peek?); })
31
+ FalseClass.create_shared_method('&&', TosSpec, [],
32
+ &lambda {|vm| vm.poke(false); })
33
+ NilClass.create_shared_method('&&', TosSpec, [],
34
+ &lambda {|vm| vm.poke(false); })
35
+
36
+ # [b,a] || [b|a]
37
+ Object.create_shared_method('||', TosSpec, [],
38
+ &lambda {|vm| vm.poke(true); })
39
+ FalseClass.create_shared_method('||', TosSpec, [],
40
+ &lambda {|vm| vm.poke(vm.peek?); })
41
+ NilClass.create_shared_method('||', TosSpec, [],
42
+ &lambda {|vm| vm.poke(vm.peek?); })
43
+
44
+ # [b,a] ^^ [b^a]
45
+ Object.create_shared_method('^^', TosSpec, [],
46
+ &lambda {|vm| vm.poke(!vm.peek?); })
47
+ FalseClass.create_shared_method('^^', TosSpec, [],
48
+ &lambda {|vm| vm.poke(vm.peek?); })
49
+ NilClass.create_shared_method('^^', TosSpec, [],
50
+ &lambda {|vm| vm.poke(vm.peek?); })
51
+
52
+ # [a] not [!a]
53
+ Object.create_shared_method('not', TosSpec, [],
54
+ &lambda {|vm| vm.push(false); })
55
+ FalseClass.create_shared_method('not', TosSpec, [],
56
+ &lambda {|vm| vm.push(true); })
57
+ NilClass.create_shared_method('not', TosSpec, [],
58
+ &lambda {|vm| vm.push(true); })
59
+
60
+
61
+ # Some nil operation words
62
+
63
+ # [a] =nil [true/false]
64
+ Object.create_shared_method('nil=', TosSpec, [],
65
+ &lambda {|vm| vm.push(false); })
66
+ NilClass.create_shared_method('nil=', TosSpec, [],
67
+ &lambda {|vm| vm.push(true); })
68
+
69
+ # [a] <>nil [true/false]
70
+ Object.create_shared_method('nil<>', TosSpec, [],
71
+ &lambda {|vm| vm.push(true); })
72
+ NilClass.create_shared_method('nil<>', TosSpec, [],
73
+ &lambda {|vm| vm.push(false); })
74
+
75
+
76
+ # Special Float values.
77
+
78
+ # [] epsilon [Float::EPSILON]
79
+ VirtualMachine.create_shared_method('epsilon', MacroSpec, [:macro, "vm.push(Float::EPSILON); "])
80
+
81
+ # [] infinity [Float::INFINITY]
82
+ VirtualMachine.create_shared_method('infinity', MacroSpec, [:macro, "vm.push(Float::INFINITY); "])
83
+
84
+ # [] -infinity [-Float::INFINITY]
85
+ VirtualMachine.create_shared_method('-infinity', MacroSpec, [:macro, "vm.push(-Float::INFINITY); "])
86
+
87
+ # [] max_float [Float::MAX]
88
+ VirtualMachine.create_shared_method('max_float', MacroSpec, [:macro, "vm.push(Float::MAX); "])
89
+
90
+ # [] min_float [Float::MIN]
91
+ VirtualMachine.create_shared_method('min_float', MacroSpec, [:macro, "vm.push(Float::MIN); "])
92
+
93
+ # [] nan [Float::NAN]
94
+ VirtualMachine.create_shared_method('nan', MacroSpec, [:macro, "vm.push(Float::NAN); "])
95
+
96
+ end
@@ -0,0 +1,146 @@
1
+ # coding: utf-8
2
+
3
+ #* library/in_stream_library.rb - The fOOrth InStream class library.
4
+ module XfOOrth
5
+
6
+ out_stream = Object.create_foorth_subclass('OutStream').new_class
7
+
8
+ #* The fOOrth InStream file input mini-class.
9
+ class XfOOrth_OutStream
10
+
11
+ #The file used to perform the actual input operations.
12
+ attr_reader :file
13
+
14
+ #Set up the OutStream for the given file name.
15
+ #<br>Parameters
16
+ #* file_name - The name of the file.
17
+ #* file_mode - The mode to use opening the file. Either 'w' or 'a'
18
+ def initialize(file_name, file_mode)
19
+ @file = File.new(file_name, file_mode)
20
+ rescue
21
+ error "F51: Unable to open the file #{file_name} for writing."
22
+ end
23
+
24
+ end
25
+
26
+ #The .new method is stubbed out.
27
+ out_stream.create_exclusive_method('.new', TosSpec, [:stub])
28
+
29
+ # ["file_name" OutStream] .create [an_outstream]
30
+ out_stream.create_exclusive_method('.create', TosSpec, [], &lambda {|vm|
31
+ file_name = vm.pop.to_s
32
+ vm.push(XfOOrth_OutStream.new(file_name, 'w'))
33
+ })
34
+
35
+ # ["file_name" OutStream] .create{{ ... }} []
36
+ out_stream.create_exclusive_method('.create{{', TosSpec, [], &lambda {|vm|
37
+ block = vm.pop
38
+ file_name = vm.pop.to_s
39
+ out_stream = XfOOrth_OutStream.new(file_name, 'w')
40
+
41
+ begin
42
+ out_stream.instance_exec(vm, nil, nil, &block)
43
+ ensure
44
+ out_stream.file.close
45
+ end
46
+ })
47
+
48
+ # ["file_name" OutStream] .append{{ ... }} []
49
+ out_stream.create_exclusive_method('.append{{', TosSpec, [], &lambda {|vm|
50
+ block = vm.pop
51
+ file_name = vm.pop.to_s
52
+ out_stream = XfOOrth_OutStream.new(file_name, 'a')
53
+
54
+ begin
55
+ out_stream.instance_exec(vm, nil, nil, &block)
56
+ ensure
57
+ out_stream.file.close
58
+ end
59
+ })
60
+
61
+ # ["file_name" OutStream] .append [an_outstream]
62
+ out_stream.create_exclusive_method('.append', TosSpec, [], &lambda {|vm|
63
+ file_name = vm.pop.to_s
64
+ vm.push(XfOOrth_OutStream.new(file_name, 'a'))
65
+ })
66
+
67
+ # [an_outstream] .close []
68
+ out_stream.create_shared_method('.close', TosSpec, [], &lambda {|vm|
69
+ file.close
70
+ })
71
+
72
+ #[obj an_outstream] . []; print out the object as a string to the OutStream instance.
73
+ out_stream.create_shared_method('.', TosSpec, [],
74
+ &lambda {|vm| file << vm.pop})
75
+
76
+ #{self = an_outstream} [obj] ~ []; print out the object as a string to the OutStream self.
77
+ out_stream.create_shared_method('~', SelfSpec, [],
78
+ &lambda {|vm| file << vm.pop})
79
+
80
+ #{self = an_outstream} [] ~"a string" []; print out the string to the OutStream self.
81
+ out_stream.create_shared_method('~"', SelfSpec, [],
82
+ &lambda {|vm| file << vm.pop })
83
+
84
+
85
+ #[obj an_outstream] .emit []; print out a character to the OutStream.
86
+ out_stream.create_shared_method('.emit', TosSpec, [],
87
+ &lambda {|vm| file << vm.pop.to_foorth_c})
88
+
89
+ #{self = an_outstream} [obj] ~emit []; print out a character to the OutStream self.
90
+ out_stream.create_shared_method('~emit', SelfSpec, [],
91
+ &lambda {|vm| file << vm.pop.to_foorth_c})
92
+
93
+
94
+ #[an_outstream] .cr []; print out a newline to the OutStream instance.
95
+ out_stream.create_shared_method('.cr', TosSpec, [],
96
+ &lambda {|vm| file << "\n"})
97
+
98
+ #{self = an_outstream} [] ~cr []; print out a newline to the OutStream self.
99
+ out_stream.create_shared_method('~cr', SelfSpec, [],
100
+ &lambda {|vm| file << "\n"})
101
+
102
+
103
+ #[an_outstream] .space []; print out a space to the OutStream instance.
104
+ out_stream.create_shared_method('.space', TosSpec, [],
105
+ &lambda {|vm| file << " "})
106
+
107
+ #{self = an_outstream} [] ~space []; print out a space to the OutStream self.
108
+ out_stream.create_shared_method('~space', SelfSpec, [],
109
+ &lambda {|vm| file << " "})
110
+
111
+
112
+ #[count an_outstream] .spaces []; print out spaces to the OutStream instance.
113
+ out_stream.create_shared_method('.spaces', TosSpec, [],
114
+ &lambda {|vm| file << " " * Integer.foorth_coerce(vm.pop())})
115
+
116
+ #{self = an_outstream} [count] ~spaces []; print out spaces to the OutStream self.
117
+ out_stream.create_shared_method('~spaces', SelfSpec, [],
118
+ &lambda {|vm| file << " " * Integer.foorth_coerce(vm.pop())})
119
+
120
+ # [text_array "file_name" OutStream] .put_all []; Write the array to file_name
121
+ out_stream.create_exclusive_method('.put_all', TosSpec, [], &lambda {|vm|
122
+ file_name = vm.pop.to_s
123
+ file_source = vm.pop
124
+ out_stream = XfOOrth_OutStream.new(file_name, 'w')
125
+
126
+ begin
127
+ file_source.each {|line| out_stream.file.puts(line) }
128
+ ensure
129
+ out_stream.file.close
130
+ end
131
+ })
132
+
133
+ # [text_array "file_name" OutStream] .append_all []; Append the array to file_name
134
+ out_stream.create_exclusive_method('.append_all', TosSpec, [], &lambda {|vm|
135
+ file_name = vm.pop.to_s
136
+ file_source = vm.pop
137
+ out_stream = XfOOrth_OutStream.new(file_name, 'a')
138
+
139
+ begin
140
+ file_source.each {|line| out_stream.file.puts(line) }
141
+ ensure
142
+ out_stream.file.close
143
+ end
144
+ })
145
+
146
+ end
@@ -0,0 +1,65 @@
1
+ # coding: utf-8
2
+
3
+ #* library/procedure_library.rb - Proc support for the fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the Proc class to the fOOrth class system.
7
+ Proc.create_foorth_proxy('Procedure')
8
+
9
+ # A no operation place holder for procedure literals
10
+ VirtualMachine.create_shared_method('{{', MacroSpec, [:macro, " "])
11
+
12
+ # [procedure] .call [unspecified]
13
+ Proc.create_shared_method('.call', TosSpec, [],
14
+ &lambda {|vm| self.call(vm); })
15
+
16
+ # [owner procedure] .call_with [unspecified]
17
+ Proc.create_shared_method('.call_with', TosSpec, [],
18
+ &lambda {|vm| vm.pop.instance_exec(vm, &self); })
19
+
20
+ # [v procedure] .call_v [unspecified]
21
+ Proc.create_shared_method('.call_v', TosSpec, [],
22
+ &lambda {|vm| value = vm.pop; self.call(vm, value); })
23
+
24
+ # [x procedure] .call_x [unspecified]
25
+ Proc.create_shared_method('.call_x', TosSpec, [],
26
+ &lambda {|vm| index = vm.pop; self.call(vm, nil, index); })
27
+
28
+ # [v x procedure] .call_vx [unspecified]
29
+ Proc.create_shared_method('.call_vx', TosSpec, [],
30
+ &lambda {|vm| value, index = vm.popm(2); self.call(vm, value, index); })
31
+
32
+ # [procedure] .start [a_thread]
33
+ Proc.create_shared_method('.start', TosSpec, [], &lambda {|vm|
34
+ vm.push(self.do_thread_start(vm, '-'))
35
+ })
36
+
37
+ # [name procedure] .start_named [a_thread]
38
+ Proc.create_shared_method('.start_named', TosSpec, [], &lambda {|vm|
39
+ vm.push(self.do_thread_start(vm, vm.pop.to_s))
40
+ })
41
+
42
+ end
43
+
44
+ #A helper method in the Proc class for fOOrth threads.
45
+ class Proc
46
+ #Do the mechanics of starting a thread.
47
+ def do_thread_start(vm, vm_name)
48
+ block, interlock = self, Queue.new
49
+
50
+ result = Thread.new(vm.foorth_copy(vm_name)) do |vm_copy|
51
+
52
+ begin
53
+ self.foorth_init(vm_copy.compiler_reset.connect_vm_to_thread)
54
+ ensure
55
+ interlock.push(:ready)
56
+ end
57
+
58
+ vm_copy.instance_exec(vm_copy, &block)
59
+ end
60
+
61
+ interlock.pop
62
+ result
63
+ end
64
+ end
65
+
@@ -0,0 +1,47 @@
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
+ Queue.create_foorth_proxy("Queue")
10
+
11
+ #Uses the default implementation of the .new method.
12
+
13
+ # [v queue] .push []; v is pushed onto the queue
14
+ Queue.create_shared_method('.push', TosSpec, [], &lambda {|vm|
15
+ self.push(vm.pop)
16
+ })
17
+
18
+ # [queue] .pop [v]; v is popped from the queue
19
+ Queue.create_shared_method('.pop', TosSpec, [], &lambda {|vm|
20
+ if self.length > 0
21
+ vm.push(self.pop)
22
+ else
23
+ error "F31: Queue Underflow: .pop"
24
+ end
25
+ })
26
+
27
+ # [queue] .pend [v]; v is popped from the queue, will pend for data.
28
+ Queue.create_shared_method('.pend', TosSpec, [], &lambda {|vm|
29
+ vm.push(self.pop)
30
+ })
31
+
32
+ # [queue] .empty? [a_boolean]
33
+ Queue.create_shared_method('.empty?', TosSpec, [], &lambda {|vm|
34
+ vm.push(self.empty?)
35
+ })
36
+
37
+ # [queue] .length [an_integer]
38
+ Queue.create_shared_method('.length', TosSpec, [], &lambda {|vm|
39
+ vm.push(self.length)
40
+ })
41
+
42
+ # [queue] .clear []
43
+ Queue.create_shared_method('.clear', TosSpec, [], &lambda {|vm|
44
+ self.clear
45
+ })
46
+
47
+ end
@@ -0,0 +1,90 @@
1
+ # coding: utf-8
2
+
3
+ #* library/rational_library.rb - Numeric support for the fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the Rational class to the fOOrth class system.
7
+ Rational.create_foorth_proxy
8
+
9
+ # Some conversion words.
10
+ # [n d] rational [n/d]
11
+ VirtualMachine.create_shared_method('rational', VmSpec, [], &lambda {|vm|
12
+ num,den = popm(2)
13
+
14
+ begin
15
+ push(Rational(num.to_foorth_r, den.to_foorth_r))
16
+ rescue
17
+ push(nil)
18
+ end
19
+ })
20
+
21
+ # Some conversion words.
22
+ # [n d] rational! [n/d]
23
+ VirtualMachine.create_shared_method('rational!', VmSpec, [], &lambda {|vm|
24
+ num,den = popm(2)
25
+
26
+ begin
27
+ push(Rational(num.to_foorth_r, den.to_foorth_r))
28
+ rescue
29
+ error "F40: Cannot coerce a #{num.foorth_name}, #{den.foorth_name} to a Rational"
30
+ end
31
+ })
32
+
33
+ # [err_limit float] .rationalize_to [rational]
34
+ Numeric.create_shared_method('.rationalize_to', TosSpec, [], &lambda {|vm|
35
+ err_limit = Float.foorth_coerce(vm.pop)
36
+
37
+ vm.push(self.rationalize(err_limit))
38
+ })
39
+
40
+ Complex.create_shared_method('.rationalize_to', TosSpec, [:stub])
41
+
42
+ # [rational] .split [numerator, denominator]
43
+ Rational.create_shared_method('.split', TosSpec, [],
44
+ &lambda {|vm| vm.push(self.numerator); vm.push(self.denominator); })
45
+
46
+ # [a] .to_r [n/d]
47
+ Object.create_shared_method('.to_r', TosSpec, [], &lambda {|vm|
48
+ begin
49
+ vm.push(Rational(self))
50
+ rescue
51
+ vm.push(nil)
52
+ end
53
+ })
54
+
55
+ # [a] .to_r! [n/d]
56
+ Object.create_shared_method('.to_r!', TosSpec, [], &lambda {|vm|
57
+ begin
58
+ vm.push(Rational(self))
59
+ rescue
60
+ error "F40: Cannot convert a #{self.foorth_name} to a Rational instance"
61
+ end
62
+ })
63
+
64
+ # [a_float] .to_r [n/d]
65
+ Float.create_shared_method('.to_r', TosSpec, [], &lambda {|vm|
66
+ begin
67
+ vm.push(self.rationalize)
68
+ rescue
69
+ vm.push(nil)
70
+ end
71
+ })
72
+
73
+ # [a_float] .to_r! [n/d]
74
+ Float.create_shared_method('.to_r!', TosSpec, [], &lambda {|vm|
75
+ begin
76
+ vm.push(self.rationalize)
77
+ rescue
78
+ error "F40: Cannot convert a #{self.foorth_name} to a Rational instance"
79
+ end
80
+ })
81
+
82
+ # [n/d] .numerator [n]
83
+ Numeric.create_shared_method('.numerator', TosSpec, [],
84
+ &lambda {|vm| vm.push(self.numerator); })
85
+
86
+ # [n/d] .denominator [d]
87
+ Numeric.create_shared_method('.denominator', TosSpec, [],
88
+ &lambda {|vm| vm.push(self.denominator); })
89
+
90
+ end