fOOrth 0.6.6 → 0.6.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b78d9f4016b73209d62eaf5c8d01497f64b65582
4
- data.tar.gz: 98ec2f26ae3bf20ea9a65d120ecb0d9bc6b2f88c
3
+ metadata.gz: 1374c4bba58032a13a910d7b284ef79fcb512837
4
+ data.tar.gz: 5c60e71d86f800551b0041c5f8afa4c75e8b87a8
5
5
  SHA512:
6
- metadata.gz: f04893f0850026b62865f1087298d8f8ad1a621da78d097a96106adcba71f00ba14abe1968992bcdda57ef14ed6a0bfc4969d9f3b291793b55618d0b7cad0e09
7
- data.tar.gz: 0f17fc2d2d9dd61a37e6b3be5440346a18af935d591d261ef53a3d7b2eb9e94ef29460bf6b40babe243d39efb4139dc63bd97081cb098bac012a04ac03869dc6
6
+ metadata.gz: 2d4ee24f67b5268c8976acfd83f54604ef65aef74c648507fed2356a7f5afe2025480314c9708b9bc5782507d98f671f1c5504523142f31d11364ba1ed8ed28e
7
+ data.tar.gz: aa223c7aff3c0f0a5bfb60b365f8bf7f6596889e071d9333ed7dc44f583edf79cd9e8ae7c5372d26f38ecc2bd179e39bba169d340e2e7a5a155be90bfb04530a
@@ -112,7 +112,6 @@ class CompileLibraryTester < Minitest::Test
112
112
 
113
113
  foorth_equal('Object .: .lvt6 val: lv lv 10 * ;' , [])
114
114
  foorth_equal('10 Object .new .lvt6 ' , [100])
115
-
116
115
  end
117
116
 
118
117
  def test_exclusive_methods
@@ -233,7 +232,74 @@ class CompileLibraryTester < Minitest::Test
233
232
 
234
233
  foorth_equal("Integer .: minus self swap - ; 10 5 minus", [5])
235
234
  foorth_equal("Integer '. .: rinus self swap - ; 10 5 rinus", [-5])
235
+ end
236
+
237
+ def test_method_aliasing
238
+ foorth_run('class: TestAlias')
239
+ foorth_run('TestAlias .: .method_name 42 ;')
240
+ foorth_run('TestAlias .new val$: $test_aliasing_one')
241
+ foorth_run('TestAlias .new val$: $test_aliasing_two')
242
+
243
+ foorth_equal('$test_aliasing_one .method_name', [42])
244
+ foorth_raises('$test_aliasing_one .alias_name')
245
+ foorth_raises('$test_aliasing_one .with {{ ~other_name }}')
246
+
247
+ foorth_run('".method_name" TestAlias .alias: .alias_name')
248
+
249
+ foorth_equal('$test_aliasing_one .method_name', [42])
250
+ foorth_equal('$test_aliasing_one .alias_name', [42])
251
+ foorth_raises('$test_aliasing_one .with {{ ~other_name }}')
252
+
253
+ foorth_run('".method_name" TestAlias .alias: ~other_name')
254
+
255
+ foorth_equal('$test_aliasing_one .method_name', [42])
256
+ foorth_equal('$test_aliasing_one .alias_name', [42])
257
+ foorth_equal('$test_aliasing_one .with{{ ~other_name }}', [42])
258
+
259
+ foorth_raises('".method_name" TestAlias .alias: ++++')
260
+
261
+ foorth_run('$test_aliasing_two .:: .method_name 69 ;')
262
+ foorth_equal('$test_aliasing_one .method_name', [42])
263
+ foorth_equal('$test_aliasing_two .method_name', [69])
264
+
265
+ foorth_run('".method_name" $test_aliasing_two .alias:: .crazy')
266
+ foorth_equal('$test_aliasing_two .crazy', [69])
267
+ foorth_raises('$test_aliasing_one .crazy')
268
+
269
+ foorth_raises('"+" Numeric .alias: .add')
270
+ foorth_run('"-" Numeric \'* .alias: .sub')
271
+ foorth_equal('11 4 .sub', [7])
236
272
 
273
+ foorth_run('"dup" alias: doop')
274
+ foorth_equal('11 doop', [11, 11])
237
275
  end
238
276
 
277
+ def test_method_stubs
278
+ foorth_run('class: TestStubs')
279
+ foorth_equal('TestStubs .new .to_i', [nil])
280
+
281
+ foorth_run('TestStubs .stub: .to_i')
282
+ foorth_raises('TestStubs .new .to_i')
283
+
284
+ foorth_run('TestStubs .new val$: $test_stubs_one')
285
+ foorth_run('TestStubs .new val$: $test_stubs_two')
286
+
287
+ foorth_run('$test_stubs_two .stub:: .to_r')
288
+
289
+ foorth_equal('$test_stubs_one .to_r', [nil])
290
+ foorth_raises('$test_stubs_two .to_r')
291
+
292
+ foorth_run('"dup" alias: dupe')
293
+ foorth_equal('3 dup ', [3,3])
294
+ foorth_equal('3 dupe', [3,3])
295
+
296
+ foorth_run('stub: dup')
297
+
298
+ foorth_raises('3 dup ')
299
+ foorth_equal('3 dupe', [3,3])
300
+
301
+ foorth_run('"dupe" alias: dup')
302
+ end
303
+
304
+
239
305
  end
