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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4388a5a344cbc54d04a341a42a341cf05aae8ebc
4
- data.tar.gz: 2777d3e71e1f2f90a953487007f4c6b4fdcaf97a
3
+ metadata.gz: c457075dab1a292cac646bf9148aaafb79de2457
4
+ data.tar.gz: b8909a0fef1f820b121110a06394366a7c01c3a4
5
5
  SHA512:
6
- metadata.gz: 1655075e45839d973a8a5bc310cc7a8399ac155960261e968785932a1cb733082a15d084dd3ea669cfe28fbc64ec19b6af54c59e46542fef0b99489290a8491f
7
- data.tar.gz: be259a2837137dd278a3d8c6a9912df4051ed953a82805b5b138b72e1c7e7cd1e4dea991f0655ca63793ae68532025371a65ee67cdca8e276e8a551729b078b3
6
+ metadata.gz: 686bb28d207078c9e7e0a9ad38c058fe9ed7da9695a84adf4f51a85e58ca3870b90235ada593ae3c7ebdedfc641ac0649591dfa59ae9dc43b84b1f5607747de9
7
+ data.tar.gz: d767482519d1199ad6206f122fd0c1bd8211c155df994cdabbf5e9c7f2f5f6a616e7019e1d7d9886a775ffd1e72625d605c837286b6d4cd6dda6012884169092
data/.rspec CHANGED
@@ -0,0 +1 @@
1
+ -I ./lib -I ./shen/lib
data/.travis.yml CHANGED
@@ -1,5 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - jruby-19mode
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ env: "RUBY_THREAD_VM_STACK_SIZE=2097152"
7
+ script: "ruby bin/shen_test_suite.rb && rake"
8
+ matrix:
9
+ include:
10
+ - rvm: jruby-1.7.17
11
+ script: "ruby -J-Xss32m bin/shen_test_suite.rb && rake"
data/Gemfile CHANGED
@@ -1,6 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :development do
4
- gem 'rake', '~> 0.9'
5
- gem 'rspec', '~> 2.12.0'
6
- end
3
+ gemspec
data/HISTORY.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # ShenRuby Release History
2
2
 
