fOOrth 0.6.6 → 0.6.11

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 (67) hide show
  1. checksums.yaml +5 -5
  2. data/CODE_OF_CONDUCT.md +49 -0
  3. data/README.md +32 -1
  4. data/fOOrth.gemspec +3 -3
  5. data/integration/array_lib_tests.rb +10 -0
  6. data/integration/compile_lib_tests.rb +67 -1
  7. data/integration/exception_lib_tests.rb +4 -0
  8. data/integration/hash_lib_tests.rb +9 -0
  9. data/integration/numeric_lib_tests.rb +326 -321
  10. data/integration/procedure_lib_tests.rb +16 -0
  11. data/integration/queue_lib_tests.rb +2 -1
  12. data/integration/stack_lib_tests.rb +2 -1
  13. data/integration/stdio_lib_tests.rb +62 -0
  14. data/integration/string_lib_tests.rb +11 -0
  15. data/integration/thread_lib_tests.rb +19 -5
  16. data/lib/fOOrth.rb +0 -2
  17. data/lib/fOOrth/compiler/context.rb +64 -64
  18. data/lib/fOOrth/compiler/context/locals.rb +34 -34
  19. data/lib/fOOrth/compiler/context/map_name.rb +85 -74
  20. data/lib/fOOrth/compiler/context/tags.rb +60 -48
  21. data/lib/fOOrth/compiler/process/generate.rb +1 -1
  22. data/lib/fOOrth/compiler/process/procedure.rb +40 -0
  23. data/lib/fOOrth/compiler/word_specs.rb +3 -3
  24. data/lib/fOOrth/core/object.rb +1 -1
  25. data/lib/fOOrth/library.rb +3 -0
  26. data/lib/fOOrth/library/alias_library.rb +126 -0
  27. data/lib/fOOrth/library/array_library.rb +41 -21
  28. data/lib/fOOrth/library/command_library.rb +1 -1
  29. data/lib/fOOrth/library/compile_library.rb +266 -264
  30. data/lib/fOOrth/library/complex_library.rb +82 -80
  31. data/lib/fOOrth/library/float_library.rb +37 -0
  32. data/lib/fOOrth/library/formatting/array.rb +90 -0
  33. data/lib/fOOrth/library/formatting/bullets.rb +15 -79
  34. data/lib/fOOrth/library/formatting/columns.rb +20 -42
  35. data/lib/fOOrth/library/formatting/hash.rb +29 -0
  36. data/lib/fOOrth/library/formatting/nil.rb +13 -0
  37. data/lib/fOOrth/library/formatting/object.rb +18 -0
  38. data/lib/fOOrth/library/formatting/string.rb +46 -0
  39. data/lib/fOOrth/library/hash_library.rb +14 -6
  40. data/lib/fOOrth/library/introspection/class.rb +20 -18
  41. data/lib/fOOrth/library/introspection/context.rb +3 -2
  42. data/lib/fOOrth/library/introspection/object.rb +42 -20
  43. data/lib/fOOrth/library/introspection/string.rb +21 -5
  44. data/lib/fOOrth/library/introspection/vm.rb +17 -29
  45. data/lib/fOOrth/library/mutex_library.rb +8 -1
  46. data/lib/fOOrth/library/numeric_library.rb +359 -380
  47. data/lib/fOOrth/library/procedure_library.rb +69 -65
  48. data/lib/fOOrth/library/queue_library.rb +6 -1
  49. data/lib/fOOrth/library/rational_library.rb +89 -89
  50. data/lib/fOOrth/library/stack_library.rb +6 -1
  51. data/lib/fOOrth/library/stdio_library.rb +11 -8
  52. data/lib/fOOrth/library/string_library.rb +21 -6
  53. data/lib/fOOrth/library/stubs_library.rb +49 -0
  54. data/lib/fOOrth/monkey_patch/exceptions.rb +2 -6
  55. data/lib/fOOrth/monkey_patch/object.rb +7 -0
  56. data/lib/fOOrth/version.rb +1 -1
  57. data/reek.txt +1 -59
  58. data/sire.rb +0 -1
  59. data/tests/compiler/context_tests.rb +188 -177
  60. data/tests/compiler/file_source_tests.rb +130 -130
  61. data/tests/compiler/parser_tests.rb +4 -4
  62. data/tests/compiler/string_source_tests.rb +4 -4
  63. data/tests/core_tests.rb +138 -138
  64. data/tests/monkey_patch/complex_test.rb +24 -24
  65. data/tests/monkey_patch/object_test.rb +49 -49
  66. data/tests/monkey_patch/string_test.rb +61 -61
  67. metadata +20 -13