@@ -11,9 +11,30 @@ module XfOOrth
11
11
  #* name - The string to be mapped.
12
12
  #<br>Returns:
13
13
  #* The specification that corresponds to the name or nil if none found.
14
- def map(name, allow_defaults=:allow)
14
+ def map_with_defaults(name)
15
15
  if (@symbol = SymbolMap.map(@name = name))
16
- do_map_name(allow_defaults)
16
+ do_map_name ||
17
+ case @name[0]
18
+ when '.'
19
+ TosSpec.new(@name, @symbol, [:temp])
20
+
21
+ when '~'
22
+ SelfSpec.new(@name, @symbol, [:temp])
23
+
24
+ else
25
+ spec_error
26
+ end
27
+ end
28
+ end
29
+
30
+ #Map a name to a specification.
31
+ #<br>Parameters:
32
+ #* name - The string to be mapped.
33
+ #<br>Returns:
34
+ #* The specification that corresponds to the name or nil if none found.
35
+ def map_without_defaults(name)
36
+ if (@symbol = SymbolMap.map(@name = name))
37
+ do_map_name
17
38
  end
18
39
  end
19
40
 
@@ -21,23 +42,13 @@ module XfOOrth
21
42
  private
22
43
 
23
44
  #Do a search of dictionaries based on the syntax of the name.
24
- def do_map_name(allow_defaults)
45
+ def do_map_name
25
46
  self[@symbol] ||
26
47
  do_target_class_map ||
27
48
  do_target_object_map ||
28
49
  do_target_vm_map ||
29
50
  do_object_class_map ||
30
- do_global_map ||
31
- (allow_defaults && case @name[0]
32
- when '.'
33
- TosSpec.new(@name, @symbol, [:temp])
34
-
35
- when '~'
36
- SelfSpec.new(@name, @symbol, [:temp])
37
-
38
- else
39
- spec_error
40
- end)
51
+ do_global_map
41
52
  end
42
53
 
43
54
  #Do a search of the Object class for the item.
@@ -11,7 +11,7 @@ module XfOOrth
11
11
  #* token - The token to receive the generated code.
12
12
  #* word - The text of the word.
13
13
  def generate_code(token, word)
14
- if (spec = @context.map(word))
14
+ if (spec = @context.map_with_defaults(word))
15
15
  token.add(spec.builds, spec.tags)
16
16
  elsif (value = word.to_foorth_n)
17
17
  token.add("vm.push(#{value.foorth_embed}); ", [:numeric])
@@ -39,7 +39,7 @@ module XfOOrth
39
39
  #Get the default action if none is specified.
40
40
  def get_stub_action(name, symbol)
41
41
  lambda do |*_any|
42
- error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol.inspect})."
42
+ f20_error(self, name, symbol)
43
43
  end
44
44
  end
45
45
 
@@ -100,7 +100,7 @@ module XfOOrth
100
100
  #be removed at this time.
101
101
  vm.data_stack.pop
102
102
 
103
- error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol.inspect})."
103
+ f20_error(self, name, symbol)
104
104
  end
105
105
  end
106
106
 
@@ -175,7 +175,7 @@ module XfOOrth
175
175
  #* The last entry in the tags array is expected to be a string
176
176
  # with the text of the command macro.
177
177
  def build_builds_string(_name, _symbol)
178
- @builds = @tags.pop
178
+ @builds = @tags[-1]
179
179
  end
180
180
  end
181
181
  end
@@ -68,7 +68,7 @@ class Object
68
68
  if (stub_spec = Object.foorth_shared[symbol])
69
69
  self.instance_exec(*args, &stub_spec.does)
70
70
  else
71
- error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol})."
71
+ f20_error(self, name, symbol)
72
72
  end
73
73
  else
74
74
  super
@@ -7,6 +7,8 @@ require_relative 'library/vm_library'
7
7
  require_relative 'library/data_ref_library'
8
8
  require_relative 'library/clone_library'
9
9
  require_relative 'library/compile_library'
10
+ require_relative 'library/alias_library'
11
+ require_relative 'library/stubs_library'
10
12
  require_relative 'library/ctrl_struct_library'
11
13
  require_relative 'library/stdio_library'
12
14
  require_relative 'library/numeric_library'
