shen-ruby 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +5 -0
- data/README.md +62 -4
- data/lib/shen_ruby/rb.shen +139 -0
- data/lib/shen_ruby/shen_ruby.shen +26 -0
- data/lib/shen_ruby/version.rb +1 -1
- data/shen/lib/shen_ruby/shen.rb +11 -1
- data/shen-ruby.gemspec +1 -1
- data/spec/shen_ruby/converters_spec.rb +1 -13
- data/spec/shen_ruby/interop_spec.rb +106 -0
- data/spec/spec_helper.rb +18 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cc8006d7f3fac61a20da31b9abe918d51ccfc56
|
4
|
+
data.tar.gz: bb145ab8f07ab6ede1cb1eef9ff9ea5aa219d31a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a3c09ebb9aaf85a1df12b949ea8d820f3924aa7034dad4c425af651d1e898323e2c725e067ded89e81e441abe7d7624e37a53f9e8438af52df30044f0dd3b3f
|
7
|
+
data.tar.gz: 57339d8ecf2d9cc0e2bcc2e452235e15eb9ce70f4d36244a880cd79cc55706ade719bcc54ef1a9ee9f064964ac77ae63e7fd1ee7da69b38c380ad3eb453e1821
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# ShenRuby Release History
|
2
2
|
|
3
|
+
## 0.12.0 - January 31, 2014
|
4
|
+
### Features
|
5
|
+
- Shen -> Ruby interop
|
6
|
+
- See README.md for details
|
7
|
+
|
3
8
|
## 0.11.0 - January 15, 2014
|
4
9
|
### Features
|
5
10
|
- KLambda implementation switched to [Klam](https://github.com/gregspurrier/klam). This has many implications, including:
|
data/README.md
CHANGED
@@ -14,7 +14,7 @@ ShenRuby 0.1.0 began to satisfy the first goal by providing a Shen REPL accessib
|
|
14
14
|
## Installation
|
15
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.
|
17
|
+
ShenRuby 0.12.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,13 +23,13 @@ ShenRuby 0.11.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 2.
|
26
|
+
Loading.... Completed in 2.62 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
31
|
running under Ruby, implementation: ruby 2.2.0
|
32
|
-
port 0.
|
32
|
+
port 0.12.0 ported by Greg Spurrier
|
33
33
|
|
34
34
|
|
35
35
|
(0-)
|
@@ -124,6 +124,65 @@ The equivalent conversion functions for vectors are `ShenRuby.vector_to_list` an
|
|
124
124
|
#### Caveats
|
125
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
126
|
|
127
|
+
### Invoking Ruby from Shen
|
128
|
+
By convention, functionality for interacting with Shen's host platform is placed within a package named with the host language's file extension. Therefore the Ruby interop forms begin with `rb.`.
|
129
|
+
|
130
|
+
#### Constant References
|
131
|
+
Ruby constants, including classes and modules, are referenced by prefixing them with `rb.#` and replacing `::` with `#`. For example:
|
132
|
+
|
133
|
+
rb.#Hash
|
134
|
+
rb.#Math#PI
|
135
|
+
rb.#RUBY_VERSION
|
136
|
+
|
137
|
+
### Method Invocation
|
138
|
+
Ruby method invocation uses a syntax inspired by Clojure and looks similar to normal function application. The method name, prefixed with `rb.`, is used as the operator and the receiver is the first operand. Any additional operands are passed to the method as its arguments. For example:
|
139
|
+
|
140
|
+
(rb.reverse "hello")
|
141
|
+
(rb.prepend "bye" "good")
|
142
|
+
(rb.sqrt rb.#Math 4)
|
143
|
+
|
144
|
+
The `[]` and `[]=` method names used for accessing and manipulating Ruby arrays and hashes cannot be used directly because the Shen reader interprets `[]` as an empty list. Use `rb.<-` and `rb.->` instead. These mimic Shen's `<-vector` and `vector->` operations on vectors.
|
145
|
+
|
146
|
+
#### Invoking Class Methods
|
147
|
+
The last example above invokes the `Math` module's `sqrt` class method. A shorter form is provided as a convenience:
|
148
|
+
|
149
|
+
(rb.#Math.sqrt 4)
|
150
|
+
|
151
|
+
Invocations of `Kernel` class methods can be further shortened by prefixing the method's name with `rb.#`. The following are all equivalent:
|
152
|
+
|
153
|
+
(rb.require rb.#Kernel "digest/md5")
|
154
|
+
(rb.#Kernel.require "digest/md5")
|
155
|
+
(rb.#require "digest/md5")
|
156
|
+
|
157
|
+
#### Hash Parameters
|
158
|
+
Many Ruby methods take a `Hash` object as their final parameter. Ruby provides a special syntax for this which is echoed by ShenRuby. Argument triples of the form 'key `=>` value' are poured into `Hash` and passed as the method's final argument. For example:
|
159
|
+
|
160
|
+
(rb.#puts a => "hello" b => 37)
|
161
|
+
|
162
|
+
As in Ruby, the key-arrow-value triples must be the final normal arguments to the method.
|
163
|
+
|
164
|
+
#### Block Parameters
|
165
|
+
In addition to normal arguments, Ruby methods may also accept blocks. A block argument in ShenRuby is denoted by `&n`--where `n` is the arity of the block expected by the method--followed by a function. Arities from 0 to 5 are supported. If the arity is one, `&` may be used instead of `&1`. The arity marker and the block function must be the last two elements of the argument list.
|
166
|
+
|
167
|
+
For example, to print each character of a string on a separate line using Shen's `pr` and `nl` system functions:
|
168
|
+
|
169
|
+
(rb.each_char "hello" &1 (/. X (do (pr X) (nl))))
|
170
|
+
|
171
|
+
Or, to sum the elements of a list using Ruby's `Enumerable#reduce`:
|
172
|
+
|
173
|
+
(rb.reduce [1 2 3] &2 +)
|
174
|
+
|
175
|
+
This use of `reduce` is possible because Shen's list and vector types are enumerable in ShenRuby.
|
176
|
+
|
177
|
+
Please note that these two examples can--and, in practice, should--be easily implemented in Shen without resorting to Ruby methods. They are here simply to demonstrate ShenRuby's syntax for block arguments.
|
178
|
+
|
179
|
+
#### Type Coercion
|
180
|
+
Shen booleans, numbers, strings, and symbols are implemented using the corresponding Ruby classes and no coercion is required.
|
181
|
+
|
182
|
+
Shen's list and vector types both implement the Ruby `Enumerable` interface and may be passed directly as arguments to methods expecting instances of `Enumerable`. When an `Array` is required, they can be coerced using `rb.to_a`.
|
183
|
+
|
184
|
+
ShenRuby provides two system functions for coercing Ruby `Enumerable` instances to Shen lists and vectors. These are `rb-to-l` and `rb-to-v`, respectively.
|
185
|
+
|
127
186
|
## Setting Stack Size
|
128
187
|
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.
|
129
188
|
|
@@ -148,7 +207,6 @@ The following resources may be helpful for those wanting to learn more about the
|
|
148
207
|
|
149
208
|
The following features and improvements are among those planned for ShenRuby as it approaches its 1.0 release:
|
150
209
|
|
151
|
-
- Ability to call Ruby methods directly from Shen
|
152
210
|
- Support for command-line Shen scripts that under ShenRuby
|
153
211
|
- Support for Rubinius
|
154
212
|
- Thread-safe `ShenRuby::Shen` instances
|
@@ -0,0 +1,139 @@
|
|
1
|
+
\\ Ruby Interoperability
|
2
|
+
\\
|
3
|
+
\\ The rb package provides interoperability with the host Ruby
|
4
|
+
\\ environment.
|
5
|
+
|
6
|
+
(package rb []
|
7
|
+
|
8
|
+
\\\\ Parsing of rb.<const-or-method> symbols
|
9
|
+
|
10
|
+
(defcc <ruby-extension>
|
11
|
+
<rb-dot> "#" <const-name> "." <method-name>
|
12
|
+
:= [class-method <const-name> <method-name>];
|
13
|
+
<rb-dot> "#" <const-name> := [constant <const-name>];
|
14
|
+
<rb-dot> "#" <method-name> := [class-method "Kernel" <method-name>];
|
15
|
+
<rb-dot> <method-name> := [instance-method <method-name>];)
|
16
|
+
|
17
|
+
(defcc <rb-dot> "r" "b" "." := skip;)
|
18
|
+
|
19
|
+
(defcc <const-name>
|
20
|
+
<const-segment> "#" <const-name> := (@s <const-segment> "::" <const-name>);
|
21
|
+
<const-segment> := <const-segment>;)
|
22
|
+
|
23
|
+
(defcc <const-segment>
|
24
|
+
Cap <const-segment-tail> := (cn Cap <const-segment-tail>)
|
25
|
+
where (capital? Cap);)
|
26
|
+
|
27
|
+
(defcc <const-segment-tail>
|
28
|
+
<char> <const-segment-tail> := (cn <char> <const-segment-tail>);
|
29
|
+
<e> := "";)
|
30
|
+
|
31
|
+
(defcc <method-name>
|
32
|
+
"-" ">" := "[]=";
|
33
|
+
"<" "-" := "[]";
|
34
|
+
<char> <method-name> := (cn <char> <method-name>);
|
35
|
+
<char> := <char>;)
|
36
|
+
|
37
|
+
(defcc <char>
|
38
|
+
C := C where (not (or (= C ".") (= C "#"))))
|
39
|
+
|
40
|
+
(define capital?
|
41
|
+
S -> (element? S [($ ABCDEFGHIJKLMNOPQRSTUVWXYZ)]))
|
42
|
+
|
43
|
+
\\\\ Parsing of method argument lists
|
44
|
+
|
45
|
+
(defcc <method-invocation>
|
46
|
+
Receiver Method <normal-args> <block-args> :=
|
47
|
+
[rb-send-block Receiver Method | (append <block-args> <normal-args>)];
|
48
|
+
Receiver Method <normal-args> :=
|
49
|
+
[rb-send Receiver Method | <normal-args>];)
|
50
|
+
|
51
|
+
(defcc <normal-args>
|
52
|
+
<kv-pairs> := [(make-hash-constructor <kv-pairs>)];
|
53
|
+
<arg> <normal-args> := [<arg> | <normal-args>];
|
54
|
+
<e> := [];)
|
55
|
+
|
56
|
+
(defcc <kv-pairs>
|
57
|
+
<key> <arrow> <val> <kv-pairs> := [[<key> <val>] | <kv-pairs>];
|
58
|
+
<key> <arrow> <val> := [[<key> <val>]];)
|
59
|
+
|
60
|
+
(defcc <key>
|
61
|
+
<arg> := <arg>;)
|
62
|
+
|
63
|
+
(defcc <arrow>
|
64
|
+
Arrow := Arrow where (= Arrow (intern "=>"));)
|
65
|
+
|
66
|
+
(defcc <val>
|
67
|
+
<arg> := <arg>;)
|
68
|
+
|
69
|
+
(defcc <arg>
|
70
|
+
Sym := Sym where (not (or (= Sym (intern "=>"))
|
71
|
+
(and (symbol? Sym)
|
72
|
+
(= (hdstr (str Sym)) "&"))));)
|
73
|
+
|
74
|
+
(defcc <block-args>
|
75
|
+
<arity-marker> Expr := [<arity-marker> Expr];)
|
76
|
+
|
77
|
+
(defcc <arity-marker>
|
78
|
+
X := 1 where (= X (intern "&"));
|
79
|
+
X := 0 where (= X (intern "&0"));
|
80
|
+
X := 1 where (= X (intern "&1"));
|
81
|
+
X := 2 where (= X (intern "&2"));
|
82
|
+
X := 3 where (= X (intern "&3"));
|
83
|
+
X := 4 where (= X (intern "&4"));
|
84
|
+
X := 5 where (= X (intern "&5"));)
|
85
|
+
|
86
|
+
(define make-hash-constructor
|
87
|
+
Pairs -> (let Temp (gensym (protect Hash))
|
88
|
+
[let Temp [rb-send [rb-const "Hash"] "new"]
|
89
|
+
[do | (make-hash-load-exprs Pairs Temp)]]))
|
90
|
+
|
91
|
+
(define make-hash-load-exprs
|
92
|
+
[] Hash -> [Hash]
|
93
|
+
[[Key Val] | Pairs] Hash -> [[rb-send Hash "[]=" Key Val] |
|
94
|
+
(make-hash-load-exprs Pairs Hash)])
|
95
|
+
|
96
|
+
\\\\ The macros that make the magic
|
97
|
+
|
98
|
+
(define parse-ruby-extension
|
99
|
+
RbExt -> (trap-error (compile <ruby-extension> (explode RbExt))
|
100
|
+
(/. _ (error
|
101
|
+
(make-string "Invalid Ruby reference: ~A"
|
102
|
+
RbExt)))))
|
103
|
+
|
104
|
+
(define compile-method-invocation
|
105
|
+
Receiver Method Args ->
|
106
|
+
(trap-error (compile <method-invocation> [Receiver Method | Args])
|
107
|
+
(/. _ (error
|
108
|
+
(make-string
|
109
|
+
"Invalid argument syntax for Ruby method '~A': ~A"
|
110
|
+
Method Args)))))
|
111
|
+
|
112
|
+
(define expand-method-invocation
|
113
|
+
[instance-method Method] [] ->
|
114
|
+
(error (make-string "Ruby instance method '~A' has no receiver"
|
115
|
+
Method))
|
116
|
+
[instance-method Method] [Receiver | Args] ->
|
117
|
+
(compile-method-invocation Receiver Method Args)
|
118
|
+
[class-method Class Method] Args ->
|
119
|
+
(compile-method-invocation [rb-const Class] Method Args))
|
120
|
+
|
121
|
+
(define expand-constant-reference
|
122
|
+
[constant Const] -> [rb-const Const]
|
123
|
+
\\ Bail out and give the instance method rules a shot
|
124
|
+
_ -> (fail))
|
125
|
+
|
126
|
+
\\ This function is extremely performance critical because it is used in
|
127
|
+
\\ the guard expressions of the macro below.
|
128
|
+
(define ruby-extension?
|
129
|
+
RbExt -> (and (rb-send RbExt "instance_of?" (rb-const "Symbol"))
|
130
|
+
(rb-send (rb-send RbExt "to_s") "start_with?" "rb.")))
|
131
|
+
|
132
|
+
(defmacro desugar-ruby-extensions
|
133
|
+
[Method | Args] -> (expand-method-invocation (parse-ruby-extension Method)
|
134
|
+
Args)
|
135
|
+
where (ruby-extension? Method)
|
136
|
+
Const <- (expand-constant-reference (parse-ruby-extension Const))
|
137
|
+
where (ruby-extension? Const))
|
138
|
+
|
139
|
+
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
(package shen-ruby [rb-to-l rb-to-v]
|
2
|
+
|
3
|
+
\\ Convert a Ruby Enumerable to a Shen vector
|
4
|
+
(define rb-to-l
|
5
|
+
Enum -> (reverse (rb.reduce Enum [] &2 (/. L X (cons X L))))
|
6
|
+
where (rb.kind_of? Enum rb.#Enumerable)
|
7
|
+
X -> (error (make-string "'~A' is not a Ruby Enumerable" X)))
|
8
|
+
|
9
|
+
(systemf rb-to-l)
|
10
|
+
|
11
|
+
\\ Convert a Ruby Enumerable to a Shen vector
|
12
|
+
(define rb-to-v
|
13
|
+
Enum -> (let Array (rb.to_a Enum)
|
14
|
+
Size (rb.size Array)
|
15
|
+
Vector (vector Size)
|
16
|
+
(rb-to-v-helper Array Vector Size))
|
17
|
+
X -> (error (make-string "'~A' is not a Ruby Enumerable" X)))
|
18
|
+
|
19
|
+
(systemf rb-to-v)
|
20
|
+
|
21
|
+
(define rb-to-v-helper
|
22
|
+
A V 0 -> V
|
23
|
+
A V Index -> (do (vector-> V Index (rb.<- A (- Index 1)))
|
24
|
+
(rb-to-v-helper A V (- Index 1))))
|
25
|
+
|
26
|
+
)
|
data/lib/shen_ruby/version.rb
CHANGED
data/shen/lib/shen_ruby/shen.rb
CHANGED
@@ -125,7 +125,7 @@ module ShenRuby
|
|
125
125
|
# Load the rest of the K Lambda files
|
126
126
|
%w(sequent yacc
|
127
127
|
reader prolog track load writer
|
128
|
-
macros declarations t-star
|
128
|
+
macros declarations types t-star
|
129
129
|
).each do |kl_filename|
|
130
130
|
::ShenRuby::Shen.load_file(self, ::File.join(kl_root, kl_filename + ".kl"))
|
131
131
|
end
|
@@ -134,6 +134,16 @@ module ShenRuby
|
|
134
134
|
declare :quit, cons(:"-->", cons(:unit, nil))
|
135
135
|
declare :eval_string, cons(:string, cons(:"-->", cons(:unit, nil)))
|
136
136
|
declare :"eval-string", cons(:string, cons(:"-->", cons(:unit, nil)))
|
137
|
+
|
138
|
+
systemf :"rb-const"
|
139
|
+
systemf :"rb-send"
|
140
|
+
systemf :"rb-send-block"
|
141
|
+
|
142
|
+
old_hush = value(:"*hush*")
|
143
|
+
set :"*hush*", true
|
144
|
+
load ::File.expand_path('../../../../lib/shen_ruby/rb.shen', __FILE__)
|
145
|
+
load ::File.expand_path('../../../../lib/shen_ruby/shen_ruby.shen', __FILE__)
|
146
|
+
set :"*hush*", old_hush
|
137
147
|
end
|
138
148
|
|
139
149
|
class << self
|
data/shen-ruby.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
|
17
17
|
s.required_ruby_version = ">= 1.9.3"
|
18
18
|
|
19
|
-
s.add_runtime_dependency 'klam', '0.0.
|
19
|
+
s.add_runtime_dependency 'klam', '0.0.5', '0.0.5'
|
20
20
|
|
21
21
|
s.add_development_dependency 'rake', '~> 10.4.2', '>= 10.4.2'
|
22
22
|
s.add_development_dependency 'rspec', '~> 3.1', '>= 3.1.0'
|
@@ -1,18 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'Ruby <-> Shen type converters' do
|
4
|
-
before :all do
|
5
|
-
@shen = ShenRuby::Shen.new
|
6
|
-
end
|
7
|
-
|
8
|
-
def eval_shen(str)
|
9
|
-
@shen.eval_string(str)
|
10
|
-
end
|
11
|
-
|
12
|
-
def expect_shen(str)
|
13
|
-
expect(eval_shen(str))
|
14
|
-
end
|
15
|
-
|
3
|
+
describe 'Ruby <-> Shen type converters', :type => :functional do
|
16
4
|
describe 'ShenRuby.array_to_list' do
|
17
5
|
it 'returns a Shen list containing the elements of the array' do
|
18
6
|
@shen.set(:"test-list", ShenRuby.array_to_list([1, 2, 3]))
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Shen -> Ruby interop', :type => :functional do
|
4
|
+
describe 'dereferencing constants' do
|
5
|
+
it 'supports classes' do
|
6
|
+
expect_shen('rb.#String').to eq(String)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'supports modules' do
|
10
|
+
expect_shen('rb.#Math').to eq(Math)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'supports constants' do
|
14
|
+
expect_shen('rb.#RUBY_VERSION').to eq(RUBY_VERSION)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'supports nested lookup' do
|
18
|
+
expect_shen('rb.#Math#PI').to eq(Math::PI)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'method invocation' do
|
23
|
+
describe 'instance methods' do
|
24
|
+
it 'invokes the named method on an object' do
|
25
|
+
expect_shen('(rb.reverse "abc")').to eq("cba")
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'passes additional arguments to the method' do
|
29
|
+
expect_shen('(rb.prepend "bar" "foo")').to eq("foobar")
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'supports [] and []= via rb.<- and rb.->' do
|
33
|
+
expect_shen(<<-EOSHEN).to eq('ruby')
|
34
|
+
(let Hash (rb.new rb.#Hash)
|
35
|
+
(do (rb.-> Hash "hello" "ruby")
|
36
|
+
(rb.<- Hash "hello")))
|
37
|
+
EOSHEN
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'provides sugar for hash parameters in final position' do
|
41
|
+
expect_shen(<<-EOSHEN).to eq('hello ruby')
|
42
|
+
(let Hash (rb.<- rb.#Hash key1 => "hello" key2 =>"ruby")
|
43
|
+
(@s (rb.<- Hash key1) " " (rb.<- Hash key2)))
|
44
|
+
EOSHEN
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'class method invocation' do
|
49
|
+
it 'is supported by a sugared syntax' do
|
50
|
+
expect_shen('(rb.#Math.sqrt 4)').to eq(2)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'kernel method invocation' do
|
55
|
+
it 'is supported by a sugared syntax' do
|
56
|
+
expect_shen('(rb.#sprintf "%0.3f" 0.1)').to eq('0.100')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'the optional block argument' do
|
61
|
+
it 'accepts abstractions' do
|
62
|
+
expect_shen('(rb.find [1 2 3] & (/. X (> X 1)))').to eq(2)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'accepts naked function names' do
|
66
|
+
expect_shen('(rb.find [1 "abc" foo] & string?)').to eq("abc")
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'accepts wrapped function names' do
|
70
|
+
expect_shen('(rb.find [1 "abc" foo] & (function string?))').to eq("abc")
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'supports arities other than 1' do
|
74
|
+
expect_shen('(rb.reduce [1 2 3] &2 (/. A X (+ A X)))').to eq(6)
|
75
|
+
expect_shen('(rb.reduce [1 2 3] &2 +)').to eq(6)
|
76
|
+
expect_shen('(rb.reduce [1 2 3] &2 (function +))').to eq(6)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "Shen's list type" do
|
82
|
+
it 'implements Enumerable' do
|
83
|
+
expect_shen('(rb.reduce [1 2 3] &2 +)').to eq(6)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "Shen's vector type" do
|
88
|
+
it 'implements Enumerable' do
|
89
|
+
expect_shen('(rb.reduce (@v 1 2 3 <>) &2 +)').to eq(6)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "Ruby Enumerable coercion" do
|
94
|
+
describe 'rb-to-l' do
|
95
|
+
it 'coerces Enumerable instances to lists' do
|
96
|
+
expect_shen('(= (rb-to-l (rb.to_a [1 2 3])) [1 2 3])').to be(true)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'rb-to-v' do
|
101
|
+
it 'coerces Enumerable instances to vectors' do
|
102
|
+
expect_shen('(= (rb-to-v (rb.to_a [1 2 3])) (@v 1 2 3 <>))').to be(true)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,19 @@
|
|
1
1
|
require 'shen_ruby'
|
2
|
+
|
3
|
+
module EvalShen
|
4
|
+
def eval_shen(str)
|
5
|
+
@shen.eval_string(str)
|
6
|
+
end
|
7
|
+
|
8
|
+
def expect_shen(str)
|
9
|
+
expect(eval_shen(str))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |cfg|
|
14
|
+
# Support eval_kl and friends in functional specs
|
15
|
+
cfg.include EvalShen, :type => :functional
|
16
|
+
cfg.before(:all, :type => :functional) do
|
17
|
+
@shen = ShenRuby::Shen.new
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shen-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Spurrier
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01
|
12
|
+
date: 2015-02-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: klam
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - '='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.0.
|
20
|
+
version: 0.0.5
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - '='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.0.
|
27
|
+
version: 0.0.5
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +86,8 @@ files:
|
|
86
86
|
- bin/srrepl
|
87
87
|
- lib/shen_ruby.rb
|
88
88
|
- lib/shen_ruby/converters.rb
|
89
|
+
- lib/shen_ruby/rb.shen
|
90
|
+
- lib/shen_ruby/shen_ruby.shen
|
89
91
|
- lib/shen_ruby/version.rb
|
90
92
|
- shen-ruby.gemspec
|
91
93
|
- shen/README.txt
|
@@ -166,6 +168,7 @@ files:
|
|
166
168
|
- shen/release/test_programs/whist.shen
|
167
169
|
- shen/release/test_programs/yacc.shen
|
168
170
|
- spec/shen_ruby/converters_spec.rb
|
171
|
+
- spec/shen_ruby/interop_spec.rb
|
169
172
|
- spec/spec_helper.rb
|
170
173
|
homepage: https://github.com/gregspurrier/shen-ruby
|
171
174
|
licenses:
|
@@ -194,4 +197,5 @@ specification_version: 4
|
|
194
197
|
summary: ShenRuby is a Ruby port of the Shen programming language
|
195
198
|
test_files:
|
196
199
|
- spec/shen_ruby/converters_spec.rb
|
200
|
+
- spec/shen_ruby/interop_spec.rb
|
197
201
|
- spec/spec_helper.rb
|