shen-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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