@@ -0,0 +1,126 @@
1
+ # coding: utf-8
2
+
3
+ #* library/alias_library.rb - Support for method aliasing in fOOrth.
4
+ module XfOOrth
5
+
6
+ VirtualMachine.create_shared_method('alias:', VmSpec, [:immediate],
7
+ &lambda {|vm|
8
+ new_name = parser.get_word().inspect
9
+ process_text("vm.create_word_alias(#{new_name}); ")
10
+ })
11
+
12
+ VirtualMachine.create_shared_method('.alias:', VmSpec, [:immediate],
13
+ &lambda {|vm|
14
+ new_name = parser.get_word().inspect
15
+ process_text("vm.create_shared_alias(#{new_name}); ")
16
+ })
17
+
18
+ VirtualMachine.create_shared_method('.alias::', VmSpec, [:immediate],
19
+ &lambda {|vm|
20
+ new_name = parser.get_word().inspect
21
+ process_text("vm.create_exclusive_alias(#{new_name}); ")
22
+ })
23
+
24
+ # Alias support methods in the VirtualMachine class.
25
+ class VirtualMachine
26
+ ALLOWED_ALIAS_TYPES = {
27
+ TosSpec => [TosSpec, SelfSpec],
28
+ SelfSpec => [TosSpec, SelfSpec],
29
+ NosSpec => [NosSpec]
30
+ }
31
+
32
+ #Create a virtual machine word method alias.
33
+ def create_word_alias(new_name)
34
+ old_name, target = pop, self.class
35
+
36
+ old_spec = get_old_shared_spec(target, old_name)
37
+
38
+ target.create_shared_method(new_name,
39
+ old_spec.class,
40
+ old_spec.tags,
41
+ &old_spec.does)
42
+ end
43
+
44
+ #Create a shared method alias
45
+ def create_shared_alias(new_name)
46
+ old_name, target = popm(2)
47
+
48
+ unless target.is_a?(Class)
49
+ error "F13: The target of .alias: must be a class"
50
+ end
51
+
52
+ old_spec = get_old_shared_spec(target, old_name)
53
+
54
+ target.create_shared_method(new_name,
55
+ get_alias_type(old_spec, new_name),
56
+ old_spec.tags,
57
+ &old_spec.does)
58
+ clear_cast
59
+ end
60
+
61
+ #Create an exclusive method alias
62
+ def create_exclusive_alias(new_name)
63
+ old_name, target = popm(2)
64
+
65
+ old_spec = get_old_exclusive_spec(target, old_name)
66
+
67
+ target.create_exclusive_method(new_name,
68
+ get_alias_type(old_spec, new_name),
69
+ old_spec.tags,
70
+ &old_spec.does)
71
+ clear_cast
72
+ end
73
+
74
+ private
75
+
76
+ #Get the shared specification of the original method.
77
+ def get_old_shared_spec(target, old_name)
78
+ old_symbol = get_old_symbol(old_name)
79
+
80
+ unless (old_spec = target.map_foorth_shared(old_symbol))
81
+ f20_error(target, old_name, old_symbol)
82
+ end
83
+
84
+ old_spec
85
+ end
86
+
87
+ #Get the exclusive specification of the original method.
88
+ def get_old_exclusive_spec(target, old_name)
89
+ old_symbol = get_old_symbol(old_name)
90
+
91
+ unless (old_spec = target.map_foorth_exclusive(old_symbol))
92
+ f20_error(target, old_name, old_symbol)
93
+ end
94
+
95
+ old_spec
96
+ end
97
+
98
+ #Get the symbol of the old method.
99
+ def get_old_symbol(old_name)
100
+ old_symbol = XfOOrth::SymbolMap.map(old_name)
101
+ error "F10: ?#{old_name}?" unless old_symbol
102
+ old_symbol
103
+ end
104
+
105
+ #Get the type of the aliased method.
106
+ def get_alias_type(old_spec, new_name)
107
+ old_type = old_spec.class
108
+ new_type = XfOOrth.name_to_type(new_name, self)
109
+ old_desc, new_desc = old_type.foorth_name, new_type.foorth_name
110
+
111
+ unless (allowed = ALLOWED_ALIAS_TYPES[old_type])
112
+ error "F13: A #{old_desc} method may not be aliased."
113
+ end
114
+
115
+ unless allowed.include?(new_type)
116
+ error "F13: A #{old_desc} method may not be aliased as a #{new_desc}"
117
+ end
118
+
119
+ XfOOrth.validate_type(self, new_type, new_name)
120
+
121
+ new_type
122
+ end
123
+
124
+ end
125
+
126
+ end
@@ -74,7 +74,7 @@ module XfOOrth
74
74
  error "F13: The target of .: must be a class" unless target.is_a?(Class)
75
75
 
76
76
  name = vm.parser.get_word()
77
- type = XfOOrth.name_to_type(name, get_cast)
77
+ type = XfOOrth.name_to_type(name, self)
78
78
  XfOOrth.validate_type(vm, type, name)
79
79
  XfOOrth.validate_string_method(type, target, name)
80
80
 
@@ -132,7 +132,7 @@ module XfOOrth
132
132
  if execute_mode?
133
133
  target = vm.pop
134
134
  name = vm.parser.get_word()
135
- type = XfOOrth.name_to_type(name, get_cast)
135
+ type = XfOOrth.name_to_type(name, self)
136
136
  XfOOrth.validate_type(vm, type, name)
137
137
  XfOOrth.validate_string_method(type, target.class, name)
138
138
 
@@ -188,6 +188,8 @@ module XfOOrth
188
188
  #<br>Parameters:
189
189
  #* vm - The current virtual machine instance.
190
190
  #* ctrl - A list of valid start controls.
191
+ #<br>Endemic Code Smells
192
+ #* :reek:TooManyStatements
191
193
  def self.add_common_compiler_locals(vm, ctrl)
192
194
  context = vm.context
193
195
 
@@ -212,7 +214,7 @@ module XfOOrth
212
214
  #*name - The name of the method to be created.
