shen-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +0 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +20 -0
  5. data/MIT_LICENSE.txt +26 -0
  6. data/README.md +94 -0
  7. data/bin/shen_test_suite.rb +9 -0
  8. data/bin/srrepl +23 -0
  9. data/lib/kl.rb +7 -0
  10. data/lib/kl/absvector.rb +12 -0
  11. data/lib/kl/compiler.rb +253 -0
  12. data/lib/kl/cons.rb +51 -0
  13. data/lib/kl/empty_list.rb +12 -0
  14. data/lib/kl/environment.rb +123 -0
  15. data/lib/kl/error.rb +4 -0
  16. data/lib/kl/internal_error.rb +7 -0
  17. data/lib/kl/lexer.rb +186 -0
  18. data/lib/kl/primitives/arithmetic.rb +60 -0
  19. data/lib/kl/primitives/assignments.rb +18 -0
  20. data/lib/kl/primitives/booleans.rb +17 -0
  21. data/lib/kl/primitives/error_handling.rb +13 -0
  22. data/lib/kl/primitives/generic_functions.rb +22 -0
  23. data/lib/kl/primitives/lists.rb +21 -0
  24. data/lib/kl/primitives/streams.rb +38 -0
  25. data/lib/kl/primitives/strings.rb +55 -0
  26. data/lib/kl/primitives/symbols.rb +17 -0
  27. data/lib/kl/primitives/time.rb +17 -0
  28. data/lib/kl/primitives/vectors.rb +30 -0
  29. data/lib/kl/reader.rb +40 -0
  30. data/lib/kl/trampoline.rb +14 -0
  31. data/lib/shen_ruby.rb +7 -0
  32. data/lib/shen_ruby/version.rb +3 -0
  33. data/shen-ruby.gemspec +26 -0
  34. data/shen/README.txt +17 -0
  35. data/shen/lib/shen_ruby/shen.rb +124 -0
  36. data/shen/license.txt +34 -0
  37. data/shen/release/benchmarks/N_queens.shen +45 -0
  38. data/shen/release/benchmarks/README.shen +14 -0
  39. data/shen/release/benchmarks/benchmarks.shen +56 -0
  40. data/shen/release/benchmarks/bigprog +2173 -0
  41. data/shen/release/benchmarks/br.shen +13 -0
  42. data/shen/release/benchmarks/einstein.shen +33 -0
  43. data/shen/release/benchmarks/heatwave.gif +0 -0
  44. data/shen/release/benchmarks/interpreter.shen +219 -0
  45. data/shen/release/benchmarks/picture.jpg +0 -0
  46. data/shen/release/benchmarks/plato.jpg +0 -0
  47. data/shen/release/benchmarks/powerset.shen +10 -0
  48. data/shen/release/benchmarks/prime.shen +10 -0
  49. data/shen/release/benchmarks/short.shen +129 -0
  50. data/shen/release/benchmarks/text.txt +68 -0
  51. data/shen/release/k_lambda/core.kl +1002 -0
  52. data/shen/release/k_lambda/declarations.kl +1021 -0
  53. data/shen/release/k_lambda/load.kl +94 -0
  54. data/shen/release/k_lambda/macros.kl +479 -0
  55. data/shen/release/k_lambda/prolog.kl +1309 -0
  56. data/shen/release/k_lambda/reader.kl +1058 -0
  57. data/shen/release/k_lambda/sequent.kl +556 -0
  58. data/shen/release/k_lambda/sys.kl +582 -0
  59. data/shen/release/k_lambda/t-star.kl +3493 -0
  60. data/shen/release/k_lambda/toplevel.kl +223 -0
  61. data/shen/release/k_lambda/track.kl +208 -0
  62. data/shen/release/k_lambda/types.kl +455 -0
  63. data/shen/release/k_lambda/writer.kl +108 -0
  64. data/shen/release/k_lambda/yacc.kl +280 -0
  65. data/shen/release/test_programs/Chap13/problems.txt +26 -0
  66. data/shen/release/test_programs/README.shen +53 -0
  67. data/shen/release/test_programs/TinyLispFunctions.txt +16 -0
  68. data/shen/release/test_programs/TinyTypes.shen +55 -0
  69. data/shen/release/test_programs/binary.shen +24 -0
  70. data/shen/release/test_programs/bubble_version_1.shen +28 -0
  71. data/shen/release/test_programs/bubble_version_2.shen +22 -0
  72. data/shen/release/test_programs/calculator.shen +21 -0
  73. data/shen/release/test_programs/cartprod.shen +23 -0
  74. data/shen/release/test_programs/change.shen +25 -0
  75. data/shen/release/test_programs/classes-defaults.shen +94 -0
  76. data/shen/release/test_programs/classes-inheritance.shen +100 -0
  77. data/shen/release/test_programs/classes-typed.shen +74 -0
  78. data/shen/release/test_programs/classes-untyped.shen +46 -0
  79. data/shen/release/test_programs/depth_.shen +14 -0
  80. data/shen/release/test_programs/einstein.shen +33 -0
  81. data/shen/release/test_programs/fruit_machine.shen +46 -0
  82. data/shen/release/test_programs/interpreter.shen +219 -0
  83. data/shen/release/test_programs/metaprog.shen +85 -0
  84. data/shen/release/test_programs/minim.shen +193 -0
  85. data/shen/release/test_programs/mutual.shen +11 -0
  86. data/shen/release/test_programs/n_queens.shen +45 -0
  87. data/shen/release/test_programs/newton_version_1.shen +33 -0
  88. data/shen/release/test_programs/newton_version_2.shen +24 -0
  89. data/shen/release/test_programs/parse.prl +14 -0
  90. data/shen/release/test_programs/parser.shen +52 -0
  91. data/shen/release/test_programs/powerset.shen +10 -0
  92. data/shen/release/test_programs/prime.shen +10 -0
  93. data/shen/release/test_programs/proof_assistant.shen +81 -0
  94. data/shen/release/test_programs/proplog_version_1.shen +25 -0
  95. data/shen/release/test_programs/proplog_version_2.shen +27 -0
  96. data/shen/release/test_programs/qmachine.shen +67 -0
  97. data/shen/release/test_programs/red-black.shen +55 -0
  98. data/shen/release/test_programs/search.shen +56 -0
  99. data/shen/release/test_programs/semantic_net.shen +44 -0
  100. data/shen/release/test_programs/spreadsheet.shen +35 -0
  101. data/shen/release/test_programs/stack.shen +27 -0
  102. data/shen/release/test_programs/streams.shen +20 -0
  103. data/shen/release/test_programs/strings.shen +59 -0
  104. data/shen/release/test_programs/structures-typed.shen +71 -0
  105. data/shen/release/test_programs/structures-untyped.shen +42 -0
  106. data/shen/release/test_programs/tests.shen +294 -0
  107. data/shen/release/test_programs/types.shen +11 -0
  108. data/shen/release/test_programs/whist.shen +240 -0
  109. data/shen/release/test_programs/yacc.shen +136 -0
  110. data/spec/kl/cons_spec.rb +12 -0
  111. data/spec/kl/environment_spec.rb +306 -0
  112. data/spec/kl/lexer_spec.rb +149 -0
  113. data/spec/kl/primitives/generic_functions_spec.rb +29 -0
  114. data/spec/kl/primitives/symbols_spec.rb +21 -0
  115. data/spec/kl/reader_spec.rb +36 -0
  116. data/spec/spec_helper.rb +2 -0
  117. metadata +189 -0
