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.
- checksums.yaml +5 -5
- data/CODE_OF_CONDUCT.md +49 -0
- data/README.md +32 -1
- data/fOOrth.gemspec +3 -3
- data/integration/array_lib_tests.rb +10 -0
- data/integration/compile_lib_tests.rb +67 -1
- data/integration/exception_lib_tests.rb +4 -0
- data/integration/hash_lib_tests.rb +9 -0
- data/integration/numeric_lib_tests.rb +326 -321
- data/integration/procedure_lib_tests.rb +16 -0
- data/integration/queue_lib_tests.rb +2 -1
- data/integration/stack_lib_tests.rb +2 -1
- data/integration/stdio_lib_tests.rb +62 -0
- data/integration/string_lib_tests.rb +11 -0
- data/integration/thread_lib_tests.rb +19 -5
- data/lib/fOOrth.rb +0 -2
- data/lib/fOOrth/compiler/context.rb +64 -64
- data/lib/fOOrth/compiler/context/locals.rb +34 -34
- data/lib/fOOrth/compiler/context/map_name.rb +85 -74
- data/lib/fOOrth/compiler/context/tags.rb +60 -48
- data/lib/fOOrth/compiler/process/generate.rb +1 -1
- data/lib/fOOrth/compiler/process/procedure.rb +40 -0
- data/lib/fOOrth/compiler/word_specs.rb +3 -3
- data/lib/fOOrth/core/object.rb +1 -1
- data/lib/fOOrth/library.rb +3 -0
- data/lib/fOOrth/library/alias_library.rb +126 -0
- data/lib/fOOrth/library/array_library.rb +41 -21
- data/lib/fOOrth/library/command_library.rb +1 -1
- data/lib/fOOrth/library/compile_library.rb +266 -264
- data/lib/fOOrth/library/complex_library.rb +82 -80
- data/lib/fOOrth/library/float_library.rb +37 -0
- data/lib/fOOrth/library/formatting/array.rb +90 -0
- data/lib/fOOrth/library/formatting/bullets.rb +15 -79
- data/lib/fOOrth/library/formatting/columns.rb +20 -42
- data/lib/fOOrth/library/formatting/hash.rb +29 -0
- data/lib/fOOrth/library/formatting/nil.rb +13 -0
- data/lib/fOOrth/library/formatting/object.rb +18 -0
- data/lib/fOOrth/library/formatting/string.rb +46 -0
- data/lib/fOOrth/library/hash_library.rb +14 -6
- data/lib/fOOrth/library/introspection/class.rb +20 -18
- data/lib/fOOrth/library/introspection/context.rb +3 -2
- data/lib/fOOrth/library/introspection/object.rb +42 -20
- data/lib/fOOrth/library/introspection/string.rb +21 -5
- data/lib/fOOrth/library/introspection/vm.rb +17 -29
- data/lib/fOOrth/library/mutex_library.rb +8 -1
- data/lib/fOOrth/library/numeric_library.rb +359 -380
- data/lib/fOOrth/library/procedure_library.rb +69 -65
- data/lib/fOOrth/library/queue_library.rb +6 -1
- data/lib/fOOrth/library/rational_library.rb +89 -89
- data/lib/fOOrth/library/stack_library.rb +6 -1
- data/lib/fOOrth/library/stdio_library.rb +11 -8
- data/lib/fOOrth/library/string_library.rb +21 -6
- data/lib/fOOrth/library/stubs_library.rb +49 -0
- data/lib/fOOrth/monkey_patch/exceptions.rb +2 -6
- data/lib/fOOrth/monkey_patch/object.rb +7 -0
- data/lib/fOOrth/version.rb +1 -1
- data/reek.txt +1 -59
- data/sire.rb +0 -1
- data/tests/compiler/context_tests.rb +188 -177
- data/tests/compiler/file_source_tests.rb +130 -130
- data/tests/compiler/parser_tests.rb +4 -4
- data/tests/compiler/string_source_tests.rb +4 -4
- data/tests/core_tests.rb +138 -138
- data/tests/monkey_patch/complex_test.rb +24 -24
- data/tests/monkey_patch/object_test.rb +49 -49
- data/tests/monkey_patch/string_test.rb +61 -61
- 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,
|
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,
|
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
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
#<
|
214
|
-
#* The
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
#
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
#*
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
#*
|
256
|
-
|
257
|
-
#*
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
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
|