fOOrth 0.6.6 → 0.6.7

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