@@ -0,0 +1,18 @@
1
+ module Kl
2
+ module Primitives
3
+ module Assignments
4
+ def set(sym, value)
5
+ @variables[sym] = value
6
+ value
7
+ end
8
+
9
+ def value(sym)
10
+ if @variables.has_key?(sym)
11
+ @variables[sym]
12
+ else
13
+ raise Kl::Error, "variable #{sym} has no value"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Kl
2
+ module Primitives
3
+ # The boolean functions are all implemented as short-circuiting special
4
+ # forms in the compiler. The implementations below are for use as
5
+ # arguments to higher-order functions. They are used, e.g., in the
6
+ # Quantifier Machine test case in the Shen Test Suite.
7
+ module Booleans
8
+ def or(a, b)
9
+ a || b
10
+ end
11
+
12
+ def and(a, b)
13
+ a && b
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Kl
2
+ module Primitives
3
+ module ErrorHandling
4
+ define_method 'simple-error' do |err_msg|
5
+ raise Kl::Error, err_msg
6
+ end
7
+
8
+ define_method 'error-to-string' do |err|
9
+ err.message
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ module Kl
2
+ module Primitives
3
+ # The following functions are implemented as special forms
4
+ # in Kl::Compiler:
5
+ #
6
+ # - defun
7
+ # - lambda
8
+ # - let
9
+ # - freeze
10
+ # - type
11
+ module GenericFunctions
12
+ define_method '=' do |a, b|
13
+ a == b
14
+ end
15
+
16
+ # Curried after inclusion
17
+ define_method 'eval-kl' do |exp|
18
+ __eval(exp)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Kl
2
+ module Primitives
3
+ module Lists
4
+ def cons(a, b)
5
+ Kl::Cons.new(a, b)
6
+ end
7
+
8
+ def hd(a)
9
+ a.hd
10
+ end
11
+
12
+ def tl(a)
13
+ a.tl
14
+ end
15
+
16
+ def cons?(a)
17
+ a.kind_of? Kl::Cons
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ module Kl
2
+ module Primitives
3
+ module Streams
4
+ def pr(s, stream)
5
+ if stream == STDIN
6
+ # shen-prbytes in toplevel.kl calls pr on *stinput* rather than
7
+ # *stoutput*. As a temporary solution, use the same approach
8
+ # that Bruno Deferrari uses in his Scheme port. See
9
+ # https://groups.google.com/d/topic/qilang/2ixosqX4Too/discussion
10
+ stream = STDOUT if stream == STDIN
11
+ end
12
+ stream.write(s)
13
+ s
14
+ end
15
+
16
+ define_method 'read-byte' do |stream|
17
+ if stream.eof?
18
+ -1
19
+ else
20
+ stream.readbyte
21
+ end
22
+ end
23
+
24
+ def open(stream_type, name, direction)
25
+ unless stream_type == :file
26
+ raise Kl::Error, "unsupported stream type: #{stream_type}"
27
+ end
28
+ File.open(File.expand_path(name, value(:'*home-directory*')),
29
+ direction == :out ? 'w' : 'r')
30
+ end
31
+
32
+ def close(stream)
33
+ stream.close
34
+ :NIL
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ module Kl
2
+ module Primitives
3
+ # For the time being, Shen Ruby's string functions only support 8-bit
4
+ # characters. Once the Shen environment is up and running and passing
5
+ # its test suite, strings will be extended to support UTF-8.
6
+ module Strings
7
+ def pos(s, n)
8
+ s.byteslice(n)
9
+ end
10
+
11
+ def tlstr(s)
12
+ if s.empty?
13
+ :"shen-eos"
14
+ else
15
+ s.byteslice(1, s.bytesize - 1)
16
+ end
17
+ end
18
+
19
+ def cn(s1, s2)
20
+ s1 + s2
21
+ end
22
+
23
+ def str(x)
24
+ case x
25
+ when String
26
+ '"' + x + '"'
27
+ when Symbol
28
+ x.to_s
29
+ when Numeric
30
+ x.to_s
31
+ when TrueClass, FalseClass
32
+ x.to_s
33
+ when Proc
34
+ x.to_s
35
+ when IO
36
+ x.to_s
37
+ else
38
+ raise Kl::Error, "str applied to non-atomic type: #{x.class}"
39
+ end
40
+ end
41
+
42
+ def string?(x)
43
+ x.kind_of? String
44
+ end
45
+
46
+ define_method 'n->string' do |n|
47
+ "" << n
48
+ end
49
+
50
+ define_method 'string->n' do |s|
51
+ s.bytes.to_a.first
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,17 @@
1
+ module Kl
2
+ module Primitives
3
+ module Symbols
4
+ def intern(str)
5
+ # 'true' and 'false' are treated specially and return the
6
+ # corresponding booleans
7
+ if str == 'true'
8
+ true
9
+ elsif str == 'false'
10
+ false
11
+ else
12
+ str.to_sym
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Kl
2
+ module Primitives
3
+ module Time
4
+ define_method 'get-time' do |time_type|
5
+ case time_type
6
+ when :run, :real
7
+ ::Time.now.to_f
8
+ when :unix
9
+ ::Time.now.to_i
10
+ else
11
+ raise Kl::Error, "unsupported time type: #{time_type}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,30 @@
1
+ module Kl
2
+ module Primitives
3
+ module Vectors
4
+ def absvector(n)
5
+ Kl::Absvector.new(n)
6
+ end
7
+
8
+ define_method 'address->' do |v, n, value|
9
+ if n < 0 || n >= v.upper_limit
10
+ raise Kl::Error, "out of bounds"
11
+ end
12
+
13
+ v[n] = value
14
+ v
15
+ end
16
+
17
+ define_method '<-address' do |v, n|
18
+ if n < 0 || n >= v.upper_limit
19
+ raise Kl::Error, "out of bounds"
20
+ end
21
+
22
+ v[n]
23
+ end
24
+
25
+ def absvector?(v)
26
+ v.kind_of? Kl::Absvector
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/kl/reader.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'kl/lexer'
2
+
3
+ module Kl
4
+ class Reader
5
+ def initialize(stream)
6
+ @lexer = Kl::Lexer.new(stream)
7
+ end
8
+
9
+ def next
10
+ token = @lexer.next
11
+ unless token.nil?
12
+ if token.kind_of? Kl::Lexer::OpenParen
13
+ read_list
14
+ else
15
+ token
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def read_list
23
+ items = []
24
+
25
+ loop do
26
+ token = @lexer.next
27
+ raise Kl::Error, 'Unterminated list' if token.nil?
28
+ case token
29
+ when Kl::Lexer::OpenParen
30
+ items << read_list
31
+ when Kl::Lexer::CloseParen
32
+ break
33
+ else
34
+ items << token
35
+ end
36
+ end
37
+ Kl::Cons.list(items)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ module Kl
2
+ # Trampolines hold a function and a list of its already-evaluated
3
+ # arguments. They are used to keep the strack from growing on
4
+ # tail calls.
5
+ class Trampoline
6
+ attr_reader :fn, :args, :f
7
+
8
+ def initialize(fn, args, f)
9
+ @fn = fn
10
+ @args = args
11
+ @f = f
12
+ end
13
+ end
14
+ end
data/lib/shen_ruby.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'kl'
2
+ require 'shen_ruby/version'
3
+
4
+ # The following file is a derivative of the Shen release packages with ShenRuby
5
+ # and it located under the shen directory hierarchy to make the license
6
+ # unambigous. It can be found at shen/lib/shen_ruby/shen.rb
7
+ require 'shen_ruby/shen'
@@ -0,0 +1,3 @@
1
+ module ShenRuby
2
+ VERSION = "0.1.0"
3
+ end
data/shen-ruby.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'shen_ruby/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "shen-ruby"
8
+ s.version = ShenRuby::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.license = "Shen License and MIT License. See README.md for details."
11
+ s.authors = ["Greg Spurrier", "Mark Tarver"]
12
+ s.email = ["greg@sourcematters.org"]
13
+ s.homepage = "https://github.com/gregspurrier/shen-ruby"
14
+ s.summary = %q{ShenRuby is a Ruby port of the Shen programming language}
15
+ s.description = %q{ShenRuby is a port of the Shen programming language to Ruby. It currently supports Shen version 7.1.}
16
+
17
+ s.required_ruby_version = ">= 1.9.3"
18
+
19
+ s.add_development_dependency "rspec", "~> 2.12"
20
+
21
+ git_files = `git ls-files`.split("\n") rescue ''
22
+ s.files = git_files
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = %w(srrepl)
25
+ s.require_paths = ["lib", "shen/lib"]
26
+ end
data/shen/README.txt ADDED
@@ -0,0 +1,17 @@
1
+ The files found in this directory and its subdirectories are part of
2
+ Shen and are subject to the Shen License. A copy of the license may be
3
+ found in license.txt in this directory. A detailed explanation of the
4
+ license may be found at http://shenlanguage.org/license.html.
5
+
6
+ Directory contents:
7
+
8
+ README.txt -- this file
9
+ license.txt -- the Shen license
10
+ release/ -- files extracted directly from the Shen 7.1 Source
11
+ release. The complete source for the most recent
12
+ release of Shen may be downloaded from
13
+ http://www.shenlanguage.org/Download/index.htm
14
+ lib/ -- Ruby code that creates a full Shen environment running
15
+ under ShenRuby's implementation of K Lambda. This code
16
+ is considered a derivative work of the original Shen
17
+ Source release.
@@ -0,0 +1,124 @@
1
+ ############################################################################
2
+ # License
3
+ # -------
4
+ # The user is free to produce commercial applications with the
5
+ # software, to distribute these applications in source or binary form,
6
+ # and to charge monies for them as he sees fit and in concordance with
7
+ # the laws of the land subject to the following license.
8
+ #
9
+ # 1. The license applies to all the software and all derived software
10
+ # and must appear on such.
11
+ #
12
+ # 2. It is illegal to distribute the software without this license
13
+ # attached to it and use of the software implies agreement with the
14
+ # license as such. It is illegal for anyone who is not the copyright
15
+ # holder to tamper with or change the license.
16
+ #
17
+ # 3. Neither the names of Lambda Associates or the copyright holder
18
+ # may be used to endorse or promote products built using the software
19
+ # without specific prior written permission from the copyright holder.
20
+ #
21
+ # 4. That possession of this license does not confer on the copyright
22
+ # holder any special contractual obligation towards the user. That in
23
+ # no event shall the copyright holder be liable for any direct,
24
+ # indirect, incidental, special, exemplary or consequential damages
25
+ # (including but not limited to procurement of substitute goods or
26
+ # services, loss of use, data, or profits; or business interruption),
27
+ # however caused and on any theory of liability, whether in contract,
28
+ # strict liability or tort (including negligence) arising in any way
29
+ # out of the use of the software, even if advised of the possibility
30
+ # of such damage.
31
+ #
32
+ # 5. It is permitted for the user to change the software, for the
33
+ # purpose of improving performance, correcting an error, or porting to
34
+ # a new platform, and distribute the modified version of Shen
35
+ # (hereafter the modified version) provided the resulting program
36
+ # conforms in all respects to the Shen standard and is issued under
37
+ # that title. The user must make it clear with his distribution that
38
+ # he/she is the author of the changes and what these changes are and
39
+ # why.
40
+ #
41
+ # 6. Derived versions of this software in whatever form are subject to
42
+ # the same restrictions. In particular it is not permitted to make
43
+ # derived copies of this software which do not conform to the Shen
44
+ # standard or appear under a different title.
45
+ #
46
+ # 7. It is permitted to distribute versions of Shen which incorporate
47
+ # libraries, graphics or other facilities which are not part of the
48
+ # Shen standard.
49
+ #
50
+ # For an explication of this license see
51
+ # http://www.lambdassociates.org/News/june11/license.htm which
52
+ # explains this license in full.
53
+ #
54
+ ############################################################################
55
+ #
56
+ # This file was written by Greg Spurrier as part of the ShenRuby
57
+ # project. It is essentially a shell into which the K Lambda sources
58
+ # of Shen are loaded at runtime as part of object initialization to
59
+ # produce a working Shen environment. It is thefore a derivative work
60
+ # of the Shen sources and is subject to the Shen License.
61
+ #
62
+ ############################################################################
63
+
64
+ module ShenRuby
65
+ # Instances of the ShenRuby::Shen class provide a Shen environment
66
+ # running within ShenRuby's K Lambda implementation.
67
+ class Shen < Kl::Environment
68
+ def initialize
69
+ super
70
+
71
+ # Set the global variables
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)
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
+
81
+
82
+ # Load the K Lambda files
83
+ kl_root = File.expand_path('../../../release/k_lambda', __FILE__)
84
+ %w(toplevel core sys).each do |kl_filename|
85
+ Kl::Environment.load_file(self, File.join(kl_root, kl_filename + ".kl"))
86
+ end
87
+
88
+ # Overrides
89
+ 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
+ # The version of shen-explode-string from sys.kl is not tail-recursive.
99
+ # Replace it with a version that does not blow up the stack.
100
+ define_method "shen-explode-string" do |str|
101
+ Kl::Cons.list(str.split(//))
102
+ end
103
+
104
+ # Give a way to bail out
105
+ define_method 'quit' do
106
+ ::Kernel.exit(0)
107
+ end
108
+
109
+ # For debugging the compiler
110
+ define_method 'set-dump-code' do |val|
111
+ @dump_code = val
112
+ end
113
+ end
114
+
115
+ # Load the rest of the K Lambda files
116
+ %w(sequent yacc
117
+ reader prolog track load writer
118
+ macros declarations t-star types
119
+ ).each do |kl_filename|
120
+ Kl::Environment.load_file(self, File.join(kl_root, kl_filename + ".kl"))
121
+ end
122
+ end
123
+ end
124
+ end