shen-ruby 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +9 -3
  4. data/Gemfile +1 -4
  5. data/HISTORY.md +16 -0
  6. data/MIT_LICENSE.txt +1 -1
  7. data/README.md +25 -26
  8. data/Rakefile +3 -11
  9. data/bin/shen_test_suite.rb +15 -3
  10. data/bin/srrepl +6 -8
  11. data/lib/shen_ruby.rb +6 -1
  12. data/lib/shen_ruby/converters.rb +23 -0
  13. data/lib/shen_ruby/version.rb +1 -1
  14. data/shen-ruby.gemspec +4 -1
  15. data/shen/lib/shen_ruby/shen.rb +49 -33
  16. data/shen/release/benchmarks/N_queens.shen +45 -45
  17. data/shen/release/benchmarks/README.shen +14 -14
  18. data/shen/release/benchmarks/benchmarks.shen +52 -52
  19. data/shen/release/benchmarks/einstein.shen +32 -32
  20. data/shen/release/benchmarks/interpreter.shen +219 -219
  21. data/shen/release/benchmarks/jnk.shen +193 -193
  22. data/shen/release/benchmarks/powerset.shen +10 -10
  23. data/shen/release/benchmarks/prime.shen +10 -10
  24. data/shen/release/benchmarks/short.shen +129 -129
  25. data/shen/release/k_lambda/core.kl +181 -181
  26. data/shen/release/k_lambda/declarations.kl +131 -131
  27. data/shen/release/k_lambda/load.kl +84 -84
  28. data/shen/release/k_lambda/macros.kl +112 -112
  29. data/shen/release/k_lambda/prolog.kl +252 -252
  30. data/shen/release/k_lambda/reader.kl +222 -222
  31. data/shen/release/k_lambda/sequent.kl +166 -166
  32. data/shen/release/k_lambda/sys.kl +271 -271
  33. data/shen/release/k_lambda/t-star.kl +139 -139
  34. data/shen/release/k_lambda/toplevel.kl +135 -135
  35. data/shen/release/k_lambda/track.kl +103 -103
  36. data/shen/release/k_lambda/types.kl +324 -324
  37. data/shen/release/k_lambda/writer.kl +105 -105
  38. data/shen/release/k_lambda/yacc.kl +113 -113
  39. data/shen/release/test_programs/Chap13/problems.txt +26 -26
  40. data/shen/release/test_programs/README.shen +52 -52
  41. data/shen/release/test_programs/TinyLispFunctions.txt +15 -15
  42. data/shen/release/test_programs/TinyTypes.shen +55 -55
  43. data/shen/release/test_programs/binary.shen +24 -24
  44. data/shen/release/test_programs/bubble_version_1.shen +28 -28
  45. data/shen/release/test_programs/bubble_version_2.shen +22 -22
  46. data/shen/release/test_programs/calculator.shen +21 -21
  47. data/shen/release/test_programs/cartprod.shen +23 -23
  48. data/shen/release/test_programs/change.shen +25 -25
  49. data/shen/release/test_programs/classes-defaults.shen +94 -94
  50. data/shen/release/test_programs/classes-inheritance.shen +100 -100
  51. data/shen/release/test_programs/classes-typed.shen +74 -74
  52. data/shen/release/test_programs/classes-untyped.shen +46 -46
  53. data/shen/release/test_programs/depth_.shen +14 -14
  54. data/shen/release/test_programs/einstein.shen +34 -34
  55. data/shen/release/test_programs/fruit_machine.shen +46 -46
  56. data/shen/release/test_programs/interpreter.shen +217 -217
  57. data/shen/release/test_programs/metaprog.shen +85 -85
  58. data/shen/release/test_programs/minim.shen +192 -192
  59. data/shen/release/test_programs/mutual.shen +11 -11
  60. data/shen/release/test_programs/n_queens.shen +45 -45
  61. data/shen/release/test_programs/newton_version_1.shen +33 -33
  62. data/shen/release/test_programs/newton_version_2.shen +24 -24
  63. data/shen/release/test_programs/parse.prl +14 -14
  64. data/shen/release/test_programs/parser.shen +51 -51
  65. data/shen/release/test_programs/powerset.shen +10 -10
  66. data/shen/release/test_programs/prime.shen +10 -10
  67. data/shen/release/test_programs/prolog.shen +78 -78
  68. data/shen/release/test_programs/proof_assistant.shen +80 -80
  69. data/shen/release/test_programs/proplog_version_1.shen +25 -25
  70. data/shen/release/test_programs/proplog_version_2.shen +27 -27
  71. data/shen/release/test_programs/qmachine.shen +66 -66
  72. data/shen/release/test_programs/red-black.shen +54 -54
  73. data/shen/release/test_programs/search.shen +55 -55
  74. data/shen/release/test_programs/semantic_net.shen +44 -44
  75. data/shen/release/test_programs/spreadsheet.shen +34 -34
  76. data/shen/release/test_programs/stack.shen +27 -27
  77. data/shen/release/test_programs/streams.shen +20 -20
  78. data/shen/release/test_programs/strings.shen +57 -57
  79. data/shen/release/test_programs/structures-typed.shen +71 -71
  80. data/shen/release/test_programs/structures-untyped.shen +41 -41
  81. data/shen/release/test_programs/tests.shen +232 -232
  82. data/shen/release/test_programs/types.shen +11 -11
  83. data/shen/release/test_programs/whist.shen +239 -239
  84. data/shen/release/test_programs/yacc.shen +132 -132
  85. data/spec/shen_ruby/converters_spec.rb +48 -0
  86. data/spec/spec_helper.rb +1 -2
  87. metadata +55 -60
  88. data/k_lambda_spec/atom_spec.rb +0 -85
  89. data/k_lambda_spec/primitives/arithmetic_spec.rb +0 -175
  90. data/k_lambda_spec/primitives/assignments_spec.rb +0 -44
  91. data/k_lambda_spec/primitives/boolean_operations_spec.rb +0 -136
  92. data/k_lambda_spec/primitives/generic_functions_spec.rb +0 -120
  93. data/k_lambda_spec/primitives/lists_spec.rb +0 -40
  94. data/k_lambda_spec/primitives/strings_spec.rb +0 -77
  95. data/k_lambda_spec/primitives/symbols_spec.rb +0 -24
  96. data/k_lambda_spec/primitives/vectors_spec.rb +0 -92
  97. data/k_lambda_spec/spec_helper.rb +0 -29
  98. data/k_lambda_spec/support/shared_examples.rb +0 -124
  99. data/k_lambda_spec/tail_recursion_spec.rb +0 -30
  100. data/lib/kl.rb +0 -7
  101. data/lib/kl/absvector.rb +0 -12
  102. data/lib/kl/compiler.rb +0 -360
  103. data/lib/kl/cons.rb +0 -51
  104. data/lib/kl/empty_list.rb +0 -12
  105. data/lib/kl/environment.rb +0 -163
  106. data/lib/kl/error.rb +0 -4
  107. data/lib/kl/internal_error.rb +0 -7
  108. data/lib/kl/lexer.rb +0 -186
  109. data/lib/kl/primitives/arithmetic.rb +0 -60
  110. data/lib/kl/primitives/assignments.rb +0 -15
  111. data/lib/kl/primitives/booleans.rb +0 -21
  112. data/lib/kl/primitives/error_handling.rb +0 -13
  113. data/lib/kl/primitives/extensions.rb +0 -12
  114. data/lib/kl/primitives/generic_functions.rb +0 -29
  115. data/lib/kl/primitives/lists.rb +0 -23
  116. data/lib/kl/primitives/streams.rb +0 -28
  117. data/lib/kl/primitives/strings.rb +0 -63
  118. data/lib/kl/primitives/symbols.rb +0 -18
  119. data/lib/kl/primitives/time.rb +0 -17
  120. data/lib/kl/primitives/vectors.rb +0 -36
  121. data/lib/kl/reader.rb +0 -46
  122. data/spec/kl/cons_spec.rb +0 -12
  123. data/spec/kl/environment_spec.rb +0 -282
  124. data/spec/kl/interop_spec.rb +0 -68
  125. data/spec/kl/lexer_spec.rb +0 -149
  126. data/spec/kl/primitives/generic_functions_spec.rb +0 -29
  127. data/spec/kl/primitives/symbols_spec.rb +0 -21
  128. data/spec/kl/reader_spec.rb +0 -42
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for lists' do
4
- describe '(cons Hd Tl)' do
5
- it 'creates a list with Hd as the head and Tl as the tail' do
6
- kl_eval('(cons a ())').should be_kind_of Kl::Cons
7
- kl_eval('(hd (cons a ()))').should == :a
8
- kl_eval('(tl (cons a (cons b ())))').should == kl_eval('(cons b ())')
9
- end
10
-
11
- it 'allows Tl to be a non-list' do
12
- kl_eval('(tl (cons a b))').should == :b
13
- end
14
-
15
- include_examples 'partially-applicable function', %w(cons a b)
16
- include_examples 'applicative order evaluation', %w(cons a b)
17
- end
18
-
19
- describe '(hd L)' do
20
- it 'returns the head of L' do
21
- kl_eval('(hd (cons a b))').should == :a
22
- end
23
-
24
- include_examples 'argument types', [:hd, "(cons a b)"], 1 => [:list, :dotted_pair]
25
- include_examples 'partially-applicable function', [:hd, "(cons a b)"]
26
- end
27
-
28
- describe '(tl L)' do
29
- it 'returns the tail of L' do
30
- kl_eval('(tl (cons a b))').should == :b
31
- end
32
-
33
- include_examples 'argument types', [:tl, "(cons a b)"], 1 => [:list, :dotted_pair]
34
- include_examples 'partially-applicable function', [:tl, "(cons a b)"]
35
- end
36
-
37
- describe 'cons?' do
38
- include_examples 'type predicate', 'cons?', [:list, :dotted_pair]
39
- end
40
- end
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for strings' do
4
- describe '(pos S N)' do
5
- it 'returns the character at zero-based index N of S as a unit string' do
6
- kl_eval('(pos "ABC" 1)').should == "B"
7
- end
8
-
9
- it 'raises an error if N is negative' do
10
- expect {
11
- kl_eval('(pos "ABC" -1)')
12
- }.to raise_error(Kl::Error, "out of bounds")
13
- end
14
-
15
- it 'raises an error if N is >= the length of S' do
16
- expect {
17
- kl_eval('(pos "ABC" 3)')
18
- }.to raise_error(Kl::Error, "out of bounds")
19
- expect {
20
- kl_eval('(pos "ABC" 99)')
21
- }.to raise_error(Kl::Error, "out of bounds")
22
- end
23
-
24
- include_examples 'argument types', %w(pos "string" 1),
25
- 1 => [:string],
26
- 2 => [:integer]
27
- include_examples 'partially-applicable function', %w(pos "string" 1)
28
- include_examples 'applicative order evaluation', %w(pos "string" 1)
29
- end
30
-
31
- describe '(tlstr S)' do
32
- it 'returns a string containing all but the first character of S' do
33
- kl_eval('(tlstr "string")').should == "tring"
34
- end
35
-
36
- it 'raises an error when S is the empty string' do
37
- expect {
38
- kl_eval('(tlstr "")')
39
- }.to raise_error(Kl::Error, 'attempted to take tail of an empty string')
40
- end
41
-
42
- include_examples 'argument types', %w(tlstr "string"), 1 => [:string]
43
- include_examples 'partially-applicable function', %w(tlstr "string")
44
- end
45
-
46
- describe 'string?' do
47
- include_examples 'type predicate', 'string?', [:string]
48
- end
49
-
50
- describe '(n->string N)' do
51
- it 'returns a unit string containing the character with ASCII code N' do
52
- kl_eval('(n->string 65)').should == "A"
53
- end
54
-
55
- include_examples 'argument types', %w(n->string 65), 1 => [:integer]
56
- include_examples 'partially-applicable function', %w(n->string 65)
57
- end
58
-
59
- describe '(string->n S)' do
60
- it 'returns the ASCII code of the unit string S' do
61
- kl_eval('(string->n "A")').should == 65
62
- end
63
-
64
- it 'returns the ASCII code of the first character of non-unit string S' do
65
- kl_eval('(string->n "AB")').should == 65
66
- end
67
-
68
- it 'raises an error when S is the empty string' do
69
- expect {
70
- kl_eval('(string->n "")')
71
- }.to raise_error(Kl::Error, 'attempted to get code point of empty string')
72
- end
73
-
74
- include_examples 'argument types', %w(string->n "A"), 1 => [:string]
75
- include_examples 'partially-applicable function', %w(string->n "A")
76
- end
77
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for symbols' do
4
- describe 'intern' do
5
- it 'converts a string to its corresponding symbol' do
6
- kl_eval('(intern "foo")').should == :foo
7
- end
8
-
9
- it 'supports characters not allowed in symbol literals' do
10
- kl_eval('(intern "[{|}]")').should == :"[{|}]"
11
- end
12
-
13
- it 'converts the string "true" to boolean true' do
14
- kl_eval('(intern "true")').should == true
15
- end
16
-
17
- it 'converts the string "false" to boolean false' do
18
- kl_eval('(intern "false")').should == false
19
- end
20
-
21
- include_examples 'argument types', %w(intern "foo"), 1 => [:string]
22
- include_examples 'partially-applicable function', %w(intern "foo")
23
- end
24
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitive functions for vectors' do
4
- describe '(absvector N)' do
5
- it 'returns a new absolute vector of size N' do
6
- kl_eval('(absvector 3)').should be_kind_of Kl::Absvector
7
- end
8
-
9
- include_examples 'argument types', %w(absvector 7), 1 => [:integer]
10
- include_examples 'partially-applicable function', %w(absvector 7)
11
- end
12
-
13
- describe '(address-> V N Value)' do
14
- before(:each) do
15
- kl_eval('(set *vec* (absvector 5))')
16
- end
17
-
18
- it 'returns the vector V updated with Value at index N' do
19
- kl_eval('(address-> (value *vec*) 3 37)').should be_kind_of Kl::Absvector
20
- kl_eval('(<-address (value *vec*) 3)').should == 37
21
- end
22
-
23
- it 'raises an error if N is negative' do
24
- expect {
25
- kl_eval('(address-> (value *vec*) -1 37)')
26
- }.to raise_error(Kl::Error, "out of bounds")
27
- end
28
-
29
- it 'raises an error if N is >= the size of the vector' do
30
- expect {
31
- kl_eval('(address-> (value *vec*) 5 37)')
32
- }.to raise_error(Kl::Error, "out of bounds")
33
- expect {
34
- kl_eval('(address-> (value *vec*) 99 37)')
35
- }.to raise_error(Kl::Error, "out of bounds")
36
- end
37
-
38
- include_examples 'argument types',
39
- ['address->', '(value *vec*)', '0', '37'],
40
- 1 => [:vector],
41
- 2 => [:integer]
42
- include_examples 'partially-applicable function',
43
- ['address->', '(value *vec*)', '0', '37']
44
- include_examples 'applicative order evaluation',
45
- ['address->', '(value *vec*)', '0', '37']
46
- end
47
-
48
- describe '(<-address V N)' do
49
- before(:each) do
50
- kl_eval('(set *vec* (absvector 5))')
51
- end
52
-
53
- it 'returns the value previously stored at index N in V' do
54
- kl_eval('(address-> (value *vec*) 3 37)')
55
- kl_eval('(<-address (value *vec*) 3)').should == 37
56
- end
57
-
58
- it 'returns an unspecified value if index N has not been stored to' do
59
- expect {
60
- kl_eval('(<-address (value *vec*) 3)')
61
- }.to_not raise_error
62
- end
63
-
64
- it 'raises an error if N is negative' do
65
- expect {
66
- kl_eval('(<-address (value *vec*) -1)')
67
- }.to raise_error(Kl::Error, "out of bounds")
68
- end
69
-
70
- it 'raises an error if N is >= the size of the vector' do
71
- expect {
72
- kl_eval('(<-address (value *vec*) 5)')
73
- }.to raise_error(Kl::Error, "out of bounds")
74
- expect {
75
- kl_eval('(<-address (value *vec*) 99)')
76
- }.to raise_error(Kl::Error, "out of bounds")
77
- end
78
-
79
- include_examples 'argument types',
80
- ['<-address', '(value *vec*)', '0'],
81
- 1 => [:vector],
82
- 2 => [:integer]
83
- include_examples 'partially-applicable function',
84
- ['address->', '(value *vec*)', '0', '37']
85
- include_examples 'applicative order evaluation',
86
- ['address->', '(value *vec*)', '0', '37']
87
- end
88
-
89
- describe 'absvector?' do
90
- include_examples 'type predicate', 'absvector?', [:vector]
91
- end
92
- end
@@ -1,29 +0,0 @@
1
- lib_path = File.expand_path("../../lib", __FILE__)
2
- $LOAD_PATH << lib_path unless $LOAD_PATH.include?(lib_path)
3
-
4
- require 'kl'
5
- require 'stringio'
6
-
7
- # Load the support files
8
- Dir["./k_lambda_spec/support/**/*.rb"].sort.each {|f| require f}
9
-
10
- # Reset the K Lambda environment before every example
11
- RSpec.configure do |config|
12
- config.before(:each) do
13
- @kl_env = Kl::Environment.new
14
- end
15
- end
16
-
17
- # Helper function that evaluates a string in the K Lambda environment and
18
- # returns the result as a Ruby object.
19
- def kl_eval(str)
20
- form = Kl::Reader.new(StringIO.new(str)).next
21
- @kl_env.__eval(form)
22
- end
23
-
24
- # Defines the 'kl-do' function in the current K Lambda environment. This is
25
- # used instead of 'do' because do is not an official K Lambda primitive
26
- # and may not be found in all K Lambda implementations.
27
- def define_kl_do
28
- kl_eval('(defun kl-do (X Y) Y)')
29
- end
@@ -1,124 +0,0 @@
1
- # args should be an array containing the components of an example expression.
2
- # E.g., to test partial application of +, you could use:
3
- #
4
- # include_examples "partially-applicable function", %w(+ 1 2)
5
- #
6
- # The expression will be evaluated in its fully-expanded form for reference
7
- # and then compared against various partial application scenarios.
8
- shared_examples "partially-applicable function" do |args|
9
- full_expression = "(#{args.join(' ')})"
10
- (0...(args.length - 1)).each do |arg_count|
11
- description = "supports partial application of #{arg_count} argument"
12
- description << "s" unless arg_count == 1
13
- it description do
14
- full_result = kl_eval(full_expression)
15
- partial_expression = "((#{args[0..arg_count].join(' ')}) #{args[(arg_count + 1)..-1].join(' ')})"
16
- kl_eval(partial_expression).should == full_result
17
- end
18
- end
19
- end
20
-
21
- shared_examples "non-partially-applicable function" do |args|
22
- (0...(args.length - 1)).each do |arg_count|
23
- description = "raises an error when given #{arg_count} argument"
24
- description << "s" unless arg_count == 1
25
- it description do
26
- partial_expression = "(#{args[0..arg_count].join(' ')})"
27
- expect {
28
- kl_eval(partial_expression)
29
- }.to raise_error(Kl::Error, "#{args[0]} expects #{args.length - 1} arguments but was given #{arg_count}")
30
- end
31
- end
32
- end
33
-
34
- # args should be an array containing the components of an example expression.
35
- # E.g., to test applicative order evaluation of +, you could use:
36
- #
37
- # include_examples "applicative order evaluation", %w(+ 1 2)
38
- shared_examples 'applicative order evaluation' do |args|
39
- it 'evaluates its arguments from left to right' do
40
- operator = args.shift
41
- arg_indexes = (0...args.size).to_a
42
- instrumented_args = args.zip(arg_indexes).map do |(arg, idx)|
43
- "(kl-do (set *arg-order* (cn (value *arg-order*) \"#{idx}\")) #{arg})"
44
- end
45
- expected = arg_indexes.join
46
-
47
- define_kl_do
48
- kl_eval('(set *arg-order* "")')
49
- kl_eval("(#{operator} #{instrumented_args.join(' ')})")
50
- kl_eval('(value *arg-order*)').should == expected
51
- end
52
- end
53
-
54
- KL_TYPE_EXAMPLES = {
55
- integer: '1',
56
- real: '1.0',
57
- string: '"a string"',
58
- symbol: 'a-symbol',
59
- boolean: 'true',
60
- list: '(cons 1 ())',
61
- dotted_pair: '(cons 1 2)',
62
- empty_list: '()',
63
- function: '(lambda X X)',
64
- vector: '(absvector 3)'
65
- }
66
-
67
- def type_with_article(type)
68
- name = type.to_s.gsub(/_/, ' ')
69
- if [:integer, :empty_list].include?(type)
70
- 'an ' + name
71
- else
72
- 'a ' + name
73
- end
74
- end
75
-
76
- shared_examples 'type predicate' do |predicate, accepted_types|
77
- accepted_types.each do |type|
78
- it "returns true when its argument is #{type_with_article(type)}" do
79
- kl_eval("(#{predicate} #{KL_TYPE_EXAMPLES[type]})").should == true
80
- end
81
- end
82
-
83
- it 'returns false when its argument is of any other type' do
84
- rejected_types = KL_TYPE_EXAMPLES.keys - accepted_types
85
- rejected_types.each do |type|
86
- kl_eval("(#{predicate} #{KL_TYPE_EXAMPLES[type]})").should == false
87
- end
88
- end
89
- end
90
-
91
- POSITION_NAMES = { 1 => 'first', 2 => 'second', 3 => 'third' }
92
-
93
- def types_to_s(types)
94
- if types.length > 2
95
- types[0..-2].map { |t| type_with_article(t) }.join(', ') +
96
- ', or ' + type_with_article(types[-1])
97
- else
98
- types.map { |t| type_with_article(t) }.join(' or ')
99
- end
100
- end
101
-
102
- shared_examples 'argument types' do |expr, accepted_argument_types|
103
- accepted_argument_types.to_a.sort.each do |(idx, accepted_types)|
104
- type_str = types_to_s(accepted_types)
105
- it "raises an error if its #{POSITION_NAMES[idx]} argument is not #{type_str}" do
106
- accepted_types.each do |type|
107
- other_expr = expr.dup
108
- other_expr[idx] = KL_TYPE_EXAMPLES[type]
109
- expect {
110
- kl_eval("(#{other_expr.join(' ')})")
111
- }.to_not raise_error
112
- end
113
-
114
- rejected_types = KL_TYPE_EXAMPLES.keys - accepted_types
115
- rejected_types.each do |type|
116
- other_expr = expr.dup
117
- other_expr[idx] = KL_TYPE_EXAMPLES[type]
118
- expect {
119
- kl_eval("(#{other_expr.join(' ')})")
120
- }.to raise_error(Kl::Error, /is not a/)
121
- end
122
- end
123
- end
124
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Tail recursion' do
4
- it 'does not consume stack space for self tail calls' do
5
- kl_eval <<-EOS
6
- (defun count-down (X)
7
- (if (= X 0)
8
- success
9
- (count-down (- X 1))))
10
- EOS
11
- kl_eval('(count-down 10000)').should == :success
12
- end
13
-
14
- it 'does not consume stack space for mutually recursive tail calls' do
15
- kl_eval <<-EOS
16
- (defun even? (X)
17
- (if (= X 1)
18
- false
19
- (odd? (- X 1))))
20
- EOS
21
- kl_eval <<-EOS
22
- (defun odd? (X)
23
- (if (= X 1)
24
- true
25
- (even? (- X 1))))
26
- EOS
27
- kl_eval('(even? 100000)').should == true
28
- kl_eval('(odd? 100000)').should == false
29
- end
30
- end
data/lib/kl.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'kl/error'
2
- require 'kl/internal_error'
3
- require 'kl/empty_list'
4
- require 'kl/cons'
5
- require 'kl/absvector'
6
- require 'kl/reader'
7
- require 'kl/environment'
data/lib/kl/absvector.rb DELETED
@@ -1,12 +0,0 @@
1
- module Kl
2
- # Absvectors are just arrays. We give them their own subclass
3
- # to support the absvector? primitive.
4
- class Absvector < Array
5
- attr_reader :upper_limit
6
-
7
- def initialize(n)
8
- super(n, :"shen.fail!")
9
- @upper_limit = n
10
- end
11
- end
12
- end