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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c457075dab1a292cac646bf9148aaafb79de2457
4
- data.tar.gz: b8909a0fef1f820b121110a06394366a7c01c3a4
3
+ metadata.gz: 2cc8006d7f3fac61a20da31b9abe918d51ccfc56
4
+ data.tar.gz: bb145ab8f07ab6ede1cb1eef9ff9ea5aa219d31a
5
5
  SHA512:
6
- metadata.gz: 686bb28d207078c9e7e0a9ad38c058fe9ed7da9695a84adf4f51a85e58ca3870b90235ada593ae3c7ebdedfc641ac0649591dfa59ae9dc43b84b1f5607747de9
7
- data.tar.gz: d767482519d1199ad6206f122fd0c1bd8211c155df994cdabbf5e9c7f2f5f6a616e7019e1d7d9886a775ffd1e72625d605c837286b6d4cd6dda6012884169092
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.11.0 is the current release. To install it as a gem, use the following command:
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.18 seconds.
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.11.0 ported by Greg Spurrier
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
+ )
@@ -1,3 +1,3 @@
1
1
  module ShenRuby
2
- VERSION = "0.11.0"
2
+ VERSION = "0.12.0"
3
3
  end
@@ -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 types
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.2', '0.0.2'
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.11.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-15 00:00:00.000000000 Z
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.2
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.2
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