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,181 @@
1
+ # coding: utf-8
2
+
3
+ #* library/compile_library.rb - The compile support fOOrth library.
4
+ module XfOOrth
5
+
6
+ # COLON =======================================
7
+
8
+ #The classic colon definition that creates a word in the Virtual Machine class.
9
+ # [] : <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
10
+ VirtualMachine.create_shared_method(':', VmSpec, [:immediate], &lambda {|vm|
11
+ if execute_mode?
12
+ target = VirtualMachine
13
+ name = vm.parser.get_word()
14
+ type = VmSpec
15
+ XfOOrth.validate_type(vm, type, name)
16
+
17
+ begin_compile_mode(':', vm: vm, &lambda {|vm, src, tags|
18
+ vm.dbg_puts "#{name} => #{src}"
19
+ target.create_shared_method(name, type, tags, &eval(src))
20
+ })
21
+
22
+ XfOOrth.add_common_compiler_locals(vm, ':')
23
+ else
24
+ delayed_compile_mode(':')
25
+ end
26
+ })
27
+
28
+ # BANG COLON ==================================
29
+
30
+ #A special colon definition that creates an immediate word in the
31
+ #Virtual Machine class.
32
+ # [] !: <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
33
+ VirtualMachine.create_shared_method('!:', VmSpec, [:immediate], &lambda {|vm|
34
+ if execute_mode?
35
+ target = VirtualMachine
36
+ name = vm.parser.get_word()
37
+ type = VmSpec
38
+ XfOOrth.validate_type(vm, type, name)
39
+
40
+ begin_compile_mode('!:', vm: vm, tags: [:immediate], &lambda {|vm, src, tags|
41
+ vm.dbg_puts "(!) #{name} => #{src}"
42
+ target.create_shared_method(name, type, tags, &eval(src))
43
+ })
44
+
45
+ XfOOrth.add_common_compiler_locals(vm, '!:')
46
+ else
47
+ delayed_compile_mode('!:')
48
+ end
49
+ })
50
+
51
+
52
+ # DOT COLON ===================================
53
+
54
+ # [a_class] .: <name> <stuff omitted> ; []; creates <name> on a_class
55
+ VirtualMachine.create_shared_method('.:', VmSpec, [:immediate], &lambda {|vm|
56
+ if execute_mode?
57
+ target = vm.pop
58
+ error "F13: The target of .: must be a class" unless target.is_a?(Class)
59
+
60
+ name = vm.parser.get_word()
61
+ type = XfOOrth.name_to_type(name)
62
+ XfOOrth.validate_type(vm, type, name)
63
+ XfOOrth.validate_string_method(type, target, name)
64
+
65
+ begin_compile_mode('.:', cls: target, &lambda {|vm, src, tags|
66
+ vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
67
+ target.create_shared_method(name, type, tags, &eval(src))
68
+ })
69
+
70
+ XfOOrth.add_common_compiler_locals(vm, '.:')
71
+ else
72
+ delayed_compile_mode('.:')
73
+ end
74
+ })
75
+
76
+
77
+ # DOT COLON COLON =============================
78
+
79
+ # [an_object] .:: <name> <stuff omitted> ; []; creates <name> on an_object
80
+ VirtualMachine.create_shared_method('.::', VmSpec, [:immediate], &lambda {|vm|
81
+ if execute_mode?
82
+ target = vm.pop
83
+ name = vm.parser.get_word()
84
+ type = XfOOrth.name_to_type(name)
85
+ XfOOrth.validate_type(vm, type, name)
86
+ XfOOrth.validate_string_method(type, target.class, name)
87
+
88
+ begin_compile_mode('.::', obj: target, &lambda {|vm, src, tags|
89
+ vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
90
+ target.create_exclusive_method(name, type, tags, &eval(src))
91
+ })
92
+
93
+ XfOOrth.add_common_compiler_locals(vm, '.::')
94
+ else
95
+ delayed_compile_mode('.::')
96
+ end
97
+ })
98
+
99
+
100
+ # COMMON LOCAL DEFNS ==========================
101
+
102
+ #Set up the common local defns.
103
+ #<br>Parameters:
104
+ #* vm - The current virtual machine instance.
105
+ #* ctrl - A list of valid start controls.
106
+ #<br>Endemic Code Smells
107
+ #* :reek:TooManyStatements
108
+ def self.add_common_compiler_locals(vm, ctrl)
109
+ context = vm.context
110
+
111
+ #Support for local variables.
112
+ context.create_local_method('var:', LocalSpec, [:immediate], &Local_Var_Action)
113
+ context.create_local_method('val:', LocalSpec, [:immediate], &Local_Val_Action)
114
+
115
+ #Support for instance variables.
116
+ context.create_local_method('var@:', LocalSpec, [:immediate], &Inst_Var_Action)
117
+ context.create_local_method('val@:', LocalSpec, [:immediate], &Inst_Val_Action)
118
+
119
+ #Support for super methods.
120
+ context.create_local_method('super', LocalSpec, [:immediate],
121
+ &lambda {|vm| vm << 'super(vm); ' })
122
+
123
+ #The standard end-compile adapter word: ';' semi-colon.
124
+ context.create_local_method(';', LocalSpec, [:immediate],
125
+ &lambda {|vm| vm.end_compile_mode([ctrl]) })
126
+ end
127
+
128
+ #Determine the type of method being created. This only applies to non-vm
129
+ #methods as vm methods are all of type VmSpec.
130
+ #<br>Parameters
131
+ #*name - The name of the method to be created.
132
+ #<Returns>
133
+ #* The class of the spec to be used for this method.
134
+ def self.name_to_type(name)
135
+ case name[0]
136
+ when '.'
137
+ TosSpec
138
+
139
+ when '~'
140
+ SelfSpec
141
+
142
+ when /[0-9A-Z$@#]/
143
+ error "F10: Invalid name for a method: #{name}"
144
+
145
+ else
146
+ NosSpec
147
+ end
148
+ end
149
+
150
+ #Compare the new method's spec against the specs of other methods of the
151
+ #same name. If no specs exist, create one on Object if the new spec is not
152
+ #a virtual machine spec.
153
+ #<br>Parameters
154
+ #*vm - The current virtual machine.
155
+ #*type - The class of the method to be created.
156
+ #*name - The name of the method to be created.
157
+ def self.validate_type(vm, type, name)
158
+ if (spec = vm.context.map(name))
159
+ if spec.class != type
160
+ error "F90: Spec type mismatch #{spec.foorth_name} vs #{type.foorth_name}"
161
+ end
162
+ else
163
+ Object.create_shared_method(name, type, [:stub]) unless type == VmSpec
164
+ end
165
+
166
+ end
167
+
168
+ #Check for the case where a string method is created on another class.
169
+ #<br>Parameters
170
+ #*type - The class of the method to be created.
171
+ #*target - The object that is to receive this method.
172
+ #*name - The name of the method to be created.
173
+ #<br>Endemic Code Smells
174
+ #* :reek:ControlParameter -- false positive
175
+ def self.validate_string_method(type, target, name)
176
+ if type == TosSpec && name[-1] == '"' && target != String
177
+ error "F13: Creating a string method #{name} on a #{target.foorth_name}"
178
+ end
179
+ end
180
+
181
+ end
@@ -0,0 +1,81 @@
1
+ # coding: utf-8
2
+
3
+ #* library/complex_library.rb - Numeric support for the fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the Complex class to the fOOrth class system.
7
+ Complex.create_foorth_proxy
8
+
9
+ #Some complex stubs.
10
+ Complex.create_shared_method('mod', NosSpec, [:stub])
11
+ Complex.create_shared_method('.ceil', TosSpec, [:stub])
12
+ Complex.create_shared_method('.floor', TosSpec, [:stub])
13
+ Complex.create_shared_method('.round', TosSpec, [:stub])
14
+ Complex.create_shared_method('<', NosSpec, [:stub])
15
+ Complex.create_shared_method('>', NosSpec, [:stub])
16
+ Complex.create_shared_method('<=', NosSpec, [:stub])
17
+ Complex.create_shared_method('>=', NosSpec, [:stub])
18
+ Complex.create_shared_method('<=>', NosSpec, [:stub])
19
+
20
+
21
+ #Some conversion words.
22
+ # [a b] complex [a+bi]
23
+ VirtualMachine.create_shared_method('complex', VmSpec, [], &lambda {|vm|
24
+ real,imag = popm(2)
25
+
26
+ begin
27
+ push(Complex(real,imag));
28
+ rescue
29
+ error "F40: Cannot coerce a #{real.foorth_name}, #{imag.foorth_name} to a Complex"
30
+ end
31
+ })
32
+
33
+ # [a+bi] .split [a b]
34
+ Complex.create_shared_method('.split', TosSpec, [],
35
+ &lambda {|vm| vm.push(self.real); vm.push(self.imaginary); })
36
+
37
+ # [a] .to_x [compleX or nil]
38
+ Object.create_shared_method('.to_x', TosSpec, [], &lambda {|vm|
39
+ begin
40
+ vm.push(Complex(self))
41
+ rescue
42
+ vm.push(nil)
43
+ end
44
+ })
45
+
46
+ # [a] .to_x! [compleX]
47
+ Object.create_shared_method('.to_x!', TosSpec, [], &lambda {|vm|
48
+ begin
49
+ vm.push(Complex(self))
50
+ rescue
51
+ error "F40: Cannot coerce a #{self.foorth_name} to a Complex"
52
+ end
53
+ })
54
+
55
+ # [a+bi] .imaginary [b]
56
+ Numeric.create_shared_method('.imaginary', TosSpec, [],
57
+ &lambda {|vm| vm.push(self.imaginary); })
58
+
59
+ # [a+bi] .real [a]
60
+ Numeric.create_shared_method('.real', TosSpec, [],
61
+ &lambda {|vm| vm.push(self.real); })
62
+
63
+ # [a+bi] .angle [atan2(b,a) or 0]
64
+ Numeric.create_shared_method('.angle', TosSpec, [],
65
+ &lambda {|vm| vm.push(self.angle); })
66
+
67
+ # [a+bi] .magnitude [sqrt(a**2 + b**2)]
68
+ Numeric.create_shared_method('.magnitude', TosSpec, [],
69
+ &lambda {|vm| vm.push(self.magnitude); })
70
+
71
+ # [a+bi] .conjugate [a-bi]
72
+ # Complex convicts that behave well are allowed .conjugate visits.
73
+ Numeric.create_shared_method('.conjugate', TosSpec, [],
74
+ &lambda {|vm| vm.push(self.conjugate); })
75
+
76
+ # [a+bi] .polar [magnitude angle]
77
+ # Convert a complex number to polar format
78
+ Numeric.create_shared_method('.polar', TosSpec, [],
79
+ &lambda {|vm| vm.pushm(self.polar); })
80
+
81
+ end
@@ -0,0 +1,116 @@
1
+ # coding: utf-8
2
+
3
+ #* library/ctrl_struct_library.rb - The control structures fOOrth library.
4
+ module XfOOrth
5
+
6
+ # [boolean] if (boolean true code) else (boolean false code) then
7
+ VirtualMachine.create_shared_method('if', VmSpec, [:immediate], &lambda {|vm|
8
+ suspend_execute_mode('if vm.pop? then ', :if)
9
+
10
+ context.create_local_method('else', LocalSpec, [:immediate], &lambda {|vm|
11
+ check_deferred_mode('else ', [:if])
12
+ vm.context.remove_local_method('else')
13
+ })
14
+
15
+ context.create_local_method('then', LocalSpec, [:immediate],
16
+ &lambda {|vm| resume_execute_mode('end; ', [:if]) })
17
+ })
18
+
19
+ # [unspecified] switch ... end [unspecified]
20
+ VirtualMachine.create_shared_method('switch', VmSpec, [:immediate], &lambda {|vm|
21
+ suspend_execute_mode('loop do; ', :switch)
22
+
23
+ context.create_local_method('break', LocalSpec, [:immediate],
24
+ &lambda {|vm| vm << 'break; ' })
25
+
26
+ context.create_local_method('?break', LocalSpec, [:immediate],
27
+ &lambda {|vm| vm << 'break if vm.pop?; ' })
28
+
29
+ context.create_local_method('end', LocalSpec, [:immediate],
30
+ &lambda {|vm| resume_execute_mode('break; end; ', [:switch]) })
31
+ })
32
+
33
+ # Looping constructs for fOOrth.
34
+ VirtualMachine.create_shared_method('begin', VmSpec, [:immediate], &lambda {|vm|
35
+ suspend_execute_mode('begin ', :begin)
36
+
37
+ context.create_local_method('while', LocalSpec, [:immediate],
38
+ &lambda {|vm| check_deferred_mode('break unless vm.pop?; ', [:begin]) })
39
+
40
+ context.create_local_method('until', LocalSpec, [:immediate],
41
+ &lambda {|vm| resume_execute_mode('end until vm.pop?; ', [:begin]) })
42
+
43
+ context.create_local_method('again', LocalSpec, [:immediate],
44
+ &lambda {|vm| resume_execute_mode('end until false; ', [:begin]) })
45
+
46
+ context.create_local_method('repeat', LocalSpec, [:immediate],
47
+ &lambda {|vm| resume_execute_mode('end until false; ', [:begin]) })
48
+ })
49
+
50
+ # Support for the sanitized do loop constructs!
51
+ VirtualMachine.create_shared_method('do', VmSpec, [:immediate], &lambda {|vm|
52
+ jvar = context[:jloop].to_s
53
+ suspend_execute_mode("vm.vm_do(#{jvar}) {|iloop, jloop| ", :do)
54
+ context[:jloop] = 'iloop'
55
+
56
+ context.create_local_method('i', MacroSpec,
57
+ [:macro, 'vm.push(iloop[0]); '])
58
+
59
+ context.create_local_method('j', MacroSpec,
60
+ [:macro, 'vm.push(jloop[0]); '])
61
+
62
+ context.create_local_method('-i', MacroSpec,
63
+ [:macro, 'vm.push(iloop[2] - iloop[0]); '])
64
+
65
+ context.create_local_method('-j', MacroSpec,
66
+ [:macro, 'vm.push(jloop[2] - jloop[0]); '])
67
+
68
+ context.create_local_method('loop', LocalSpec, [:immediate],
69
+ &lambda {|vm| resume_execute_mode('iloop[0] += 1}; ', [:do]) })
70
+
71
+ context.create_local_method('+loop', LocalSpec, [:immediate],
72
+ &lambda {|vm| resume_execute_mode('iloop[0] += vm.vm_do_increment}; ', [:do]) })
73
+ })
74
+
75
+ #Support for the try ... catch ... finally ... end construct.
76
+ VirtualMachine.create_shared_method('try', VmSpec, [:immediate], &lambda {|vm|
77
+ suspend_execute_mode('begin; ', :try_block)
78
+
79
+ SymbolMap.add_entry('error') #Make sure an entry for 'error' exists.
80
+ SymbolMap.add_entry('?"') #Make sure an entry for '?"' exists.
81
+
82
+ context.create_local_method('catch', LocalSpec, [:immediate], &lambda {|vm|
83
+ check_deferred_mode('rescue StandardError, SignalException => error; ', [:try_block])
84
+
85
+ vm.context.create_local_method('?"', LocalSpec, [:immediate], &lambda {|vm|
86
+ str = vm.pop
87
+ vm << "vm.push(error.foorth_match(#{str.foorth_embed})); "
88
+ })
89
+
90
+ vm.context.create_local_method('error', LocalSpec, [:immediate], &lambda {|vm|
91
+ vm << 'vm.push(error.foorth_message); '
92
+ })
93
+
94
+ vm.context.create_local_method('bounce', LocalSpec, [:immediate], &lambda {|vm|
95
+ vm << 'raise; '
96
+ })
97
+
98
+ vm.context.remove_local_method('catch')
99
+ })
100
+
101
+ context.create_local_method('finally', LocalSpec, [:immediate], &lambda {|vm|
102
+ check_deferred_mode('ensure; ', [:try_block])
103
+
104
+ vm.context.remove_local_method('catch')
105
+ vm.context.remove_local_method('finally')
106
+ vm.context.remove_local_method('?"')
107
+ vm.context.remove_local_method('error')
108
+ vm.context.remove_local_method('bounce')
109
+ })
110
+
111
+ vm.context.create_local_method('end', LocalSpec, [:immediate], &lambda {|vm|
112
+ vm.resume_execute_mode('end; ', [:try_block])
113
+ })
114
+ })
115
+
116
+ end
@@ -0,0 +1,100 @@
1
+ # coding: utf-8
2
+
3
+ #* library/data_ref_library.rb - The data references (variables) fOOrth library.
4
+ module XfOOrth
5
+
6
+ #The lambda used to define local variables. fOOrth language definition is:
7
+ # [n] var: lv [], lv = [n]
8
+ Local_Var_Action = lambda {|vm|
9
+ name = vm.parser.get_word()
10
+ error "F10: Invalid var name #{name}" unless /^[a-z][a-z0-9_]*$/ =~ name
11
+ symbol = XfOOrth::SymbolMap.add_entry(name)
12
+ vm << "#{symbol} = [vm.pop]; "
13
+
14
+ #Add a local defn for the local variable.
15
+ vm.context.create_local_method(name, LocalSpec, [:immediate],
16
+ &lambda {|vm| vm << "vm.push(#{symbol}); "} )
17
+ }
18
+
19
+ #The lambda used to define local values. fOOrth language definition is:
20
+ # [n] val: lv [], lv = n
21
+ Local_Val_Action = lambda {|vm|
22
+ name = vm.parser.get_word()
23
+ error "F10: Invalid val name #{name}" unless /^[a-z][a-z0-9_]*$/ =~ name
24
+ symbol = XfOOrth::SymbolMap.add_entry(name)
25
+ vm << "#{symbol} = vm.pop; "
26
+
27
+ #Add a local defn for the local variable.
28
+ vm.context.create_local_method(name, LocalSpec, [:immediate],
29
+ &lambda {|vm| vm << "vm.push(#{symbol}); "} )
30
+ }
31
+
32
+ #The lambda used to define instance variables. fOOrth language definition is:
33
+ # [n] var@: @iv [], @iv = [n]
34
+ Inst_Var_Action = lambda { |vm|
35
+ name = vm.parser.get_word()
36
+ error "F10: Invalid var name #{name}" unless /^@[a-z][a-z0-9_]*$/ =~ name
37
+ symbol = XfOOrth::SymbolMap.add_entry(name)
38
+ vm << "#{'@'+(symbol.to_s)} = [vm.pop]; "
39
+
40
+ #Add a defn for the instance variable.
41
+ vm.context.recvr.create_shared_method(name, InstanceVarSpec, [])
42
+ }
43
+
44
+ #The lambda used to define instance values. fOOrth language definition is:
45
+ # [n] val@: @iv [], @iv = n
46
+ Inst_Val_Action = lambda { |vm|
47
+ name = vm.parser.get_word()
48
+ error "F10: Invalid val name #{name}" unless /^@[a-z][a-z0-9_]*$/ =~ name
49
+ symbol = XfOOrth::SymbolMap.add_entry(name)
50
+ vm << "#{'@'+(symbol.to_s)} = vm.pop; "
51
+
52
+ #Add a defn for the instance variable.
53
+ vm.context.recvr.create_shared_method(name, InstanceVarSpec, [])
54
+ }
55
+
56
+ # Thread Variables
57
+ # [n] var#: #tv [], Thread.current[#tv] = [n]
58
+ VirtualMachine.create_shared_method('var#:', VmSpec, [], &lambda {|vm|
59
+ name = vm.parser.get_word()
60
+ error "F10: Invalid var name #{name}" unless /^#[a-z][a-z0-9_]*$/ =~ name
61
+ symbol = XfOOrth::SymbolMap.add_entry(name)
62
+ @data[symbol] = [vm.pop]
63
+
64
+ vm.create_exclusive_method(name, ThreadVarSpec, [])
65
+ })
66
+
67
+ # Thread values.
68
+ # [n] val#: #tv [], Thread.current[#tv] = n
69
+ VirtualMachine.create_shared_method('val#:', VmSpec, [], &lambda {|vm|
70
+ name = vm.parser.get_word()
71
+ error "F10: Invalid val name #{name}" unless /^#[a-z][a-z0-9_]*$/ =~ name
72
+ symbol = XfOOrth::SymbolMap.add_entry(name)
73
+ @data[symbol] = vm.pop
74
+
75
+ vm.create_exclusive_method(name, ThreadVarSpec, [])
76
+ })
77
+
78
+ # Global Variables
79
+ # [n] var$: $gv [], $gv = [n]
80
+ VirtualMachine.create_shared_method('var$:', VmSpec, [], &lambda {|vm|
81
+ name = vm.parser.get_word()
82
+ error "F10: Invalid var name #{name}" unless /^\$[a-z][a-z0-9_]*$/ =~ name
83
+ symbol = XfOOrth::SymbolMap.add_entry(name)
84
+ eval "#{'$' + symbol.to_s} = [vm.pop]"
85
+
86
+ $FOORTH_GLOBALS[symbol] = GlobalVarSpec.new(name, symbol, [])
87
+ })
88
+
89
+ # Global Values
90
+ # [n] val$: $gv [], $gv = n
91
+ VirtualMachine.create_shared_method('val$:', VmSpec, [], &lambda {|vm|
92
+ name = vm.parser.get_word()
93
+ error "F10: Invalid val name #{name}" unless /^\$[a-z][a-z0-9_]*$/ =~ name
94
+ symbol = XfOOrth::SymbolMap.add_entry(name)
95
+ eval "#{'$' + symbol.to_s} = vm.pop"
96
+
97
+ $FOORTH_GLOBALS[symbol] = GlobalVarSpec.new(name, symbol, [])
98
+ })
99
+
100
+ end