213
215
  #<Returns>
214
216
  #* The class of the spec to be used for this method.
215
- def self.name_to_type(name, cast_spec=nil)
217
+ def self.name_to_type(name, vm)
216
218
  normal_spec = case name[0]
217
219
  when '.'
218
220
  TosSpec
@@ -227,7 +229,7 @@ module XfOOrth
227
229
  NosSpec
228
230
  end
229
231
 
230
- cast_spec || normal_spec
232
+ vm.get_cast || normal_spec
231
233
  end
232
234
 
233
235
  #Compare the new method's spec against the specs of other methods of the
@@ -238,7 +240,7 @@ module XfOOrth
238
240
  #*type - The class of the method to be created.
239
241
  #*name - The name of the method to be created.
240
242
  def self.validate_type(vm, type, name)
241
- if (spec = vm.context.map(name, false))
243
+ if (spec = vm.context.map_without_defaults(name))
242
244
  if spec.class != type
243
245
  error "F90: Spec type mismatch #{spec.foorth_name} vs #{type.foorth_name}"
244
246
  end
@@ -13,13 +13,15 @@ module XfOOrth
13
13
  #Add an item to this page.
14
14
  #<br>Returns
15
15
  #* The number if items that did not fit in the page.
16
+ #<br>Endemic Code Smells
17
+ #* :reek:FeatureEnvy
16
18
  def add(raw_bullet = "*", *raw_item)
17
19
 
18
20
  if raw_item.empty?
19
21
  bullet = ["*"]
20
22
  items = raw_bullet.in_array
21
23
  else
22
- bullet = raw_bullet.in_array
24
+ bullet = [raw_bullet]
23
25
  items = raw_item.in_array
24
26
  end
25
27
 
@@ -48,24 +50,25 @@ module XfOOrth
48
50
  end
49
51
 
50
52
  #Render one bullet point.
53
+ #<br>Endemic Code Smells
54
+ #* :reek:DuplicateMethodCall :reek:TooManyStatements
51
55
  def render_bullet(key, item)
52
- result = []
56
+ result, pass_one = [], true
53
57
  input = item.split(' ').each
54
58
  temp = key.ljust(len = @key_length)
55
- pass_one = true
56
59
 
57
60
  loop do
58
61
  word = ' ' + input.next
59
62
 
60
63
  while len >= @page_width
61
64
  result << temp.slice!(0, @page_width - 1)
62
- temp = (' ' * @key_length) + ' ' + temp
65
+ temp = blank_key + ' ' + temp
63
66
  len = temp.length
64
67
  end
65
68
 
66
69
  if ((len += word.length) >= @page_width) && !pass_one
67
70
  result << temp
68
- temp = (' ' * @key_length) + word
71
+ temp = blank_key + word
69
72
  len = temp.length
70
73
  else
71
74
  temp << word
@@ -76,10 +79,16 @@ module XfOOrth
76
79
  result << temp
77
80
  end
78
81
 
82
+ #Generate a blank bullet key
83
+ def blank_key
84
+ ' ' * @key_length
85
+ end
86
+
79
87
  end
80
88
 
81
89
  end
82
90
 
91
+ #Bullet point support in the Array class.
83
92
  class Array
84
93
  #Print out the array as bullet points.
85
94
  def puts_foorth_bullets(page_width)
@@ -100,6 +109,7 @@ class Array
100
109
  end
101
110
  end
102
111
 
112
+ #Bullet point support in the Hash class.
103
113
  class Hash
104
114
  #Print out the hash as bullet points.
105
115
  def puts_foorth_bullets(page_width)
@@ -28,6 +28,8 @@ module XfOOrth
28
28
  end
29
29
 
30
30
  #Render the page as an array of strings.
31
+ #<br>Endemic Code Smells
32
+ #* :reek:NestedIterators :reek:TooManyStatements
31
33
  def render
32
34
  results = []
33
35
  widths = @page_data.map {|column| column.foorth_column_width}
@@ -30,17 +30,11 @@ class Class
30
30
  found = false
31
31
 
32
32
  if symbol
33
- spec, info = map_foorth_shared_info(symbol)
34
-
35
- if spec && !spec.has_tag?(:stub)
36
- (results << ["", ""]).concat(info).concat(spec.get_info)
33
+ if scrape_method_info(results, *map_foorth_shared_info(symbol))
37
34
  found = true
38
35
  end
39
36
 
40
- spec, info = map_foorth_exclusive_info(symbol)
41
-
42
- if spec && !spec.has_tag?(:stub)
43
- (results << ["", ""]).concat(info).concat(spec.get_info)
37
+ if scrape_method_info(results, *map_foorth_exclusive_info(symbol, "Class"))
44
38
  found = true
45
39
  end
46
40
 
@@ -54,18 +48,28 @@ class Class
54
48
  def get_info
55
49
  results = [["Lineage", lineage]]
56
50
 
57
- if foorth_has_exclusive?
58
- results.concat([["", ""], ["Methods", "Class"]])
51
+ get_exclusive_method_info(results, "Class")
52
+ get_shared_method_info(results)
59
53
 
