fOOrth 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|