@@ -9,7 +9,7 @@ module XfOOrth
9
9
 
10
10
  #Execute a command to the shell.
11
11
  VirtualMachine.create_shared_method(')"', MacroSpec,
12
- [:macro, "system(vm.pop()); "])
12
+ [:macro, "system(vm.pop().to_s.chomp + \"\n\"); "])
13
13
 
14
14
  #Enter debug mode. Warning! This is really verbose!
15
15
  VirtualMachine.create_shared_method(')debug', MacroSpec,
@@ -1,264 +1,266 @@
1
- # coding: utf-8
2
-
3
- #* library/compile_library.rb - The compile support fOOrth library.
4
- module XfOOrth
5
-
6
- # METHOD CASTING ==============================
7
-
8
- #TosSpec method cast.
9
- VirtualMachine.create_shared_method("'.", VmSpec, [],
10
- &lambda {|vm| vm.set_cast(TosSpec) })
11
-
12
- #NosSpec method cast.
13
- VirtualMachine.create_shared_method("'*", VmSpec, [],
14
- &lambda {|vm| vm.set_cast(NosSpec) })
15
-
16
- #SelfSpec method cast.
17
- VirtualMachine.create_shared_method("'~", VmSpec, [],
18
- &lambda {|vm| vm.set_cast(SelfSpec) })
19
-
20
- # COLON =======================================
21
-
22
- #The classic colon definition that creates a word in the Virtual Machine class.
23
- # [] : <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
24
- VirtualMachine.create_shared_method(':', VmSpec, [:immediate], &lambda {|vm|
25
- if execute_mode?
26
- verify_cast([VmSpec])
27
- target = VirtualMachine
28
- name = vm.parser.get_word()
29
- type = VmSpec
30
- XfOOrth.validate_type(vm, type, name)
31
-
32
- begin_compile_mode(':', vm: vm, &lambda {|vm, src, tags|
33
- vm.dbg_puts "#{name} => #{src}"
34
- target.create_shared_method(name, type, tags, &eval(src))
35
- })
36
-
37
- XfOOrth.add_common_compiler_locals(vm, ':')
38
- else
39
- delayed_compile_mode(':')
40
- end
41
- })
42
-
43
- # BANG COLON ==================================
44
-
45
- #A special colon definition that creates an immediate word in the
46
- #Virtual Machine class.
47
- # [] !: <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
48
- VirtualMachine.create_shared_method('!:', VmSpec, [:immediate], &lambda {|vm|
49
- if execute_mode?
50
- verify_cast([VmSpec])
51
- target = VirtualMachine
52
- name = vm.parser.get_word()
53
- type = VmSpec
54
- XfOOrth.validate_type(vm, type, name)
55
-
56
- begin_compile_mode('!:', vm: vm, tags: [:immediate], &lambda {|vm, src, tags|
57
- vm.dbg_puts "(!) #{name} => #{src}"
58
- target.create_shared_method(name, type, tags, &eval(src))
59
- })
60
-
61
- XfOOrth.add_common_compiler_locals(vm, '!:')
62
- else
63
- delayed_compile_mode('!:')
64
- end
65
- })
66
-
67
-
68
- # DOT COLON ===================================
69
-
70
- # [a_class] .: <name> <stuff omitted> ; []; creates <name> on a_class
71
- VirtualMachine.create_shared_method('.:', VmSpec, [:immediate], &lambda {|vm|
72
- if execute_mode?
73
- target = vm.pop
74
- error "F13: The target of .: must be a class" unless target.is_a?(Class)
75
-
76
- name = vm.parser.get_word()
77
- type = XfOOrth.name_to_type(name, get_cast)
78
- XfOOrth.validate_type(vm, type, name)
79
- XfOOrth.validate_string_method(type, target, name)
80
-
81
- begin_compile_mode('.:', cls: target, &lambda {|vm, src, tags|
82
- vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
83
- target.create_shared_method(name, type, tags, &eval(src))
84
- })
85
-
86
- XfOOrth.add_common_compiler_locals(vm, '.:')
87
- XfOOrth.add_dot_colon_locals(vm.context)
88
- else
89
- delayed_compile_mode('.:')
90
- end
91
- })
92
-
93
- #The procedure used for dot colon instance vars
94
- DC_VAR = lambda {|vm|
95
- var_name = vm.parser.get_word()
96
-
97
- unless /^@[a-z][a-z0-9_]*$/ =~ var_name
98
- error "F10: Invalid var name #{var_name}"
99
- end
100
-
101
- var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
102
- vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
103
-
104
- vm.context.target_class.create_shared_method(var_name, InstanceVarSpec, [])
105
- }
106
-
107
- #The procedure used for dot colon instance vals
108
- DC_VAL = lambda {|vm|
109
- val_name = vm.parser.get_word()
110
-
111
- unless /^@[a-z][a-z0-9_]*$/ =~ val_name
112
- error "F10: Invalid val name #{val_name}"
113
- end
114
-
115
- val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
116
- vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
117
-
118
- vm.context.target_class.create_shared_method(val_name, InstanceVarSpec, [])
119
- }
120
-
121
- # Add locals specific to a dot colon methods.
122
- def self.add_dot_colon_locals(context)
123
- context.create_local_method('var@:', LocalSpec, [:immediate], &DC_VAR)
124
- context.create_local_method('val@:', LocalSpec, [:immediate], &DC_VAL)
125
- end
126
-
127
-
128
- # DOT COLON COLON =============================
129
-
130
- # [an_object] .:: <name> <stuff omitted> ; []; creates <name> on an_object
131
- VirtualMachine.create_shared_method('.::', VmSpec, [:immediate], &lambda {|vm|
132
- if execute_mode?
133
- target = vm.pop
134
- name = vm.parser.get_word()
135
- type = XfOOrth.name_to_type(name, get_cast)
136
- XfOOrth.validate_type(vm, type, name)
137
- XfOOrth.validate_string_method(type, target.class, name)
138
-
139
- begin_compile_mode('.::', obj: target, &lambda {|vm, src, tags|
140
- vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
141
- target.create_exclusive_method(name, type, tags, &eval(src))
142
- })
143
-
144
- XfOOrth.add_common_compiler_locals(vm, '.::')
145
- XfOOrth.add_dot_colon_colon_locals(vm.context)
146
- else
147
- delayed_compile_mode('.::')
148
- end
149
- })
150
-
151
- #The procedure used for dot colon colon instance vars
152
- DCC_VAR = lambda { |vm|
153
- var_name = vm.parser.get_word()
154
-
155
- unless /^@[a-z][a-z0-9_]*$/ =~ var_name
156
- error "F10: Invalid var name #{var_name}"
157
- end
158
-
159
- var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
160
- vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
161
-
162
- vm.context.target_object.create_exclusive_method(var_name, InstanceVarSpec, [])
163
- }
164
-
165
- #The procedure used for dot colon colon instance vals
166
- DCC_VAL = lambda {|vm|
167
- val_name = vm.parser.get_word()
168
-
169
- unless /^@[a-z][a-z0-9_]*$/ =~ val_name
170
- error "F10: Invalid val name #{val_name}"
171
- end
172
-
173
- val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
174
- vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
175
-
176
- vm.context.target_object.create_exclusive_method(val_name, InstanceVarSpec, [])
177
- }
178
-
179
- # Add locals specific to a dot colon colon methods.
180
- def self.add_dot_colon_colon_locals(context)
181
- context.create_local_method('var@:', LocalSpec, [:immediate], &DCC_VAR)
182
- context.create_local_method('val@:', LocalSpec, [:immediate], &DCC_VAL)
183
- end
184
-
185
- # COMMON LOCAL DEFNS ==========================
186
-
187
- #Set up the common local defns.
188
- #<br>Parameters:
189
- #* vm - The current virtual machine instance.
190
- #* ctrl - A list of valid start controls.
191
- def self.add_common_compiler_locals(vm, ctrl)
192
- context = vm.context
193
-
194
- #Support for local data.
195
- context.create_local_method('var:', LocalSpec, [:immediate], &Local_Var_Action)
196
- context.create_local_method('val:', LocalSpec, [:immediate], &Local_Val_Action)
197
-
198
- #Support for super methods.
199
- context.create_local_method('super', LocalSpec, [:immediate],
200
- &lambda {|vm| vm << 'super(vm); ' })
201
-
202
- #The standard end-compile adapter word: ';' semi-colon.
203
- context.create_local_method(';', LocalSpec, [:immediate], &lambda {|vm|
204
- vm.clear_cast
205
- vm.end_compile_mode([ctrl])
206
- })
207
- end
208
-
209
- #Determine the type of method being created. This only applies to non-vm
210
- #methods as vm methods are all of type VmSpec.
211
- #<br>Parameters
212
- #*name - The name of the method to be created.
213
- #<Returns>
214
- #* The class of the spec to be used for this method.
215
- def self.name_to_type(name, cast_spec=nil)
216
- normal_spec = case name[0]
217
- when '.'
218
- TosSpec
219
-
220
- when '~'
221
- SelfSpec
222
-
223
- when /[0-9A-Z$@#]/
224
- error "F10: Invalid name for a method: #{name}"
225
-
226
- else
227
- NosSpec
228
- end
229
-
230
- cast_spec || normal_spec
231
- end
232
-
233
- #Compare the new method's spec against the specs of other methods of the
234
- #same name. If no specs exist, create one on Object if the new spec is not
235
- #a virtual machine spec.
236
- #<br>Parameters
237
- #*vm - The current virtual machine.
238
- #*type - The class of the method to be created.
239
- #*name - The name of the method to be created.
240
- def self.validate_type(vm, type, name)
241
- if (spec = vm.context.map(name, false))
242
- if spec.class != type
243
- error "F90: Spec type mismatch #{spec.foorth_name} vs #{type.foorth_name}"
244
- end
245
- else
246
- Object.create_shared_method(name, type, [:stub]) unless type == VmSpec
247
- end
248
-
249
- end
250
-
251
- #Check for the case where a string method is created on another class.
252
- #<br>Parameters
253
- #*type - The class of the method to be created.
254
- #*target - The object that is to receive this method.
255
- #*name - The name of the method to be created.
256
- #<br>Endemic Code Smells
257
- #* :reek:ControlParameter -- false positive
258
- def self.validate_string_method(type, target, name)
259
- if type == TosSpec && name[-1] == '"' && target != String
260
- error "F13: Creating a string method #{name} on a #{target.foorth_name}"
261
- end
262
- end
263
-
264
- end
1
+ # coding: utf-8
2
+
3
+ #* library/compile_library.rb - The compile support fOOrth library.
4
+ module XfOOrth
5
+
6
+ # METHOD CASTING ==============================
7
+
8
+ #TosSpec method cast.
9
+ VirtualMachine.create_shared_method("'.", VmSpec, [],
10
+ &lambda {|vm| vm.set_cast(TosSpec) })
11
+
12
+ #NosSpec method cast.
13
+ VirtualMachine.create_shared_method("'*", VmSpec, [],
14
+ &lambda {|vm| vm.set_cast(NosSpec) })
15
+
16
+ #SelfSpec method cast.
17
+ VirtualMachine.create_shared_method("'~", VmSpec, [],
18
+ &lambda {|vm| vm.set_cast(SelfSpec) })
19
+
20
+ # COLON =======================================
21
+
22
+ #The classic colon definition that creates a word in the Virtual Machine class.
23
+ # [] : <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
24
+ VirtualMachine.create_shared_method(':', VmSpec, [:immediate], &lambda {|vm|
25
+ if execute_mode?
26
+ verify_cast([VmSpec])
27
+ target = VirtualMachine
28
+ name = vm.parser.get_word()
29
+ type = VmSpec
30
+ XfOOrth.validate_type(vm, type, name)
31
+
32
+ begin_compile_mode(':', vm: vm, &lambda {|vm, src, tags|
33
+ vm.dbg_puts "#{name} => #{src}"
34
+ target.create_shared_method(name, type, tags, &eval(src))
35
+ })
36
+
37
+ XfOOrth.add_common_compiler_locals(vm, ':')
38
+ else
39
+ delayed_compile_mode(':')
40
+ end
41
+ })
42
+
43
+ # BANG COLON ==================================
44
+
45
+ #A special colon definition that creates an immediate word in the
46
+ #Virtual Machine class.
47
+ # [] !: <name> <stuff omitted> ; []; creates <name> on the VirtualMachine
48
+ VirtualMachine.create_shared_method('!:', VmSpec, [:immediate], &lambda {|vm|
49
+ if execute_mode?
50
+ verify_cast([VmSpec])
51
+ target = VirtualMachine
52
+ name = vm.parser.get_word()
53
+ type = VmSpec
54
+ XfOOrth.validate_type(vm, type, name)
55
+
56
+ begin_compile_mode('!:', vm: vm, tags: [:immediate], &lambda {|vm, src, tags|
57
+ vm.dbg_puts "(!) #{name} => #{src}"
58
+ target.create_shared_method(name, type, tags, &eval(src))
59
+ })
60
+
61
+ XfOOrth.add_common_compiler_locals(vm, '!:')
62
+ else
63
+ delayed_compile_mode('!:')
64
+ end
65
+ })
66
+
67
+
68
+ # DOT COLON ===================================
69
+
70
+ # [a_class] .: <name> <stuff omitted> ; []; creates <name> on a_class
71
+ VirtualMachine.create_shared_method('.:', VmSpec, [:immediate], &lambda {|vm|
72
+ if execute_mode?
73
+ target = vm.pop
74
+ error "F13: The target of .: must be a class" unless target.is_a?(Class)
75
+
76
+ name = vm.parser.get_word()
77
+ type = XfOOrth.name_to_type(name, self)
78
+ XfOOrth.validate_type(vm, type, name)
79
+ XfOOrth.validate_string_method(type, target, name)
80
+
81
+ begin_compile_mode('.:', cls: target, &lambda {|vm, src, tags|
82
+ vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
83
+ target.create_shared_method(name, type, tags, &eval(src))
84
+ })
85
+
86
+ XfOOrth.add_common_compiler_locals(vm, '.:')
87
+ XfOOrth.add_dot_colon_locals(vm.context)
88
+ else
89
+ delayed_compile_mode('.:')
90
+ end
91
+ })
92
+
93
+ #The procedure used for dot colon instance vars
94
+ DC_VAR = lambda {|vm|
95
+ var_name = vm.parser.get_word()
96
+
97
+ unless /^@[a-z][a-z0-9_]*$/ =~ var_name
98
+ error "F10: Invalid var name #{var_name}"
99
+ end
100
+
101
+ var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
102
+ vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
103
+
104
+ vm.context.target_class.create_shared_method(var_name, InstanceVarSpec, [])
105
+ }
106
+
107
+ #The procedure used for dot colon instance vals
108
+ DC_VAL = lambda {|vm|
109
+ val_name = vm.parser.get_word()
110
+
111
+ unless /^@[a-z][a-z0-9_]*$/ =~ val_name
112
+ error "F10: Invalid val name #{val_name}"
113
+ end
114
+
115
+ val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
116
+ vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
117
+
118
+ vm.context.target_class.create_shared_method(val_name, InstanceVarSpec, [])
119
+ }
120
+
121
+ # Add locals specific to a dot colon methods.
122
+ def self.add_dot_colon_locals(context)
123
+ context.create_local_method('var@:', LocalSpec, [:immediate], &DC_VAR)
124
+ context.create_local_method('val@:', LocalSpec, [:immediate], &DC_VAL)
125
+ end
126
+
127
+
128
+ # DOT COLON COLON =============================
129
+
130
+ # [an_object] .:: <name> <stuff omitted> ; []; creates <name> on an_object
131
+ VirtualMachine.create_shared_method('.::', VmSpec, [:immediate], &lambda {|vm|
132
+ if execute_mode?
133
+ target = vm.pop
134
+ name = vm.parser.get_word()
135
+ type = XfOOrth.name_to_type(name, self)
136
+ XfOOrth.validate_type(vm, type, name)
137
+ XfOOrth.validate_string_method(type, target.class, name)
138
+
139
+ begin_compile_mode('.::', obj: target, &lambda {|vm, src, tags|
140
+ vm.dbg_puts "#{target.foorth_name} #{name} => #{src}"
141
+ target.create_exclusive_method(name, type, tags, &eval(src))
142
+ })
143
+
144
+ XfOOrth.add_common_compiler_locals(vm, '.::')
145
+ XfOOrth.add_dot_colon_colon_locals(vm.context)
146
+ else
147
+ delayed_compile_mode('.::')
148
+ end
149
+ })
150
+
151
+ #The procedure used for dot colon colon instance vars
152
+ DCC_VAR = lambda { |vm|
153
+ var_name = vm.parser.get_word()
154
+
155
+ unless /^@[a-z][a-z0-9_]*$/ =~ var_name
156
+ error "F10: Invalid var name #{var_name}"
157
+ end
158
+
159
+ var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
160
+ vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
161
+
162
+ vm.context.target_object.create_exclusive_method(var_name, InstanceVarSpec, [])
163
+ }
164
+
165
+ #The procedure used for dot colon colon instance vals
166
+ DCC_VAL = lambda {|vm|
167
+ val_name = vm.parser.get_word()
168
+
169
+ unless /^@[a-z][a-z0-9_]*$/ =~ val_name
170
+ error "F10: Invalid val name #{val_name}"
171
+ end
172
+
173
+ val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
174
+ vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
175
+
176
+ vm.context.target_object.create_exclusive_method(val_name, InstanceVarSpec, [])
177
+ }
178
+
179
+ # Add locals specific to a dot colon colon methods.
180
+ def self.add_dot_colon_colon_locals(context)
181
+ context.create_local_method('var@:', LocalSpec, [:immediate], &DCC_VAR)
182
+ context.create_local_method('val@:', LocalSpec, [:immediate], &DCC_VAL)
183
+ end
184
+
185
+ # COMMON LOCAL DEFNS ==========================
186
+
187
+ #Set up the common local defns.
188
+ #<br>Parameters:
189
+ #* vm - The current virtual machine instance.
190
+ #* ctrl - A list of valid start controls.
191
+ #<br>Endemic Code Smells
192
+ #* :reek:TooManyStatements
193
+ def self.add_common_compiler_locals(vm, ctrl)
194
+ context = vm.context
195
+
196
+ #Support for local data.
197
+ context.create_local_method('var:', LocalSpec, [:immediate], &Local_Var_Action)
198
+ context.create_local_method('val:', LocalSpec, [:immediate], &Local_Val_Action)
199
+
200
+ #Support for super methods.
201
+ context.create_local_method('super', LocalSpec, [:immediate],
202
+ &lambda {|vm| vm << 'super(vm); ' })
203
+
204
+ #The standard end-compile adapter word: ';' semi-colon.
205
+ context.create_local_method(';', LocalSpec, [:immediate], &lambda {|vm|
206
+ vm.clear_cast
207
+ vm.end_compile_mode([ctrl])
208
+ })
209
+ end
210
+
211
+ #Determine the type of method being created. This only applies to non-vm
212
+ #methods as vm methods are all of type VmSpec.
213
+ #<br>Parameters
214
+ #*name - The name of the method to be created.
215
+ #<Returns>
216
+ #* The class of the spec to be used for this method.
217
+ def self.name_to_type(name, vm)
218
+ normal_spec = case name[0]
219
+ when '.'
220
+ TosSpec
221
+
222
+ when '~'
223
+ SelfSpec
224
+
225
+ when /[0-9A-Z$@#]/
226
+ error "F10: Invalid name for a method: #{name}"
227
+
228
+ else
229
+ NosSpec
230
+ end
231
+
232
+ vm.get_cast || normal_spec
233
+ end
234
+
235
+ #Compare the new method's spec against the specs of other methods of the
236
+ #same name. If no specs exist, create one on Object if the new spec is not
237
+ #a virtual machine spec.
238
+ #<br>Parameters
239
+ #*vm - The current virtual machine.
240
+ #*type - The class of the method to be created.
241
+ #*name - The name of the method to be created.
242
+ def self.validate_type(vm, type, name)
243
+ if (spec = vm.context.map_without_defaults(name))
244
+ if spec.class != type
245
+ error "F90: Spec type mismatch #{spec.foorth_name} vs #{type.foorth_name}"
246
+ end
247
+ else
248
+ Object.create_shared_method(name, type, [:stub]) unless type == VmSpec
249
+ end
250
+
251
+ end
252
+
253
+ #Check for the case where a string method is created on another class.
254
+ #<br>Parameters
255
+ #*type - The class of the method to be created.
256
+ #*target - The object that is to receive this method.
257
+ #*name - The name of the method to be created.
258
+ #<br>Endemic Code Smells
259
+ #* :reek:ControlParameter -- false positive
260
+ def self.validate_string_method(type, target, name)
261
+ if type == TosSpec && name[-1] == '"' && target != String
262
+ error "F13: Creating a string method #{name} on a #{target.foorth_name}"
263
+ end
264
+ end
265
+
266
+ end