60
- foorth_exclusive.extract_method_names(:all).sort.each do |name|
61
- symbol, info = XfOOrth::SymbolMap.map_info(name)
62
- (results << ["", ""]).concat(info)
54
+ results
55
+ end
63
56
 
64
- spec, info = map_foorth_exclusive_info(symbol, :shallow)
65
- results.concat(info).concat(spec.get_info)
66
- end
57
+ private
58
+
59
+ #Get method information
60
+ #<br>Endemic Code Smells
61
+ #* :reek:UtilityFunction
62
+ def scrape_method_info(results, spec, info)
63
+ if spec && !spec.has_tag?(:stub)
64
+ (results << ["", ""]).concat(info).concat(spec.get_info)
65
+ true
66
+ else
67
+ false
67
68
  end
69
+ end
68
70
 
71
+ #Get shared method info
72
+ def get_shared_method_info(results)
69
73
  unless foorth_shared.empty?
70
74
  results.concat([["", ""], ["Methods", "Shared"]])
71
75
 
@@ -77,8 +81,6 @@ class Class
77
81
  results.concat(info).concat(spec.get_info)
78
82
  end
79
83
  end
80
-
81
- results
82
84
  end
83
85
 
84
86
  end
@@ -7,6 +7,8 @@ module XfOOrth
7
7
  class Context
8
8
 
9
9
  #Get introspection info.
10
+ #<br>Endemic Code Smells
11
+ #* :reek:FeatureEnvy :reek:TooManyStatements
10
12
  def get_info
11
13
  results = [["Level", depth]]
12
14
 
@@ -25,8 +27,7 @@ module XfOOrth
25
27
  end
26
28
 
27
29
  if (prev = self.previous)
28
- results << ["", ""]
29
- results.concat(prev.get_info)
30
+ results.concat([["", ""]]).concat(prev.get_info)
30
31
  end
31
32
 
32
33
  results
@@ -17,31 +17,15 @@ class Object
17
17
  #Get introspection info.
18
18
  def get_info
19
19
  results = [["Type", foorth_name]]
20
-
21
- unless (vars = instance_variables).empty?
22
- results.concat([["", ""], ["Data", "Instance"], ["", ""]])
23
-
24
- vars.sort.each do |name|
25
- var_name = XfOOrth::SymbolMap.unmap(name[1..-1].to_sym) || name
26
- results << [var_name, instance_variable_get(name)]
27
- end
28
- end
29
-
30
- if foorth_has_exclusive?
31
- results.concat([["", ""], ["Methods", "Exclusive"]])
32
-
33
- foorth_exclusive.extract_method_names(:all).sort.each do |name|
34
- symbol, info = XfOOrth::SymbolMap.map_info(name)
35
- results.concat([["", ""], ["Name", name], info])
36
- spec, info = map_foorth_exclusive_info(symbol, :shallow)
37
- results.concat(info).concat(spec.get_info)
38
- end
39
- end
20
+ get_instance_variable_info(results)
21
+ get_exclusive_method_info(results, "Exclusive")
40
22
 
41
23
  results
42
24
  end
43
25
 
44
26
  #Investigate a method of this object.
27
+ #<br>Endemic Code Smells
28
+ #* :reek:FeatureEnvy
45
29
  def foorth_method_info(name)
46
30
  symbol, results = XfOOrth::SymbolMap.map_info(name)
47
31
  found = false
@@ -65,5 +49,43 @@ class Object
65
49
  foorth_name + " < " + self.class.lineage
66
50
  end
67
51
 
52
+ private
53
+
54
+ #Get information about instance variables
55
+ def get_instance_variable_info(results)
56
+ names = instance_variables.map do |sym|
57
+ if (name = XfOOrth::SymbolMap.unmap(sym.to_s[1..-1].to_sym))
58
+ [name, sym]
59
+ end
60
+ end
61
+ .compact
62
+ .sort {|first, second| first[0] <=> second[0] }
63
+
64
+ unless names.empty?
65
+ results.concat([["", ""], ["Data", "Instance"], ["", ""]])
66
+
67
+ names.each do |name, sym|
68
+ results << [name, instance_variable_get(sym)]
69
+ end
70
+ end
71
+ end
72
+
73
+
74
+ #Get exclusive method info
75
+ def get_exclusive_method_info(results, designation)
76
+ if foorth_has_exclusive?
77
+ results.concat([["", ""], ["Methods", designation]])
78
+
79
+ foorth_exclusive.extract_method_names(:all).sort.each do |name|
80
+ symbol, info = XfOOrth::SymbolMap.map_info(name)
81
+ (results << ["", ""]).concat(info)
82
+
83
+ spec, info = map_foorth_exclusive_info(symbol, :shallow)
84
+ results.concat(info).concat(spec.get_info)
85
+ end
86
+ end
87
+ end
88
+
89
+
68
90
 
69
91
  end
@@ -4,6 +4,8 @@
4
4
  class String
5
5
 
6
6
  #Scan all classes for information about a method.
7
+ #<br>Endemic Code Smells
8
+ #* :reek:DuplicateMethodCall :reek:FeatureEnvy :reek:TooManyStatements
7
9
  def foorth_method_scan
8
10
  symbol, results = XfOOrth::SymbolMap.map_info(self)
9
11
  found = false
