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,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