fOOrth 0.6.3 → 0.6.4
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 +4 -4
- data/fOOrth.gemspec +0 -1
- data/integration/data_ref_lib_tests.rb +47 -0
- data/lib/fOOrth/compiler/context.rb +18 -3
- data/lib/fOOrth/compiler/context/map_name.rb +13 -12
- data/lib/fOOrth/compiler/modes.rb +1 -1
- data/lib/fOOrth/compiler/parser/skip.rb +2 -0
- data/lib/fOOrth/compiler/process.rb +1 -1
- data/lib/fOOrth/compiler/process/string.rb +6 -4
- data/lib/fOOrth/compiler/source.rb +1 -1
- data/lib/fOOrth/compiler/source/console.rb +1 -1
- data/lib/fOOrth/compiler/token.rb +14 -1
- data/lib/fOOrth/compiler/word_specs.rb +11 -8
- data/lib/fOOrth/core/class.rb +5 -0
- data/lib/fOOrth/core/object.rb +8 -4
- data/lib/fOOrth/core/virtual_machine.rb +1 -1
- data/lib/fOOrth/library/class_library.rb +1 -1
- data/lib/fOOrth/library/compile_library.rb +69 -6
- data/lib/fOOrth/library/ctrl_struct_library.rb +11 -11
- data/lib/fOOrth/library/data_ref_library.rb +0 -24
- data/lib/fOOrth/library/stubs.rb +12 -12
- data/lib/fOOrth/monkey_patch/exceptions.rb +2 -2
- data/lib/fOOrth/monkey_patch/object.rb +1 -1
- data/lib/fOOrth/version.rb +1 -1
- data/tests/compiler/context_tests.rb +7 -10
- data/tests/compiler/spec_tests.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cde7de9c337c4b22e08296e3b2a6fb2b57e5a112
|
4
|
+
data.tar.gz: 6a3280aae89e3ac08f58de51411d9a73a2b321b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eedf9eb80534ec2e6057857b81c641c0059252604b28466d423e281125a0722877e70cd9a143396fdcf0b1fc512189327cc0906eaa382b8ff82313b4015c548d
|
7
|
+
data.tar.gz: e21563be0a8a01a0949beed1b97da9250ce0dce5a60e87d8bef76a542b4552c8ef65ec92cd691e88f516c4a532667083d8a91d0febc1ecaa041b6369c4de1548
|
data/fOOrth.gemspec
CHANGED
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
|
|
18
18
|
entry.start_with?("images") }
|
19
19
|
|
20
20
|
spec.files = raw_list
|
21
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
21
|
spec.test_files = spec.files.grep(%r{^(tests|integration)/})
|
23
22
|
spec.require_paths = ["lib"]
|
24
23
|
spec.executables = ["fOOrth"]
|
@@ -40,4 +40,51 @@ class DataRefLibraryTester < Minitest::Test
|
|
40
40
|
foorth_equal('10 val$: $test2', [])
|
41
41
|
foorth_equal('$test2', [10])
|
42
42
|
end
|
43
|
+
|
44
|
+
def test_shared_instance_variables
|
45
|
+
foorth_run('class: TIV01')
|
46
|
+
foorth_run('TIV01 .: .init val@: @dder 0 var@: @counter ;')
|
47
|
+
foorth_run('TIV01 .: .add @dder + ;')
|
48
|
+
foorth_run('TIV01 .: .count @counter @ 1+ dup @counter ! ;')
|
49
|
+
|
50
|
+
foorth_run('11 TIV01 .new val$: $tiv01_01')
|
51
|
+
foorth_equal('$tiv01_01 .class .name', ['TIV01'])
|
52
|
+
foorth_equal('20 $tiv01_01 .add', [31])
|
53
|
+
foorth_equal('$tiv01_01 .count', [1])
|
54
|
+
foorth_equal('$tiv01_01 .count', [2])
|
55
|
+
foorth_equal('$tiv01_01 .count', [3])
|
56
|
+
|
57
|
+
foorth_run('42 TIV01 .new val$: $tiv01_02')
|
58
|
+
foorth_equal('$tiv01_02 .class .name', ['TIV01'])
|
59
|
+
foorth_equal('20 $tiv01_02 .add', [62])
|
60
|
+
foorth_equal('$tiv01_02 .count', [1])
|
61
|
+
foorth_equal('$tiv01_02 .count', [2])
|
62
|
+
foorth_equal('$tiv01_02 .count', [3])
|
63
|
+
|
64
|
+
foorth_equal('$tiv01_01 .count', [4])
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_exclusive_instance_variables
|
68
|
+
foorth_run('Object .new val$: $tiv02_01')
|
69
|
+
foorth_run('$tiv02_01 .:: .init val@: @dder 0 var@: @counter ;')
|
70
|
+
foorth_run('$tiv02_01 .:: .add @dder + ;')
|
71
|
+
foorth_run('$tiv02_01 .:: .count @counter @ 1+ dup @counter ! ;')
|
72
|
+
|
73
|
+
foorth_run('11 $tiv02_01 .init ')
|
74
|
+
foorth_equal('20 $tiv02_01 .add', [31])
|
75
|
+
foorth_equal('$tiv02_01 .count', [1])
|
76
|
+
foorth_equal('$tiv02_01 .count', [2])
|
77
|
+
foorth_equal('$tiv02_01 .count', [3])
|
78
|
+
|
79
|
+
foorth_run('$tiv02_01 .clone val$: $tiv02_02')
|
80
|
+
foorth_run('42 $tiv02_02 .init ')
|
81
|
+
foorth_equal('20 $tiv02_02 .add', [62])
|
82
|
+
foorth_equal('$tiv02_02 .count', [1])
|
83
|
+
foorth_equal('$tiv02_02 .count', [2])
|
84
|
+
foorth_equal('$tiv02_02 .count', [3])
|
85
|
+
|
86
|
+
foorth_equal('20 $tiv02_01 .add', [31])
|
87
|
+
foorth_equal('$tiv02_01 .count', [4])
|
88
|
+
end
|
89
|
+
|
43
90
|
end
|
@@ -40,10 +40,25 @@ module XfOOrth
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
#Get the
|
44
|
-
def
|
45
|
-
self[:obj] || self[:cls] || self[:vm] ||
|
43
|
+
#Get the current target.
|
44
|
+
def target
|
45
|
+
self[:obj] || self[:cls] || self[:vm] || no_target_error
|
46
46
|
end
|
47
47
|
|
48
|
+
#Get the current target object.
|
49
|
+
def target_object
|
50
|
+
self[:obj] || no_target_error
|
51
|
+
end
|
52
|
+
|
53
|
+
#Get the current target class.
|
54
|
+
def target_class
|
55
|
+
self[:cls] || no_target_error
|
56
|
+
end
|
57
|
+
|
58
|
+
#Signal that no receiver was found in this context.
|
59
|
+
#This is an internal error indication.
|
60
|
+
def no_target_error
|
61
|
+
error("F90: No target found in context.")
|
62
|
+
end
|
48
63
|
end
|
49
64
|
end
|
@@ -26,32 +26,33 @@ module XfOOrth
|
|
26
26
|
case @name[0]
|
27
27
|
when '.'
|
28
28
|
do_object_class_map ||
|
29
|
-
|
29
|
+
do_target_vm_map ||
|
30
30
|
TosSpec.new(@name, @symbol, [:temp])
|
31
31
|
|
32
32
|
when '~'
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
do_target_class_map ||
|
34
|
+
do_target_object_map ||
|
35
|
+
do_target_vm_map ||
|
36
36
|
SelfSpec.new(@name, @symbol, [:temp])
|
37
37
|
|
38
38
|
when '@'
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
do_target_class_map ||
|
40
|
+
do_target_object_map ||
|
41
|
+
do_target_vm_map ||
|
42
42
|
spec_error
|
43
43
|
|
44
44
|
when '$'
|
45
45
|
do_global_target_map ||
|
46
|
+
do_target_vm_map ||
|
46
47
|
spec_error
|
47
48
|
|
48
49
|
when '#'
|
49
|
-
|
50
|
+
do_target_vm_map ||
|
50
51
|
spec_error
|
51
52
|
|
52
53
|
else
|
53
54
|
do_object_class_map ||
|
54
|
-
|
55
|
+
do_target_vm_map ||
|
55
56
|
do_global_target_map ||
|
56
57
|
spec_error
|
57
58
|
end
|
@@ -64,17 +65,17 @@ module XfOOrth
|
|
64
65
|
end
|
65
66
|
|
66
67
|
#Do a search of the :cls tag if it is specified.
|
67
|
-
def
|
68
|
+
def do_target_class_map
|
68
69
|
(tc = self[:cls]) && tc.map_foorth_shared(@symbol)
|
69
70
|
end
|
70
71
|
|
71
72
|
#Do a search of the :obj tag if it is specified.
|
72
|
-
def
|
73
|
+
def do_target_object_map
|
73
74
|
(to = self[:obj]) && to.map_foorth_exclusive(@symbol)
|
74
75
|
end
|
75
76
|
|
76
77
|
#Do a search of the :vm tag if it is specified.
|
77
|
-
def
|
78
|
+
def do_target_vm_map
|
78
79
|
(vm = self[:vm]) && vm.map_foorth_exclusive(@symbol)
|
79
80
|
end
|
80
81
|
|
@@ -17,7 +17,7 @@ module XfOOrth
|
|
17
17
|
def process_text(text)
|
18
18
|
if execute_mode?
|
19
19
|
dbg_puts " Code=#{text.inspect}"
|
20
|
-
@context.
|
20
|
+
@context.target.instance_exec(self, &eval("lambda {|vm| #{text} }"))
|
21
21
|
else
|
22
22
|
self << text
|
23
23
|
end
|
@@ -36,7 +36,7 @@ module XfOOrth
|
|
36
36
|
code = token.code
|
37
37
|
|
38
38
|
if execute_mode? || ((token.has_tag?(:immediate)) && (!@force))
|
39
|
-
@context.
|
39
|
+
@context.target.instance_exec(self, &eval("lambda {|vm| #{code} }"))
|
40
40
|
else
|
41
41
|
@buffer << code
|
42
42
|
@force = false
|
@@ -11,14 +11,16 @@ module XfOOrth
|
|
11
11
|
#* token - The token to receive the generated code.
|
12
12
|
#* word - The text of the word.
|
13
13
|
def string_parms(token, word)
|
14
|
+
source = parser.source
|
15
|
+
|
14
16
|
if word.end_with?('"')
|
15
17
|
string_value = parser.get_string.foorth_embed
|
16
18
|
|
17
|
-
if
|
18
|
-
|
19
|
-
token.add("vm.push(StringBuffer.new(#{string_value})); ")
|
19
|
+
if source.peek == '*'
|
20
|
+
source.get
|
21
|
+
token.add("vm.push(StringBuffer.new(#{string_value})); ", [:string])
|
20
22
|
else
|
21
|
-
token.add("vm.push(#{string_value}.freeze); ")
|
23
|
+
token.add("vm.push(#{string_value}.freeze); ", [:string])
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -16,13 +16,26 @@ module XfOOrth
|
|
16
16
|
end
|
17
17
|
|
18
18
|
#Append some text/tags to the code_fragment.
|
19
|
+
#<br>Parameters
|
20
|
+
#* text - A string of code to be appended to this token.
|
21
|
+
#* tags - An optional array of tags to be added to this token.
|
22
|
+
#<br>Possible tag values:
|
23
|
+
#* :class - This token contains a class constant..
|
24
|
+
#* :immediate - The token is executed, even in compile modes.
|
25
|
+
#* :macro - This token contains an in-line macro.
|
26
|
+
#* :numeric - This token contains a numeric literal.
|
27
|
+
#* :procedure - This token contains a procedure literal.
|
28
|
+
#* :string - This token contains a string literal.
|
29
|
+
#* :stub - This token contains a stub spec.
|
30
|
+
#* :temp - This token contains code from a temporary spec.
|
31
|
+
#* none - Nothing special here. Move along, move along.
|
19
32
|
def add(text, tags=nil)
|
20
33
|
@code << text
|
21
34
|
@tags.concat(tags).uniq! if tags
|
22
35
|
self
|
23
36
|
end
|
24
37
|
|
25
|
-
#Does this token have the specified tag?
|
38
|
+
#Does this token have the specified tag value?
|
26
39
|
def has_tag?(value)
|
27
40
|
@tags.include?(value)
|
28
41
|
end
|
@@ -21,13 +21,16 @@ module XfOOrth
|
|
21
21
|
#* name - The string that maps to the symbol.
|
22
22
|
#* symbol - The symbol that the name maps to.
|
23
23
|
#* tags - A an array of tags.
|
24
|
-
#<br>These
|
24
|
+
#<br>These include:
|
25
|
+
#* :class - This spec defines a class.
|
25
26
|
#* :immediate - The word is executed, even in compile modes.
|
26
|
-
#* :macro -
|
27
|
+
#* :macro - This spec defines an in-line macro.
|
27
28
|
#* :stub - The word is a place holder in the hierarchy.
|
29
|
+
#* :temp - A temporary spec used during compilation.
|
30
|
+
#* none - Nothing special here. Move along, move along.
|
28
31
|
#<br>Endemic Code Smells
|
29
32
|
#* :reek:ControlParameter -- false positive
|
30
|
-
def initialize(name, symbol, tags
|
33
|
+
def initialize(name, symbol, tags, &block)
|
31
34
|
@tags = tags
|
32
35
|
@does = block || get_stub_action(name, symbol)
|
33
36
|
build_builds_string(name, symbol)
|
@@ -40,7 +43,7 @@ module XfOOrth
|
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
|
-
#Look up
|
46
|
+
#Look up a tag of interest.
|
44
47
|
def has_tag?(tag)
|
45
48
|
@tags.include?(tag)
|
46
49
|
end
|
@@ -93,8 +96,8 @@ module XfOOrth
|
|
93
96
|
#Get the default action if none is specified.
|
94
97
|
def get_stub_action(name, symbol)
|
95
98
|
lambda do |vm|
|
96
|
-
#NOS methods
|
97
|
-
#be
|
99
|
+
#NOS methods leave an extra item on the stack which must
|
100
|
+
#be removed at this time.
|
98
101
|
vm.data_stack.pop
|
99
102
|
|
100
103
|
error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol.inspect})."
|
@@ -107,7 +110,7 @@ module XfOOrth
|
|
107
110
|
class ClassSpec < AbstractWordSpec
|
108
111
|
#Generate the Ruby code for this fOOrth class.
|
109
112
|
#<br>Parameters:
|
110
|
-
#* \new_class - The
|
113
|
+
#* \new_class - The class object being specified.
|
111
114
|
#* _symbol - The symbol that the name maps to. Unused
|
112
115
|
def build_builds_string(new_class, _symbol)
|
113
116
|
@new_class = new_class
|
@@ -158,7 +161,7 @@ module XfOOrth
|
|
158
161
|
#* _name - The string that maps to the symbol. Unused
|
159
162
|
#* symbol - The symbol that the name maps to.
|
160
163
|
def build_builds_string(_name, symbol)
|
161
|
-
@builds = "vm.context[#{symbol.inspect}].does
|
164
|
+
@builds = "instance_exec(vm, &vm.context[#{symbol.inspect}].does); "
|
162
165
|
end
|
163
166
|
end
|
164
167
|
|
data/lib/fOOrth/core/class.rb
CHANGED
@@ -10,6 +10,11 @@ class Class
|
|
10
10
|
@_private_foorth_name ||= name.freeze
|
11
11
|
end
|
12
12
|
|
13
|
+
#Get the name of the class or a safe default.
|
14
|
+
def foorth_class_name
|
15
|
+
self.foorth_name || "AnonymousClass<#{self.object_id}>".freeze
|
16
|
+
end
|
17
|
+
|
13
18
|
#Set the foorth name of this class.
|
14
19
|
#<br>Decree!
|
15
20
|
#* These are to be the only references to @_private_foorth_name!
|
data/lib/fOOrth/core/object.rb
CHANGED
@@ -5,19 +5,21 @@ class Object
|
|
5
5
|
|
6
6
|
#Get the foorth name of this object.
|
7
7
|
def foorth_name
|
8
|
-
"#{self.class.foorth_name} instance"
|
8
|
+
"#{self.class.foorth_name} instance".freeze
|
9
9
|
end
|
10
10
|
|
11
11
|
#Access/create the object's exclusive fOOrth dictionary.
|
12
12
|
#<br>Decree!
|
13
|
-
#*
|
13
|
+
#* This method and the next are to be the only references
|
14
|
+
# to the @_private_foorth_exclusive variable.
|
14
15
|
def foorth_exclusive
|
15
16
|
@_private_foorth_exclusive ||= Hash.new
|
16
17
|
end
|
17
18
|
|
18
19
|
#Does this object have exclusive methods defined on it?
|
19
20
|
#<br>Decree!
|
20
|
-
#*
|
21
|
+
#* This method and the previous are to be the only references
|
22
|
+
# to the @_private_foorth_exclusive variable.
|
21
23
|
def foorth_has_exclusive?
|
22
24
|
instance_variable_defined?(:@_private_foorth_exclusive)
|
23
25
|
end
|
@@ -58,7 +60,9 @@ class Object
|
|
58
60
|
#* block - Any block that might have passed to the method.
|
59
61
|
#<br>Note:
|
60
62
|
#* Since stubs for Object class do not create methods, an attempt is made
|
61
|
-
# to execute the stub if the symbol maps and is in the Object class.
|
63
|
+
# to execute the stub if the symbol maps and is in the Object class. This
|
64
|
+
# ensures that the case specific stub code is used rather than the generic
|
65
|
+
# code in this method.
|
62
66
|
def method_missing(symbol, *args, &block)
|
63
67
|
if (name = XfOOrth::SymbolMap.unmap(symbol))
|
64
68
|
if (stub_spec = Object.foorth_shared[symbol])
|
@@ -19,7 +19,7 @@ module XfOOrth
|
|
19
19
|
#Create a new fOOrth subclass of this class. This is not allowed for the
|
20
20
|
#VirtualMachine class so this stub merely raises an exception.
|
21
21
|
def create_foorth_subclass(_name)
|
22
|
-
error "F13: Forbidden operation:
|
22
|
+
error "F13: Forbidden operation: VirtualMachine .class: "
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
@@ -11,7 +11,7 @@ module XfOOrth
|
|
11
11
|
#Get the class as a string.
|
12
12
|
# [cls] .to_s ["cls as a string"]
|
13
13
|
Class.create_shared_method('.to_s', TosSpec, [], &lambda {|vm|
|
14
|
-
vm.push(self.
|
14
|
+
vm.push(self.foorth_class_name)
|
15
15
|
})
|
16
16
|
|
17
17
|
#The .parent_class method. Retrieves the parent class of a class.
|
@@ -68,11 +68,46 @@ module XfOOrth
|
|
68
68
|
})
|
69
69
|
|
70
70
|
XfOOrth.add_common_compiler_locals(vm, '.:')
|
71
|
+
XfOOrth.add_dot_colon_locals(vm.context)
|
71
72
|
else
|
72
73
|
delayed_compile_mode('.:')
|
73
74
|
end
|
74
75
|
})
|
75
76
|
|
77
|
+
#The procedure used for dot colon instance vars
|
78
|
+
DC_VAR = lambda {|vm|
|
79
|
+
var_name = vm.parser.get_word()
|
80
|
+
|
81
|
+
unless /^@[a-z][a-z0-9_]*$/ =~ var_name
|
82
|
+
error "F10: Invalid var name #{var_name}"
|
83
|
+
end
|
84
|
+
|
85
|
+
var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
|
86
|
+
vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
|
87
|
+
|
88
|
+
vm.context.target_class.create_shared_method(var_name, InstanceVarSpec, [])
|
89
|
+
}
|
90
|
+
|
91
|
+
#The procedure used for dot colon instance vals
|
92
|
+
DC_VAL = lambda {|vm|
|
93
|
+
val_name = vm.parser.get_word()
|
94
|
+
|
95
|
+
unless /^@[a-z][a-z0-9_]*$/ =~ val_name
|
96
|
+
error "F10: Invalid val name #{val_name}"
|
97
|
+
end
|
98
|
+
|
99
|
+
val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
|
100
|
+
vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
|
101
|
+
|
102
|
+
vm.context.target_class.create_shared_method(val_name, InstanceVarSpec, [])
|
103
|
+
}
|
104
|
+
|
105
|
+
# Add locals specific to a dot colon methods.
|
106
|
+
def self.add_dot_colon_locals(context)
|
107
|
+
context.create_local_method('var@:', LocalSpec, [:immediate], &DC_VAR)
|
108
|
+
context.create_local_method('val@:', LocalSpec, [:immediate], &DC_VAL)
|
109
|
+
end
|
110
|
+
|
76
111
|
|
77
112
|
# DOT COLON COLON =============================
|
78
113
|
|
@@ -91,11 +126,45 @@ module XfOOrth
|
|
91
126
|
})
|
92
127
|
|
93
128
|
XfOOrth.add_common_compiler_locals(vm, '.::')
|
129
|
+
XfOOrth.add_dot_colon_colon_locals(vm.context)
|
94
130
|
else
|
95
131
|
delayed_compile_mode('.::')
|
96
132
|
end
|
97
133
|
})
|
98
134
|
|
135
|
+
#The procedure used for dot colon colon instance vars
|
136
|
+
DCC_VAR = lambda { |vm|
|
137
|
+
var_name = vm.parser.get_word()
|
138
|
+
|
139
|
+
unless /^@[a-z][a-z0-9_]*$/ =~ var_name
|
140
|
+
error "F10: Invalid var name #{var_name}"
|
141
|
+
end
|
142
|
+
|
143
|
+
var_symbol = XfOOrth::SymbolMap.add_entry(var_name)
|
144
|
+
vm << "#{'@'+(var_symbol.to_s)} = [vm.pop]; "
|
145
|
+
|
146
|
+
vm.context.target_object.create_exclusive_method(var_name, InstanceVarSpec, [])
|
147
|
+
}
|
148
|
+
|
149
|
+
#The procedure used for dot colon colon instance vals
|
150
|
+
DCC_VAL = lambda {|vm|
|
151
|
+
val_name = vm.parser.get_word()
|
152
|
+
|
153
|
+
unless /^@[a-z][a-z0-9_]*$/ =~ val_name
|
154
|
+
error "F10: Invalid val name #{val_name}"
|
155
|
+
end
|
156
|
+
|
157
|
+
val_symbol = XfOOrth::SymbolMap.add_entry(val_name)
|
158
|
+
vm << "#{'@'+(val_symbol.to_s)} = vm.pop; "
|
159
|
+
|
160
|
+
vm.context.target_object.create_exclusive_method(val_name, InstanceVarSpec, [])
|
161
|
+
}
|
162
|
+
|
163
|
+
# Add locals specific to a dot colon colon methods.
|
164
|
+
def self.add_dot_colon_colon_locals(context)
|
165
|
+
context.create_local_method('var@:', LocalSpec, [:immediate], &DCC_VAR)
|
166
|
+
context.create_local_method('val@:', LocalSpec, [:immediate], &DCC_VAL)
|
167
|
+
end
|
99
168
|
|
100
169
|
# COMMON LOCAL DEFNS ==========================
|
101
170
|
|
@@ -103,8 +172,6 @@ module XfOOrth
|
|
103
172
|
#<br>Parameters:
|
104
173
|
#* vm - The current virtual machine instance.
|
105
174
|
#* ctrl - A list of valid start controls.
|
106
|
-
#<br>Endemic Code Smells
|
107
|
-
#* :reek:TooManyStatements
|
108
175
|
def self.add_common_compiler_locals(vm, ctrl)
|
109
176
|
context = vm.context
|
110
177
|
|
@@ -112,10 +179,6 @@ module XfOOrth
|
|
112
179
|
context.create_local_method('var:', LocalSpec, [:immediate], &Local_Var_Action)
|
113
180
|
context.create_local_method('val:', LocalSpec, [:immediate], &Local_Val_Action)
|
114
181
|
|
115
|
-
#Support for instance data.
|
116
|
-
context.create_local_method('var@:', LocalSpec, [:immediate], &Inst_Var_Action)
|
117
|
-
context.create_local_method('val@:', LocalSpec, [:immediate], &Inst_Val_Action)
|
118
|
-
|
119
182
|
#Support for super methods.
|
120
183
|
context.create_local_method('super', LocalSpec, [:immediate],
|
121
184
|
&lambda {|vm| vm << 'super(vm); ' })
|
@@ -8,12 +8,12 @@ module XfOOrth
|
|
8
8
|
suspend_execute_mode('if vm.pop? then ', :if)
|
9
9
|
|
10
10
|
context.create_local_method('else', LocalSpec, [:immediate], &lambda {|vm|
|
11
|
-
check_deferred_mode('else ', [:if])
|
11
|
+
vm.check_deferred_mode('else ', [:if])
|
12
12
|
vm.context.remove_local_method('else')
|
13
13
|
})
|
14
14
|
|
15
15
|
context.create_local_method('then', LocalSpec, [:immediate],
|
16
|
-
&lambda {|vm| resume_execute_mode('end; ', [:if]) })
|
16
|
+
&lambda {|vm| vm.resume_execute_mode('end; ', [:if]) })
|
17
17
|
})
|
18
18
|
|
19
19
|
# [unspecified] switch ... end [unspecified]
|
@@ -27,7 +27,7 @@ module XfOOrth
|
|
27
27
|
&lambda {|vm| vm << 'break if vm.pop?; ' })
|
28
28
|
|
29
29
|
context.create_local_method('end', LocalSpec, [:immediate],
|
30
|
-
&lambda {|vm| resume_execute_mode('break; end; ', [:switch]) })
|
30
|
+
&lambda {|vm| vm.resume_execute_mode('break; end; ', [:switch]) })
|
31
31
|
})
|
32
32
|
|
33
33
|
# Looping constructs for fOOrth.
|
@@ -35,16 +35,16 @@ module XfOOrth
|
|
35
35
|
suspend_execute_mode('begin ', :begin)
|
36
36
|
|
37
37
|
context.create_local_method('while', LocalSpec, [:immediate],
|
38
|
-
&lambda {|vm| check_deferred_mode('break unless vm.pop?; ', [:begin]) })
|
38
|
+
&lambda {|vm| vm.check_deferred_mode('break unless vm.pop?; ', [:begin]) })
|
39
39
|
|
40
40
|
context.create_local_method('until', LocalSpec, [:immediate],
|
41
|
-
&lambda {|vm| resume_execute_mode('end until vm.pop?; ', [:begin]) })
|
41
|
+
&lambda {|vm| vm.resume_execute_mode('end until vm.pop?; ', [:begin]) })
|
42
42
|
|
43
43
|
context.create_local_method('again', LocalSpec, [:immediate],
|
44
|
-
&lambda {|vm| resume_execute_mode('end until false; ', [:begin]) })
|
44
|
+
&lambda {|vm| vm.resume_execute_mode('end until false; ', [:begin]) })
|
45
45
|
|
46
46
|
context.create_local_method('repeat', LocalSpec, [:immediate],
|
47
|
-
&lambda {|vm| resume_execute_mode('end until false; ', [:begin]) })
|
47
|
+
&lambda {|vm| vm.resume_execute_mode('end until false; ', [:begin]) })
|
48
48
|
})
|
49
49
|
|
50
50
|
# Support for the sanitized do loop constructs!
|
@@ -66,10 +66,10 @@ module XfOOrth
|
|
66
66
|
[:macro, 'vm.push(jloop[2] - jloop[0]); '])
|
67
67
|
|
68
68
|
context.create_local_method('loop', LocalSpec, [:immediate],
|
69
|
-
&lambda {|vm| resume_execute_mode('iloop[0] += 1}; ', [:do]) })
|
69
|
+
&lambda {|vm| vm.resume_execute_mode('iloop[0] += 1}; ', [:do]) })
|
70
70
|
|
71
71
|
context.create_local_method('+loop', LocalSpec, [:immediate],
|
72
|
-
&lambda {|vm| resume_execute_mode('iloop[0] += vm.vm_do_increment}; ', [:do]) })
|
72
|
+
&lambda {|vm| vm.resume_execute_mode('iloop[0] += vm.vm_do_increment}; ', [:do]) })
|
73
73
|
})
|
74
74
|
|
75
75
|
#Support for the try ... catch ... finally ... end construct.
|
@@ -99,7 +99,7 @@ module XfOOrth
|
|
99
99
|
})
|
100
100
|
|
101
101
|
context.create_local_method('finally', LocalSpec, [:immediate], &lambda {|vm|
|
102
|
-
check_deferred_mode('ensure; ', [:try_block])
|
102
|
+
vm.check_deferred_mode('ensure; ', [:try_block])
|
103
103
|
|
104
104
|
vm.context.remove_local_method('catch')
|
105
105
|
vm.context.remove_local_method('finally')
|
@@ -118,7 +118,7 @@ module XfOOrth
|
|
118
118
|
suspend_buffered_mode('[[')
|
119
119
|
|
120
120
|
vm.context.create_local_method(']]', LocalSpec, [:immediate], &lambda {|vm|
|
121
|
-
resume_buffered_mode('[[')
|
121
|
+
vm.resume_buffered_mode('[[')
|
122
122
|
})
|
123
123
|
})
|
124
124
|
|
@@ -29,30 +29,6 @@ module XfOOrth
|
|
29
29
|
&lambda {|vm| vm << "vm.push(#{symbol}); "} )
|
30
30
|
}
|
31
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
32
|
# Thread Variables
|
57
33
|
# [n] var#: #tv [], Thread.current[#tv] = [n]
|
58
34
|
VirtualMachine.create_shared_method('var#:', VmSpec, [], &lambda {|vm|
|
data/lib/fOOrth/library/stubs.rb
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
module XfOOrth
|
5
5
|
|
6
6
|
# Some comparison words. See numeric_library.rb and string_library.rb
|
7
|
-
Object.create_shared_method('>',
|
8
|
-
Object.create_shared_method('<',
|
9
|
-
Object.create_shared_method('>=',
|
10
|
-
Object.create_shared_method('<=',
|
11
|
-
Object.create_shared_method('<=>',
|
7
|
+
Object.create_shared_method('>', NosSpec, [:stub])
|
8
|
+
Object.create_shared_method('<', NosSpec, [:stub])
|
9
|
+
Object.create_shared_method('>=', NosSpec, [:stub])
|
10
|
+
Object.create_shared_method('<=', NosSpec, [:stub])
|
11
|
+
Object.create_shared_method('<=>', NosSpec, [:stub])
|
12
12
|
|
13
13
|
# Some comparison with zero words. See numeric_library.rb
|
14
14
|
Object.create_shared_method('0=', TosSpec, [:stub])
|
@@ -48,10 +48,10 @@ module XfOOrth
|
|
48
48
|
Object.create_shared_method('@', TosSpec, [:stub])
|
49
49
|
Object.create_shared_method('!', TosSpec, [:stub])
|
50
50
|
|
51
|
-
Object.create_shared_method('parse',
|
52
|
-
Object.create_shared_method('parse!',
|
53
|
-
Object.create_shared_method('p"',
|
54
|
-
Object.create_shared_method('p!"',
|
51
|
+
Object.create_shared_method('parse', NosSpec, [:stub])
|
52
|
+
Object.create_shared_method('parse!', NosSpec, [:stub])
|
53
|
+
Object.create_shared_method('p"', NosSpec, [:stub])
|
54
|
+
Object.create_shared_method('p!"', NosSpec, [:stub])
|
55
55
|
|
56
56
|
#Procedure literal stubs.
|
57
57
|
Object.create_shared_method('.each{{', NosSpec, [:stub])
|
@@ -66,11 +66,11 @@ module XfOOrth
|
|
66
66
|
Object.create_shared_method('.new_default{{', NosSpec, [:stub])
|
67
67
|
|
68
68
|
#Embedding stubs.
|
69
|
-
Object.create_shared_method(',asm',
|
70
|
-
Object.create_shared_method(',asm"',
|
69
|
+
Object.create_shared_method(',asm', TosSpec, [:stub])
|
70
|
+
Object.create_shared_method(',asm"', TosSpec, [:stub])
|
71
71
|
|
72
72
|
#Define some "crossover" symbols.
|
73
|
-
SymbolMap.add_entry('.is_class?',
|
73
|
+
SymbolMap.add_entry('.is_class?', :foorth_is_class?)
|
74
74
|
SymbolMap.add_entry('.to_s', :to_foorth_s)
|
75
75
|
SymbolMap.add_entry('.strlen', :foorth_strlen)
|
76
76
|
SymbolMap.add_entry('.strmax', :foorth_strmax)
|
@@ -5,7 +5,7 @@ class Object
|
|
5
5
|
|
6
6
|
#Raise a fOOrth language internal exception as this operation is not allowed.
|
7
7
|
def foorth_embed
|
8
|
-
error "F40: Can't embed class #{self.class.
|
8
|
+
error "F40: Can't embed class #{self.class.foorth_class_name}"
|
9
9
|
end
|
10
10
|
|
11
11
|
#Convert this object to a fOOrth boolean.
|
data/lib/fOOrth/version.rb
CHANGED
@@ -107,7 +107,7 @@ class ContextTester < Minitest::Test
|
|
107
107
|
|
108
108
|
name = 'b'
|
109
109
|
sym = XfOOrth::SymbolMap.add_entry(name)
|
110
|
-
context[sym] = XfOOrth::VmSpec.new(name, sym)
|
110
|
+
context[sym] = XfOOrth::VmSpec.new(name, sym, [])
|
111
111
|
spec = context.map(name)
|
112
112
|
assert(spec.is_a?(XfOOrth::VmSpec))
|
113
113
|
end
|
@@ -118,7 +118,7 @@ class ContextTester < Minitest::Test
|
|
118
118
|
|
119
119
|
name = '.c'
|
120
120
|
sym = XfOOrth::SymbolMap.add_entry(name)
|
121
|
-
mk[sym] = XfOOrth::TosSpec.new(name, sym)
|
121
|
+
mk[sym] = XfOOrth::TosSpec.new(name, sym, [])
|
122
122
|
spec = context.map(name)
|
123
123
|
assert(spec.is_a?(XfOOrth::TosSpec))
|
124
124
|
end
|
@@ -129,7 +129,7 @@ class ContextTester < Minitest::Test
|
|
129
129
|
|
130
130
|
name = '.d'
|
131
131
|
sym = XfOOrth::SymbolMap.add_entry(name)
|
132
|
-
mk[sym] = XfOOrth::TosSpec.new(name, sym)
|
132
|
+
mk[sym] = XfOOrth::TosSpec.new(name, sym, [])
|
133
133
|
spec = context.map(name)
|
134
134
|
assert(spec.is_a?(XfOOrth::TosSpec))
|
135
135
|
end
|
@@ -148,19 +148,16 @@ class ContextTester < Minitest::Test
|
|
148
148
|
|
149
149
|
def test_the_locating_of_the_receiver
|
150
150
|
context = XfOOrth::Context.new(nil, vm: 'vm_sample')
|
151
|
-
assert_equal('vm_sample', context.
|
151
|
+
assert_equal('vm_sample', context.target)
|
152
152
|
|
153
153
|
context = XfOOrth::Context.new(context, cls: 'cls_sample')
|
154
|
-
assert_equal('cls_sample', context.
|
154
|
+
assert_equal('cls_sample', context.target)
|
155
155
|
|
156
156
|
context = XfOOrth::Context.new(context, obj: 'obj_sample')
|
157
|
-
assert_equal('obj_sample', context.
|
157
|
+
assert_equal('obj_sample', context.target)
|
158
158
|
|
159
159
|
context = XfOOrth::Context.new(nil)
|
160
|
-
|
161
|
-
assert_raises(XfOOrth::XfOOrthError) do
|
162
|
-
context.recvr
|
163
|
-
end
|
160
|
+
assert_raises(XfOOrth::XfOOrthError) { context.target }
|
164
161
|
end
|
165
162
|
|
166
163
|
def test_adding_and_removing_local_methods
|
@@ -95,7 +95,7 @@ class SpecTester < Minitest::Test
|
|
95
95
|
def test_local_spec
|
96
96
|
spec = XfOOrth::LocalSpec.new("fred", :freddy, [:foo])
|
97
97
|
|
98
|
-
assert_equal("vm.context[:freddy].does
|
98
|
+
assert_equal("instance_exec(vm, &vm.context[:freddy].does); ", spec.builds)
|
99
99
|
assert_instance_of(Proc, spec.does)
|
100
100
|
assert(spec.has_tag?(:foo))
|
101
101
|
refute(spec.has_tag?(:bar))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fOOrth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|