@@ -11,13 +13,27 @@ class String
11
13
  symbol && $FOORTH_GLOBALS.values
12
14
  .select {|entry| entry.has_tag?(:class)}
13
15
  .collect {|spec| spec.new_class}
14
- .sort {|a,b| a.foorth_name <=> b.foorth_name}
16
+ .sort {|first, second| first.foorth_name <=> second.foorth_name}
15
17
  .each do |klass|
16
- spec, info = klass.map_foorth_shared_info(symbol, :shallow)
17
- found |= spec && (results << ["", ""]).concat(info).concat(spec.get_info)
18
+ shared_spec, shared_info = klass.map_foorth_shared_info(symbol, :shallow)
18
19
 
19
- spec, info = klass.map_foorth_exclusive_info(symbol, :shallow)
20
- found |= spec && (results << ["", ""]).concat(info).concat(spec.get_info)
20
+ if shared_spec
21
+ results
22
+ .concat([["", ""]])
23
+ .concat(shared_info)
24
+ .concat(shared_spec.get_info)
25
+ end
26
+
27
+ excl_spec, excl_info = klass.map_foorth_exclusive_info(symbol, :shallow)
28
+
29
+ if excl_spec
30
+ results
31
+ .concat([["", ""]])
32
+ .concat(excl_info)
33
+ .concat(excl_spec.get_info)
34
+ end
35
+
36
+ found ||= (shared_spec || excl_spec)
21
37
  end
22
38
 
23
39
  results << ["Scope", "not found in any class."] if symbol && !found
@@ -8,6 +8,18 @@ module XfOOrth
8
8
 
9
9
  #Get introspection info.
10
10
  def get_info