3
+ ## 0.11.0 - January 15, 2014
4
+ ### Features
5
+ - KLambda implementation switched to [Klam](https://github.com/gregspurrier/klam). This has many implications, including:
6
+ - Significant performance increase. E.g., the Shen Test Suite now runs 2.5 times faster than with ShenRuby 0.10.0.
7
+ - Tail call optimization applies only to self tail calls
8
+ - The environment extends BasicObject rather than Object
9
+ - Shen functions are directly installed as methods on the ShenRuby::Shen instance.
10
+ - Many primitives are inlined.
11
+ - Primitives are less strict with respect to type errors, relying on the Shen type checker to do this work when type checking is enabled.
12
+ - E.g., `(+ "a" "b") no longer throws a type error
13
+
14
+ ### Breaking Changes
15
+ - Ruby->Shen interop has changed as a result of the switch to Klam and in preparation for more substantial Ruby<->Shen interop to come. Notably:
16
+ - Underscores in method names are no longer coerced to hyphens before invoking Shen functions. Use `__send__` to invoke Shen functions having names that are not valid Ruby method names.
17
+ - Ruby arrays are no longer automatically coerced to Shen lists and vice versa.
18
+
3
19
  ## 0.10.0 - September 19, 2014
4
20
  ### Features
5
21
  - Upgrade to Shen 16
data/MIT_LICENSE.txt CHANGED
@@ -3,7 +3,7 @@ the 'shen' directory, which is subject to its own license.
3
3
 
4
4
  -----
5
5
 
6
- Copyright (c) 2012-2013 Greg Spurrier
6
+ Copyright (c) 2012-2015 Greg Spurrier
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining
9
9
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -7,14 +7,14 @@ The ShenRuby project has two primary goals. The first is to be a low barrier-to-
7
7
 
8
8
  Second, ShenRuby aims to enable hybrid applications implemented using a combination of Ruby and Shen. Ruby methods should be able to invoke functions written in Shen and vice versa. Performance is a secondary part of this goal. It should be good enough that, for most tasks, the choice between Ruby and Shen is based primarily on which language is best suited for solving the problem at hand.
9
9
 
10
- ShenRuby 0.1.0 began to satisfy the first goal by providing a Shen REPL accessible from the command line. The second goal is more ambitious and is the subject of ongoing work beginning with the 0.2.0 release and leading up to the eventual 1.0.0 release.
10
+ ShenRuby 0.1.0 began to satisfy the first goal by providing a Shen REPL accessible from the command line. The second goal is more ambitious and is the subject of ongoing work leading up to the eventual 1.0.0 release.
11
11
 
12
12
  [![Build Status](https://travis-ci.org/gregspurrier/shen-ruby.png)](https://travis-ci.org/gregspurrier/shen-ruby)
13
13
 
14
14
  ## Installation
15
- NOTE: ShenRuby requires Ruby 1.9 language features. It has been tested with Ruby 1.9.3 and Ruby 2.0.0. It has been lightly tested with JRuby 1.7.8.
15
+ NOTE: ShenRuby requires Ruby 1.9 language features. It is tested with Ruby 2.0.0, 2.1.5, and 2.2.0. It has been lightly tested with JRuby 1.7.17. It is functional with Ruby 1.9.3, however its fixed stack size prevents it from passing the Shen Test Suite (see [Setting Stack Size](setting-stack-size) below).
16
16
 
17
- ShenRuby 0.10.0 is the current release. To install it as a gem, use the following command:
17
+ ShenRuby 0.11.0 is the current release. To install it as a gem, use the following command:
18
18
 
19
19
  gem install shen-ruby
20
20
 
@@ -23,19 +23,17 @@ ShenRuby 0.10.0 is the current release. To install it as a gem, use the followin
23
23
  Once the gem has been installed, the Shen REPL can be launched via the `srrepl` (short for ShenRuby REPL) command. For example:
24
24
 
25
25
  % srrepl
26
- Loading.... Completed in 7.04 seconds.
26
+ Loading.... Completed in 2.18 seconds.
27
27
 
28
28
  Shen 2010, copyright (C) 2010 Mark Tarver
29
29
  released under the Shen license
30
30
  www.shenlanguage.org, version 16
31
- running under Ruby, implementation: ruby 2.0.0
32
- port 0.10.0 ported by Greg Spurrier
31
+ running under Ruby, implementation: ruby 2.2.0
32
+ port 0.11.0 ported by Greg Spurrier
33
33
 
34
34
 
35
35
  (0-)
36
36
 
37
- Please be patient: the Shen REPL takes a while to load (about 7 seconds on a 2.66 GHz MacBook Pro). This will be addressed in future releases.
38
-
39
37
  The `(0-)` seen above is the Shen REPL prompt. The number in the prompt increases after each expression that is entered.
40
38
 
41
39
  Here is an example of defining a recursive factorial function via the REPL and trying it out:
@@ -106,31 +104,34 @@ More commonly, though, `eval_string` is used with Shen `define` expressions to e
106
104
 
107
105
  ### Invoking Shen Functions from Ruby
108
106
 
109
- A better way to invoke most Shen functions from Ruby is to simply invoke the corresponding method on the Shen object. If the Shen function's name includes a hyphen, use an underscore instead.
110
-
111
- For example, to use the `fizz-buzz` function defined in the previous section to compute the first 20 Fizz Buzz values:
107
+ Shen functions are instance methods of the ShenRuby::Shen environment object. Functions having names that are valid Ruby method names may be invoked directly:
112
108
 
113
- (1..20).map { |x| shen.fizz_buzz(x) }
114
- # => ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "Fizz Buzz", "16", "17", "Fizz", "19", "Buzz"]
109
+ shen.cn("Hello, ", "Shen!")
110
+ # => "Hello, Shen!"
115
111
 
116
- The above example uses Ruby's `map` function, but could also have used Shen's version, relying on ShenRuby's interop features to coerce Ruby arrays to and from Shen lists:
112
+ If the Shen function's name is not a valid Ruby method name--e.g. it includes a hyphen--it can be invoked via `__send__`:
117
113
 
118
- shen.map(:fizz_buzz, (1..20).to_a)
119
- # => ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "Fizz Buzz", "16", "17", "Fizz", "19", "Buzz"]
114
+ shen.__send__('fizz-buzz', 15)
115
+ # => "Fizz Buzz"
120
116
 
121
- Note that the Ruby symbol `:fizz_buzz` is automatically coerced to the Shen symbol `fizz-buzz` so that refer to the function defined above.
117
+ Ruby arrays must be converted to Shen lists or vectors before passing to Shen. Here is an example of converting an array to a list, invoking Shen's `map` function, and converting the resulting list back to a Ruby array:
122
118
 
123
- As a final example, Ruby functions may be passed as arguments to higher-order Shen functions:
119
+ ShenRuby.list_to_array(shen.map(:'fizz-buzz', ShenRuby.array_to_list((1..20).to_a)))
120
+ => ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "Fizz Buzz", "16", "17", "Fizz", "19", "Buzz"]
124
121
 
125
- shen.map(lambda {|x| x * x}, [1, 2, 3, 4, 5])
126
- # => [1, 4, 9, 16, 25]
122
+ The equivalent conversion functions for vectors are `ShenRuby.vector_to_list` and `ShenRuby.list_to_vector`.
127
123
 
128
124
  #### Caveats
129
- Shen function invocation via methods on the Shen object only works for normal functions. It will not work for special forms like `define`.
125
+ Shen function invocation via methods on the Shen object only works for normal functions. It will not work for special forms like `define` or macros.
126
+
127
+ ## Setting Stack Size
128
+ Some operations in Shen, notably type checking of complicated types, require more stack space than is available by default in Ruby. If your program encounters a stack overflow, you can increase Ruby's stack size through the following methods.
130
129
 
131
- The array<->list and underscore<->hyphen automatic coercions do not take effect for Ruby functions that are added to the Shen environment or for the K Lambda [primitives](http://www.shenlanguage.org/documentation/shendoc.htm#The%20Primitive%20Functions%20of%20K%20Lambda) that form the basis of Shen. In practice, this should not be much of a limitation, but it is hoped that this restriction will be lifted in the future.
130
+ ### Ruby
131
+ Beginning in Ruby 2.0.0, the MRI stack size can be overridden via the `RUBY_THREAD_VM_STACK_SIZE` environment variable. A value of 2097152 is sufficient for the Shen Test Suite to pass under both OS X and Linux.
132
132
 
133
- Shen functions cannot be passed as arguments to functions defined in Ruby. This restriction will be removed in the future.
133
+ ### JRuby
134
+ JRuby uses the JVM's stack. It can be increased via the `-J-Xss` command line argument. A value of 32m (i.e., `-J-Xss32m`) is sufficient for the Shen Test Suite to pass under both OS X and Linux.
134
135
 
135
136
  ## Shen Resources
136
137
 
@@ -151,10 +152,8 @@ The following features and improvements are among those planned for ShenRuby as
151
152
  - Support for command-line Shen scripts that under ShenRuby
152
153
  - Support for Rubinius
153
154
  - Thread-safe `ShenRuby::Shen` instances
154
- - Improved performance
155
155
 
156
156
  ## Known Limitations
157
- - The "Qi interpreter - chapter 13" test case in the Shen Test Suite and some of the benchmarks are currently failing with stack overflow errors.
158
157
  - ShenRuby fails with a stack overflow when run under cygwin on Windows ([Issue #3](https://github.com/gregspurrier/shen-ruby/issues/3)). The Ruby environment installed by [RubyInstaller](http://rubyinstaller.org/), however, is capable of running ShenRuby. It is the recommended environment for running ShenRuby on Windows until the stack overflow issues seen on cygwin can be addressed.
159
158
  - ShenRuby fails to load under Rubinius ([Issue #7])(https://github.com/gregspurrier/shen-ruby/issues/7)].
160
159
 
@@ -169,4 +168,4 @@ Shen and ShenRuby are released under the Shen License. A copy of the Shen Licens
169
168
 
170
169
  The implementation of Shen, which is found in the [shen/release](https://github.com/gregspurrier/shen-ruby/tree/master/shen) directory, is Copyright (c) 2010-2014 Mark Tarver and may only be used in accordance with the Shen License.
171
170
 
172
- The remainder of the code for ShenRuby is Copyright(c) 2012-2014 Greg Spurrier. It may be used outside of the context of ShenRuby under the terms of the MIT License. A copy of the MIT License may be found in [MIT_LICENSE.txt](https://github.com/gregspurrier/shen-ruby/blob/master/MIT_LICENSE.txt).
171
+ The remainder of the code for ShenRuby is Copyright(c) 2012-2015 Greg Spurrier. It may be used outside of the context of ShenRuby under the terms of the MIT License. A copy of the MIT License may be found in [MIT_LICENSE.txt](https://github.com/gregspurrier/shen-ruby/blob/master/MIT_LICENSE.txt).
data/Rakefile CHANGED
@@ -3,14 +3,8 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  SHENRUBY_ROOT = File.expand_path(File.dirname(__FILE__))
5
5
 
6
- # Run implementation specs
7
6
  RSpec::Core::RakeTask.new(:spec)
8
-
9
- # Run K Lambda specs
10
- RSpec::Core::RakeTask.new(:k_lambda_spec) do |t|
11
- t.rspec_opts = '-I k_lambda_spec'
12
- t.pattern = 'k_lambda_spec/**/*_spec.rb'
13
- end
7
+ task :default => :spec
14
8
 
15
9
  # Import Shen Release
16
10
  RELEASE_DIR = File.join(SHENRUBY_ROOT, 'shen/release')
@@ -53,7 +47,7 @@ namespace :shen do
53
47
 
54
48
  src_paths = Dir.glob(File.join(src_root, '**/*'))
55
49
  src_dirs, src_files = src_paths.partition { |p| File.directory?(p) }
56
-
50
+
57
51
  mkdir_p dst_root
58
52
  src_dirs.each { |dir| mkdir_p dst_path(src_root, dir, dst_root) }
59
53
  src_files.each { |file| cp file, dst_path(src_root, file, dst_root) }
@@ -72,7 +66,7 @@ namespace :shen do
72
66
  end
73
67
  end
74
68
  end
75
-
69
+
76
70
  task :k_lambda => [:unzip, RELEASE_DIR] do
77
71
  import_dir('K Lambda')
78
72
  end
@@ -88,5 +82,3 @@ namespace :shen do
88
82
  end
89
83
  end
90
84
  end
91
-
92
- task :default => [:spec, :k_lambda_spec]
@@ -4,6 +4,18 @@ $LOAD_PATH << File.expand_path('../../shen/lib', __FILE__)
4
4
  require 'shen_ruby'
5
5
 
6
6
  shen = ShenRuby::Shen.new
7
- shen.__eval(Kl::Cons.list([:cd, "shen/release/test_programs"]))
8
- shen.__eval(Kl::Cons.list([:load, "README.shen"]))
9
- shen.__eval(Kl::Cons.list([:load, "tests.shen"]))
7
+ shen.cd('shen/release/test_programs')
8
+ shen.load('README.shen')
9
+
10
+ # Override y-on-n? so that the script continues on error.
11
+ # We must use KLambda's defun to circumvent Shen's protection
12
+ # against redefining system functions.
13
+ shen.eval_string('(defun y-or-n? (Ignored) true)')
14
+
15
+ # Reset the pass/fail counters now and then make reset a no-op
16
+ # so that we can query it at the end of the test run.
17
+ shen.reset
18
+ shen.eval_string('(define reset -> true)')
19
+
20
+ shen.load('tests.shen')
21
+ exit(1) unless shen.value(:"test-harness.*failed*") == 0
data/bin/srrepl CHANGED
@@ -18,22 +18,20 @@ now = Time.now.to_f
18
18
  puts ". Completed in %0.2f seconds.\n" % (now - start)
19
19
 
20
20
  # Now that the Shen environment is loaded, repurpose the SIGINT
21
- # handler to interrupt the current execution.
22
- class ReplInterrupt < StandardError; end
21
+ # handler to interrupt the current execution. Subclass Interrupt
22
+ # so that the exception is not caught by trap-error.
23
+ class ReplInterrupt < Interrupt; end
23
24
  Signal.trap("INT") { raise ReplInterrupt }
24
25
 
25
26
  # Launch the REPL
26
27
  command = :"shen.shen"
27
28
  begin
28
- shen.__eval(Kl::Cons.list([command]))
29
- rescue StandardError => e
30
- # K Lambda simple errors are already handled by the Shen REPL. Therefore
31
- # this must be another type of exception. Print it as such and reenter
32
- # the REPL without re-display the initial credits.
29
+ shen.__send__ command
30
+ rescue ReplInterrupt, SystemStackError => e
33
31
  if e.kind_of? ReplInterrupt
34
32
  puts "Execution interrupted. If you are trying to exit the REPL, use (quit)."
35
33
  else
36
- puts "Ruby exception: #{e.message}"
34
+ puts "Stack overflow"
37
35
  end
38
36
  command = :"shen.loop"
39
37
  retry
data/lib/shen_ruby.rb CHANGED
@@ -1,5 +1,10 @@
1
- require 'kl'
1
+ require 'klam'
2
2
  require 'shen_ruby/version'
3
+ require 'shen_ruby/converters'
4
+
5
+ module ShenRuby
6
+ extend ShenRuby::Converters
7
+ end
3
8
 
4
9
  # The following file is a derivative of the Shen release packages with ShenRuby
5
10
  # and it located under the shen directory hierarchy to make the license
@@ -0,0 +1,23 @@
1
+ module ShenRuby
2
+ module Converters
3
+ include Klam::Converters::List
4
+
5
+ def array_to_list(a)
6
+ arrayToList(a)
7
+ end
8
+
9
+ def list_to_array(l)
10
+ listToArray(l)
11
+ end
12
+
13
+ def array_to_vector(a)
14
+ v = Klam::Absvector.new(a)
15
+ v.unshift(a.size)
16
+ v
17
+ end
18
+
19
+ def vector_to_array(v)
20
+ Array.new(v.slice(1,v[0]))
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module ShenRuby
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  end
data/shen-ruby.gemspec CHANGED
@@ -16,7 +16,10 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.required_ruby_version = ">= 1.9.3"
18
18
 
19
- s.add_development_dependency "rspec", "~> 2.12"
19
+ s.add_runtime_dependency 'klam', '0.0.2', '0.0.2'
20
+
21
+ s.add_development_dependency 'rake', '~> 10.4.2', '>= 10.4.2'
22
+ s.add_development_dependency 'rspec', '~> 3.1', '>= 3.1.0'
20
23
 
21
24
  git_files = `git ls-files`.split("\n") rescue ''
22
25
  s.files = git_files
@@ -5,7 +5,7 @@
5
5
  # software, to distribute these applications in source or binary form,
6
6
  # and to charge monies for them as he sees fit and in concordance with
7
7
  # the laws of the land subject to the following license.
8
- #
8
+ #
9
9
  # 1. The license applies to all the software and all derived software
10
10
  # and must appear on such.
11
11
  #
@@ -63,58 +63,63 @@
63
63
 
64
64
  module ShenRuby
65
65
  # Instances of the ShenRuby::Shen class provide a Shen environment
66
- # running within ShenRuby's K Lambda implementation.
67
- class Shen < Kl::Environment
66
+ # running within a Klam environment
67
+ class Shen < Klam::Environment
68
68
  def initialize
69
69
  super
70
70
 
71
71
  # Set the global variables
72
72
  set("*language*".to_sym, "Ruby")
73
- set("*implementation*".to_sym, "#{RUBY_ENGINE} #{RUBY_VERSION}")
74
- set("*release*".to_sym, RUBY_VERSION)
75
- set("*port*".to_sym, ShenRuby::VERSION)
73
+ set("*implementation*".to_sym, "#{::RUBY_ENGINE} #{::RUBY_VERSION}")
74
+ set("*release*".to_sym, ::RUBY_VERSION)
75
+ set("*port*".to_sym, ::ShenRuby::VERSION)
76
76
  set("*porters*".to_sym, "Greg Spurrier")
77
- set("*home-directory*".to_sym, Dir.pwd)
78
- set("*stinput*".to_sym, STDIN)
79
- set("*stoutput*".to_sym, STDOUT)
80
-
77
+ set("*home-directory*".to_sym, ::Dir.pwd)
78
+ set("*stinput*".to_sym, ::STDIN)
79
+ set("*stoutput*".to_sym, ::STDOUT)
81
80
 
82
81
  # Load the K Lambda files
83
- kl_root = File.expand_path('../../../release/k_lambda', __FILE__)
82
+ kl_root = ::File.expand_path('../../../release/k_lambda', __FILE__)
84
83
  %w(toplevel core sys).each do |kl_filename|
85
- Kl::Environment.load_file(self, File.join(kl_root, kl_filename + ".kl"))
84
+ ::ShenRuby::Shen.load_file(self, ::File.join(kl_root, kl_filename + ".kl"))
86
85
  end
87
86
 
88
87
  # Overrides
89
88
  class << self
90
- # Kl::Absvector.new already initializes every element, so we can
91
- # use a simpler version of vector
92
- def vector(n)
93
- v = ::Kl::Absvector.new(n + 1) #, fail)
94
- v[0] = n
95
- v
96
- end
97
-
98
89
  # Give a way to bail out
99
- define_method 'quit' do
90
+ def quit
100
91
  ::Kernel.exit(0)
101
92
  end
102
93
 
103
- # For debugging the compiler
104
- define_method 'set-dump-code' do |val|
105
- @dump_code = val
106
- end
107
-
108
94
  # Add a way to evaluate strings, intended for use with Ruby interop.
109
95
  # Returns the result of the last expression evaluated.
110
- # Based on the implementation of read-file in reader.shen
111
96
  def eval_string(s)
112
- forms = __apply(:"read-from-string", [s])
97
+ forms = __send__(:"read-from-string", s)
113
98
  result = nil
114
- forms.each { |f| result = __apply(:eval, [f]) }
99
+ while forms
100
+ result = eval(head(forms))
101
+ forms = tail(forms)
102
+ end
115
103
  result
116
104
  end
117
105
  alias_method :"eval-string", :eval_string
106
+
107
+ # The performance of `element?` is critical
108
+ def element?(x, l)
109
+ while l
110
+ return true if l.hd == x
111
+ l = l.tl
112
+ end
113
+ return false
114
+ rescue => e
115
+ __send(:"shen.sys-error", :element?)
116
+ end
117
+
118
+ def vector(n)
119
+ v = ::Klam::Absvector.new(n + 1, :"shen.fail!")
120
+ v[0] = n
121
+ v
122
+ end
118
123
  end
119
124
 
120
125
  # Load the rest of the K Lambda files
@@ -122,13 +127,24 @@ module ShenRuby
122
127
  reader prolog track load writer
123
128
  macros declarations t-star types
124
129
  ).each do |kl_filename|
125
- Kl::Environment.load_file(self, File.join(kl_root, kl_filename + ".kl"))
130
+ ::ShenRuby::Shen.load_file(self, ::File.join(kl_root, kl_filename + ".kl"))
126
131
  end
127
132
 
128
133
  # Give type signatures to the new functions added above
129
- declare :quit, [:'-->', :unit]
130
- declare :eval_string, [:string, :'-->', :unit]
131
- declare :'eval-string', [:string, :'-->', :unit]
134
+ declare :quit, cons(:"-->", cons(:unit, nil))
135
+ declare :eval_string, cons(:string, cons(:"-->", cons(:unit, nil)))
136
+ declare :"eval-string", cons(:string, cons(:"-->", cons(:unit, nil)))
137
+ end
138
+
139
+ class << self
140
+ def load_file(env, path)
141
+ ::File.open(path, 'r') do |file|
142
+ reader = ::Klam::Reader.new(file)
143
+ while form = reader.next
144
+ env.__send__(:"eval-kl", form)
145
+ end
146
+ end
147
+ end
132
148
  end
133
149
  end
134
150
  end