11
+ results = get_basic_vm_info
12
+ get_instance_variable_info(results)
13
+ get_vm_thread_data_info(results)
14
+ get_exclusive_method_info(results, "Exclusive")
15
+
16
+ results
17
+ end
18
+
19
+ private
20
+
21
+ #Get the vm basic stuff first.
22
+ def get_basic_vm_info
11
23
  results = [["Name", foorth_name],
12
24
  ["Ruby", self.to_s],
13
25
  ["Stack", @data_stack.inspect],
@@ -22,47 +34,23 @@ module XfOOrth
22
34
  results << ["Buffer", source.read_buffer.inspect]
23
35
  end
24
36
 
25
- names = instance_variables.map do |sym|
26
- if (name = XfOOrth::SymbolMap.unmap(sym.to_s[1..-1].to_sym))
27
- [name, sym]
28
- end
29
- end
30
-
31
- names.compact!
32
-
33
- unless names.empty?
34
- results.concat([["", ""], ["Data", "Instance"], ["", ""]])
35
-
36
- names.each do |name, sym|
37
- results << [name, instance_variable_get(sym)]
38
- end
39
- end
37
+ results
38
+ end
40
39
 
40
+ #Get the thread data info.
41
+ def get_vm_thread_data_info(results)
41
42
  unless @data.empty?
42
43
  results.concat([["", ""], ["Data", "Thread"], ["", ""]])
43
44
 
44
45
  @data
45
46
  .keys
46
47
  .map{|symbol| [SymbolMap.unmap(symbol), symbol]}
47
- .sort{|a,b| a[0] <=> b[0]}
48
+ .sort{|first, second| first[0] <=> second[0]}
48
49
  .map{|name, symbol| [name, @data[symbol]]}
49
50
  .each do |name, value|
50
51
  results << [name, value.inspect]
51
52
  end
52
53
  end
53
-
54
- if foorth_has_exclusive?
55
- results.concat([["", ""], ["Methods", "Exclusive"]])
56
-
57
- foorth_exclusive.extract_method_names(:all).sort.each do |name|
58
- symbol, info = SymbolMap.map_info(name)
59
- results.concat([["", ""], ["Name", name], info])
60
- spec, info = map_foorth_exclusive_info(symbol, :shallow)
61
- results.concat(info).concat(spec.get_info)
62
- end
63
- end
64
-
65
- results
66
54
  end
67
55
 
68
56
  end
@@ -0,0 +1,49 @@
1
+ # coding: utf-8
2
+
3
+ #* library/stubs_library.rb - Support for method stubs in fOOrth.
4
+ module XfOOrth
5
+ VirtualMachine.create_shared_method('stub:', VmSpec, [:immediate],
6
+ &lambda {|vm|
7
+ name = parser.get_word().inspect
8
+ process_text("vm.class.create_shared_method(#{name}, VmSpec, [:stub]); ")
9
+ })
10
+
11
+ VirtualMachine.create_shared_method('.stub:', VmSpec, [:immediate],
12
+ &lambda {|vm|
13
+ name = parser.get_word().inspect
14
+ process_text("vm.create_shared_stub(#{name}); ")
15
+ })
16
+
17
+ VirtualMachine.create_shared_method('.stub::', VmSpec, [:immediate],
18
+ &lambda {|vm|
19
+ name = parser.get_word().inspect
20
+ process_text("vm.create_exclusive_stub(#{name}); ")
21
+ })
22
+
23
+ # Stub support methods in the VirtualMachine class.
24
+ class VirtualMachine
25
+
26
+ #Create a shared method stub
27
+ def create_shared_stub(name)
28
+ unless (target = pop).is_a?(Class)
29
+ error "F13: The target of .stub: must be a class"
30
+ end
31
+
32
+ type = XfOOrth.name_to_type(name, self)
33
+ XfOOrth.validate_type(self, type, name)
34
+ target.create_shared_method(name, type, [:stub])
35
+ clear_cast
36
+ end
37
+
38
+ #Create an exclusive method stub
39
+ def create_exclusive_stub(name)
40
+ target = pop
41
+ type = XfOOrth.name_to_type(name, self)
42
+ XfOOrth.validate_type(self, type, name)
43
+ target.create_exclusive_method(name, type, [:stub])
44
+ clear_cast
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -38,6 +38,13 @@ class Object
38
38
  fail XfOOrth::XfOOrthError, msg, caller
39
39
  end
40
40
 
41
+ #A helper macro for method not understood errors.
42
+ def f20_error(recvr, name, symbol)
43
+ fail XfOOrth::XfOOrthError,
44
+ "F20: A #{recvr.foorth_name} does not understand #{name} (#{symbol.inspect}).",
45
+ caller
46
+ end
47
+
41
48
  #Argument coercion methods. These are stubs.
42
49
 
43
50
  #Coerce the argument to match my type. Stub
@@ -3,5 +3,5 @@
3
3
  #* version.rb - The version string for fOOrth.
4
4
  module XfOOrth
5
5
  #The version string for fOOrth.
6
- VERSION = "0.6.6"
6
+ VERSION = "0.6.7"
7
7
  end
data/reek.txt CHANGED
@@ -1,59 +1 @@
1
- lib/fOOrth/compiler/context/map_name.rb -- 1 warning:
2
- [31]:ControlParameter: XfOOrth::Context#do_map_name is controlled by argument allow_defaults [https://github.com/troessner/reek/blob/master/docs/Control-Parameter.md]
3
- lib/fOOrth/library/compile_library.rb -- 2 warnings:
4
- [230]:ControlParameter: XfOOrth#self.name_to_type is controlled by argument cast_spec [https://github.com/troessner/reek/blob/master/docs/Control-Parameter.md]
5
- [191]:TooManyStatements: XfOOrth#self.add_common_compiler_locals has approx 8 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
6
- lib/fOOrth/library/formatting/bullets.rb -- 10 warnings:
7
- [20, 22]:DuplicateMethodCall: XfOOrth::BulletPoints#add calls raw_bullet.in_array 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
8
- [62, 68]:DuplicateMethodCall: XfOOrth::BulletPoints#render_bullet calls ' ' * @key_length 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
9
- [67, 76]:DuplicateMethodCall: XfOOrth::BulletPoints#render_bullet calls result << temp 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
10
- [63, 69]:DuplicateMethodCall: XfOOrth::BulletPoints#render_bullet calls temp.length 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
11
- [26, 27]:FeatureEnvy: XfOOrth::BulletPoints#add refers to items more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
12
- [20, 22]:FeatureEnvy: XfOOrth::BulletPoints#add refers to raw_bullet more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
13
- [18, 23]:FeatureEnvy: XfOOrth::BulletPoints#add refers to raw_item more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
14
- [83]:IrresponsibleModule: Array has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
15
- [103]:IrresponsibleModule: Hash has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
16
- [51]:TooManyStatements: XfOOrth::BulletPoints#render_bullet has approx 15 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
17
- lib/fOOrth/library/formatting/columns.rb -- 2 warnings:
18
- [36]:NestedIterators: XfOOrth::ColumnizedPage#render contains iterators nested 2 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
19
- [31]:TooManyStatements: XfOOrth::ColumnizedPage#render has approx 8 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
20
- lib/fOOrth/library/introspection/class.rb -- 15 warnings:
21
- [35, 42]:DuplicateMethodCall: Class#foorth_method_info calls !spec.has_tag?(:stub) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
22
- [36, 43]:DuplicateMethodCall: Class#foorth_method_info calls (results << ["", ""]).concat(info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
23
- [36, 43]:DuplicateMethodCall: Class#foorth_method_info calls (results << ["", ""]).concat(info).concat(spec.get_info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
24
- [36, 43]:DuplicateMethodCall: Class#foorth_method_info calls results << ["", ""] 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
25
- [36, 43]:DuplicateMethodCall: Class#foorth_method_info calls spec.get_info 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
26
- [35, 42]:DuplicateMethodCall: Class#foorth_method_info calls spec.has_tag?(:stub) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
27
- [62, 74]:DuplicateMethodCall: Class#get_info calls (results << ["", ""]).concat(info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
28
- [61, 73]:DuplicateMethodCall: Class#get_info calls XfOOrth::SymbolMap.map_info(name) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
29
- [62, 74]:DuplicateMethodCall: Class#get_info calls results << ["", ""] 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
30
- [65, 77]:DuplicateMethodCall: Class#get_info calls results.concat(info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
31
- [65, 77]:DuplicateMethodCall: Class#get_info calls results.concat(info).concat(spec.get_info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
32
- [65, 77]:DuplicateMethodCall: Class#get_info calls spec.get_info 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
33
- [35, 36, 42, 43]:FeatureEnvy: Class#foorth_method_info refers to spec more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
34
- [28]:TooManyStatements: Class#foorth_method_info has approx 10 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
35
- [54]:TooManyStatements: Class#get_info has approx 14 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
36
- lib/fOOrth/library/introspection/context.rb -- 3 warnings:
37
- [14, 28]:DuplicateMethodCall: XfOOrth::Context#get_info calls results << ["", ""] 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
38
- [14, 17, 18, 19, 21, 22, 28, 29]:FeatureEnvy: XfOOrth::Context#get_info refers to results more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
39
- [10]:TooManyStatements: XfOOrth::Context#get_info has approx 11 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
40
- lib/fOOrth/library/introspection/object.rb -- 3 warnings:
41
- [53, 57]:FeatureEnvy: Object#foorth_method_info refers to results more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
42
- [52, 53]:FeatureEnvy: Object#foorth_method_info refers to spec more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
43
- [18]:TooManyStatements: Object#get_info has approx 12 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
44
- lib/fOOrth/library/introspection/string.rb -- 10 warnings:
45
- [17, 20]:DuplicateMethodCall: String#foorth_method_scan calls (results << ["", ""]).concat(info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
46
- [17, 20]:DuplicateMethodCall: String#foorth_method_scan calls (results << ["", ""]).concat(info).concat(spec.get_info) 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
47
- [17, 20]:DuplicateMethodCall: String#foorth_method_scan calls results << ["", ""] 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
48
- [17, 20]:DuplicateMethodCall: String#foorth_method_scan calls spec.get_info 2 times [https://github.com/troessner/reek/blob/master/docs/Duplicate-Method-Call.md]
49
- [17, 20, 23]:FeatureEnvy: String#foorth_method_scan refers to found more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
50
- [17, 20, 23]:FeatureEnvy: String#foorth_method_scan refers to results more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
51
- [13, 17, 20]:FeatureEnvy: String#foorth_method_scan refers to spec more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]
52
- [7]:TooManyStatements: String#foorth_method_scan has approx 12 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
53
- [14]:UncommunicativeVariableName: String#foorth_method_scan has the variable name 'a' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
54
- [14]:UncommunicativeVariableName: String#foorth_method_scan has the variable name 'b' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
55
- lib/fOOrth/library/introspection/vm.rb -- 3 warnings:
56
- [10]:TooManyStatements: XfOOrth::VirtualMachine#get_info has approx 22 statements [https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md]
57
- [47]:UncommunicativeVariableName: XfOOrth::VirtualMachine#get_info has the variable name 'a' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
58
- [47]:UncommunicativeVariableName: XfOOrth::VirtualMachine#get_info has the variable name 'b' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
59
- 49 total warnings
1
+ 0 total warnings
@@ -108,7 +108,7 @@ class ContextTester < Minitest::Test
108
108
  name = 'b'
109
109
  sym = XfOOrth::SymbolMap.add_entry(name)
110
110
  context[sym] = XfOOrth::VmSpec.new(name, sym, [])
111
- spec = context.map(name)
111
+ spec = context.map_with_defaults(name)
112
112
  assert(spec.is_a?(XfOOrth::VmSpec))
113
113
  end
114
114
 
@@ -119,7 +119,7 @@ class ContextTester < Minitest::Test
119
119
  name = '.c'
120
120
  sym = XfOOrth::SymbolMap.add_entry(name)
121
121
  mk[sym] = XfOOrth::TosSpec.new(name, sym, [])
122
- spec = context.map(name)
122
+ spec = context.map_with_defaults(name)
123
123
  assert(spec.is_a?(XfOOrth::TosSpec))
124
124
  end
125
125
 
@@ -130,7 +130,7 @@ class ContextTester < Minitest::Test
130
130
  name = '.d'
131
131
  sym = XfOOrth::SymbolMap.add_entry(name)
132
132
  mk[sym] = XfOOrth::TosSpec.new(name, sym, [])
133
- spec = context.map(name)
133
+ spec = context.map_with_defaults(name)
134
134
  assert(spec.is_a?(XfOOrth::TosSpec))
135
135
  end
136
136
 
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.6
4
+ version: 0.6.7
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-09-16 00:00:00.000000000 Z
11
+ date: 2016-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -266,6 +266,7 @@ files:
266
266
  - lib/fOOrth/interpreter/do_loop.rb
267
267
  - lib/fOOrth/interpreter/squash.rb
268
268
  - lib/fOOrth/library.rb
269
+ - lib/fOOrth/library/alias_library.rb
269
270
  - lib/fOOrth/library/array_library.rb
270
271
  - lib/fOOrth/library/bundle_library.rb
271
272
  - lib/fOOrth/library/class_library.rb
@@ -306,6 +307,7 @@ files:
306
307
  - lib/fOOrth/library/stdio_library.rb
307
308
  - lib/fOOrth/library/string_library.rb
308
309
  - lib/fOOrth/library/stubs.rb
310
+ - lib/fOOrth/library/stubs_library.rb
309
311
  - lib/fOOrth/library/sync_bundle_library.rb
310
312
  - lib/fOOrth/library/thread_library.rb
311
313
  - lib/fOOrth/library/time_library.rb