shen-ruby 0.10.0 → 0.11.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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +9 -3
- data/Gemfile +1 -4
- data/HISTORY.md +16 -0
- data/MIT_LICENSE.txt +1 -1
- data/README.md +25 -26
- data/Rakefile +3 -11
- data/bin/shen_test_suite.rb +15 -3
- data/bin/srrepl +6 -8
- data/lib/shen_ruby.rb +6 -1
- data/lib/shen_ruby/converters.rb +23 -0
- data/lib/shen_ruby/version.rb +1 -1
- data/shen-ruby.gemspec +4 -1
- data/shen/lib/shen_ruby/shen.rb +49 -33
- data/shen/release/benchmarks/N_queens.shen +45 -45
- data/shen/release/benchmarks/README.shen +14 -14
- data/shen/release/benchmarks/benchmarks.shen +52 -52
- data/shen/release/benchmarks/einstein.shen +32 -32
- data/shen/release/benchmarks/interpreter.shen +219 -219
- data/shen/release/benchmarks/jnk.shen +193 -193
- data/shen/release/benchmarks/powerset.shen +10 -10
- data/shen/release/benchmarks/prime.shen +10 -10
- data/shen/release/benchmarks/short.shen +129 -129
- data/shen/release/k_lambda/core.kl +181 -181
- data/shen/release/k_lambda/declarations.kl +131 -131
- data/shen/release/k_lambda/load.kl +84 -84
- data/shen/release/k_lambda/macros.kl +112 -112
- data/shen/release/k_lambda/prolog.kl +252 -252
- data/shen/release/k_lambda/reader.kl +222 -222
- data/shen/release/k_lambda/sequent.kl +166 -166
- data/shen/release/k_lambda/sys.kl +271 -271
- data/shen/release/k_lambda/t-star.kl +139 -139
- data/shen/release/k_lambda/toplevel.kl +135 -135
- data/shen/release/k_lambda/track.kl +103 -103
- data/shen/release/k_lambda/types.kl +324 -324
- data/shen/release/k_lambda/writer.kl +105 -105
- data/shen/release/k_lambda/yacc.kl +113 -113
- data/shen/release/test_programs/Chap13/problems.txt +26 -26
- data/shen/release/test_programs/README.shen +52 -52
- data/shen/release/test_programs/TinyLispFunctions.txt +15 -15
- data/shen/release/test_programs/TinyTypes.shen +55 -55
- data/shen/release/test_programs/binary.shen +24 -24
- data/shen/release/test_programs/bubble_version_1.shen +28 -28
- data/shen/release/test_programs/bubble_version_2.shen +22 -22
- data/shen/release/test_programs/calculator.shen +21 -21
- data/shen/release/test_programs/cartprod.shen +23 -23
- data/shen/release/test_programs/change.shen +25 -25
- data/shen/release/test_programs/classes-defaults.shen +94 -94
- data/shen/release/test_programs/classes-inheritance.shen +100 -100
- data/shen/release/test_programs/classes-typed.shen +74 -74
- data/shen/release/test_programs/classes-untyped.shen +46 -46
- data/shen/release/test_programs/depth_.shen +14 -14
- data/shen/release/test_programs/einstein.shen +34 -34
- data/shen/release/test_programs/fruit_machine.shen +46 -46
- data/shen/release/test_programs/interpreter.shen +217 -217
- data/shen/release/test_programs/metaprog.shen +85 -85
- data/shen/release/test_programs/minim.shen +192 -192
- data/shen/release/test_programs/mutual.shen +11 -11
- data/shen/release/test_programs/n_queens.shen +45 -45
- data/shen/release/test_programs/newton_version_1.shen +33 -33
- data/shen/release/test_programs/newton_version_2.shen +24 -24
- data/shen/release/test_programs/parse.prl +14 -14
- data/shen/release/test_programs/parser.shen +51 -51
- data/shen/release/test_programs/powerset.shen +10 -10
- data/shen/release/test_programs/prime.shen +10 -10
- data/shen/release/test_programs/prolog.shen +78 -78
- data/shen/release/test_programs/proof_assistant.shen +80 -80
- data/shen/release/test_programs/proplog_version_1.shen +25 -25
- data/shen/release/test_programs/proplog_version_2.shen +27 -27
- data/shen/release/test_programs/qmachine.shen +66 -66
- data/shen/release/test_programs/red-black.shen +54 -54
- data/shen/release/test_programs/search.shen +55 -55
- data/shen/release/test_programs/semantic_net.shen +44 -44
- data/shen/release/test_programs/spreadsheet.shen +34 -34
- data/shen/release/test_programs/stack.shen +27 -27
- data/shen/release/test_programs/streams.shen +20 -20
- data/shen/release/test_programs/strings.shen +57 -57
- data/shen/release/test_programs/structures-typed.shen +71 -71
- data/shen/release/test_programs/structures-untyped.shen +41 -41
- data/shen/release/test_programs/tests.shen +232 -232
- data/shen/release/test_programs/types.shen +11 -11
- data/shen/release/test_programs/whist.shen +239 -239
- data/shen/release/test_programs/yacc.shen +132 -132
- data/spec/shen_ruby/converters_spec.rb +48 -0
- data/spec/spec_helper.rb +1 -2
- metadata +55 -60
- data/k_lambda_spec/atom_spec.rb +0 -85
- data/k_lambda_spec/primitives/arithmetic_spec.rb +0 -175
- data/k_lambda_spec/primitives/assignments_spec.rb +0 -44
- data/k_lambda_spec/primitives/boolean_operations_spec.rb +0 -136
- data/k_lambda_spec/primitives/generic_functions_spec.rb +0 -120
- data/k_lambda_spec/primitives/lists_spec.rb +0 -40
- data/k_lambda_spec/primitives/strings_spec.rb +0 -77
- data/k_lambda_spec/primitives/symbols_spec.rb +0 -24
- data/k_lambda_spec/primitives/vectors_spec.rb +0 -92
- data/k_lambda_spec/spec_helper.rb +0 -29
- data/k_lambda_spec/support/shared_examples.rb +0 -124
- data/k_lambda_spec/tail_recursion_spec.rb +0 -30
- data/lib/kl.rb +0 -7
- data/lib/kl/absvector.rb +0 -12
- data/lib/kl/compiler.rb +0 -360
- data/lib/kl/cons.rb +0 -51
- data/lib/kl/empty_list.rb +0 -12
- data/lib/kl/environment.rb +0 -163
- data/lib/kl/error.rb +0 -4
- data/lib/kl/internal_error.rb +0 -7
- data/lib/kl/lexer.rb +0 -186
- data/lib/kl/primitives/arithmetic.rb +0 -60
- data/lib/kl/primitives/assignments.rb +0 -15
- data/lib/kl/primitives/booleans.rb +0 -21
- data/lib/kl/primitives/error_handling.rb +0 -13
- data/lib/kl/primitives/extensions.rb +0 -12
- data/lib/kl/primitives/generic_functions.rb +0 -29
- data/lib/kl/primitives/lists.rb +0 -23
- data/lib/kl/primitives/streams.rb +0 -28
- data/lib/kl/primitives/strings.rb +0 -63
- data/lib/kl/primitives/symbols.rb +0 -18
- data/lib/kl/primitives/time.rb +0 -17
- data/lib/kl/primitives/vectors.rb +0 -36
- data/lib/kl/reader.rb +0 -46
- data/spec/kl/cons_spec.rb +0 -12
- data/spec/kl/environment_spec.rb +0 -282
- data/spec/kl/interop_spec.rb +0 -68
- data/spec/kl/lexer_spec.rb +0 -149
- data/spec/kl/primitives/generic_functions_spec.rb +0 -29
- data/spec/kl/primitives/symbols_spec.rb +0 -21
- data/spec/kl/reader_spec.rb +0 -42
data/lib/kl/error.rb
DELETED
data/lib/kl/internal_error.rb
DELETED
data/lib/kl/lexer.rb
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
require 'kl/error'
|
3
|
-
|
4
|
-
module Kl
|
5
|
-
class Lexer
|
6
|
-
SYMBOL_CHARS = /[-=*\/+_?$!\@~><&%'#`;:{}a-zA-Z0-9.]/
|
7
|
-
|
8
|
-
# Syntax tokens
|
9
|
-
class OpenParen
|
10
|
-
include Singleton
|
11
|
-
end
|
12
|
-
class CloseParen
|
13
|
-
include Singleton
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(stream)
|
17
|
-
@stream = stream
|
18
|
-
@buffer = []
|
19
|
-
end
|
20
|
-
|
21
|
-
def eof?
|
22
|
-
@buffer.empty? && @stream.eof?
|
23
|
-
end
|
24
|
-
|
25
|
-
def getc
|
26
|
-
if @buffer.empty?
|
27
|
-
@stream.getc
|
28
|
-
else
|
29
|
-
@buffer.pop
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def ungetc(c)
|
34
|
-
@buffer.push(c)
|
35
|
-
end
|
36
|
-
|
37
|
-
def next
|
38
|
-
drain_whitespace
|
39
|
-
unless eof?
|
40
|
-
c = getc
|
41
|
-
case c
|
42
|
-
when '('
|
43
|
-
OpenParen.instance
|
44
|
-
when ')'
|
45
|
-
CloseParen.instance
|
46
|
-
when '"'
|
47
|
-
consume_string
|
48
|
-
when SYMBOL_CHARS
|
49
|
-
ungetc(c)
|
50
|
-
consume_number_or_symbol
|
51
|
-
else
|
52
|
-
raise Error, "illegal character: #{c}"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
def drain_whitespace
|
59
|
-
until eof?
|
60
|
-
c = getc
|
61
|
-
if c =~ /\S/
|
62
|
-
ungetc(c)
|
63
|
-
break
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def consume_string
|
69
|
-
chars = []
|
70
|
-
loop do
|
71
|
-
raise Error, "unterminated string" if eof?
|
72
|
-
c = getc
|
73
|
-
break if c == '"'
|
74
|
-
chars << c
|
75
|
-
end
|
76
|
-
chars.join
|
77
|
-
end
|
78
|
-
|
79
|
-
def consume_number
|
80
|
-
# Shen allows multiple leading plusses and minuses. The plusses
|
81
|
-
# are ignored and an even number of minuses cancel each other.
|
82
|
-
# Thus '------+-7' is read as 7.
|
83
|
-
#
|
84
|
-
# The Shen reader parses "7." as the integer 7 and the symbol '.'
|
85
|
-
decimal_seen = false
|
86
|
-
negative = false
|
87
|
-
past_sign = false
|
88
|
-
chars = []
|
89
|
-
loop do
|
90
|
-
break if eof?
|
91
|
-
c = getc
|
92
|
-
if c =~ /\d/
|
93
|
-
past_sign = true
|
94
|
-
chars << c
|
95
|
-
elsif c == '.' && !decimal_seen
|
96
|
-
past_sign = true
|
97
|
-
decimal_seen = true
|
98
|
-
chars << c
|
99
|
-
elsif c == '+' && !past_sign
|
100
|
-
# ignore
|
101
|
-
elsif c == '-' && !past_sign
|
102
|
-
negative = !negative
|
103
|
-
else
|
104
|
-
ungetc c
|
105
|
-
break
|
106
|
-
end
|
107
|
-
end
|
108
|
-
chars.unshift('-') if negative
|
109
|
-
if chars.last == '.'
|
110
|
-
# A trailing decimal point is treated as part of the next
|
111
|
-
# token. Forget we saw it.
|
112
|
-
ungetc(chars.pop)
|
113
|
-
decimal_seen = false
|
114
|
-
end
|
115
|
-
str = chars.join
|
116
|
-
decimal_seen ? str.to_f : str.to_i
|
117
|
-
end
|
118
|
-
|
119
|
-
def consume_symbol
|
120
|
-
chars = []
|
121
|
-
loop do
|
122
|
-
break if eof?
|
123
|
-
c = getc
|
124
|
-
unless c =~ SYMBOL_CHARS
|
125
|
-
ungetc c
|
126
|
-
break
|
127
|
-
end
|
128
|
-
chars << c
|
129
|
-
end
|
130
|
-
str = chars.join
|
131
|
-
|
132
|
-
case str
|
133
|
-
when 'true'
|
134
|
-
true
|
135
|
-
when 'false'
|
136
|
-
false
|
137
|
-
else
|
138
|
-
str.to_sym
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def consume_number_or_symbol
|
143
|
-
# First drain optional leading signs
|
144
|
-
# Then drain optional decimal point
|
145
|
-
# If there is another character and it is a digit, then it
|
146
|
-
# is a number. Otherwise it is a symbol.
|
147
|
-
chars = []
|
148
|
-
loop do
|
149
|
-
break if eof?
|
150
|
-
c = getc
|
151
|
-
unless c =~ /[-+]/
|
152
|
-
ungetc c
|
153
|
-
break
|
154
|
-
end
|
155
|
-
chars << c
|
156
|
-
end
|
157
|
-
if eof?
|
158
|
-
chars.reverse.each {|x| ungetc x}
|
159
|
-
return consume_symbol
|
160
|
-
end
|
161
|
-
|
162
|
-
c = getc
|
163
|
-
chars << c
|
164
|
-
if c == '.'
|
165
|
-
if eof?
|
166
|
-
chars.reverse.each {|x| ungetc x}
|
167
|
-
return consume_symbol
|
168
|
-
end
|
169
|
-
c = getc
|
170
|
-
chars << c
|
171
|
-
chars.reverse.each {|x| ungetc x}
|
172
|
-
if c =~ /\d/
|
173
|
-
return consume_number
|
174
|
-
else
|
175
|
-
return consume_symbol
|
176
|
-
end
|
177
|
-
elsif c =~ /\d/
|
178
|
-
chars.reverse.each {|x| ungetc x}
|
179
|
-
return consume_number
|
180
|
-
else
|
181
|
-
chars.reverse.each {|x| ungetc x}
|
182
|
-
return consume_symbol
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module Kl
|
2
|
-
module Primitives
|
3
|
-
module Arithmetic
|
4
|
-
def +(a, b)
|
5
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
6
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
7
|
-
a + b
|
8
|
-
end
|
9
|
-
|
10
|
-
def -(a, b)
|
11
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
12
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
13
|
-
a - b
|
14
|
-
end
|
15
|
-
|
16
|
-
def *(a, b)
|
17
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
18
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
19
|
-
a * b
|
20
|
-
end
|
21
|
-
|
22
|
-
def /(a, b)
|
23
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
24
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
25
|
-
if a.kind_of?(Fixnum) && b.kind_of?(Fixnum) && a % b != 0
|
26
|
-
a = a.to_f
|
27
|
-
end
|
28
|
-
a / b
|
29
|
-
end
|
30
|
-
|
31
|
-
def >(a, b)
|
32
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
33
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
34
|
-
a > b
|
35
|
-
end
|
36
|
-
|
37
|
-
def <(a, b)
|
38
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
39
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
40
|
-
a < b
|
41
|
-
end
|
42
|
-
|
43
|
-
def >=(a, b)
|
44
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
45
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
46
|
-
a >= b
|
47
|
-
end
|
48
|
-
|
49
|
-
def <=(a, b)
|
50
|
-
raise ::Kl::Error, "#{a} is not a number" unless a.kind_of? Numeric
|
51
|
-
raise ::Kl::Error, "#{b} is not a number" unless b.kind_of? Numeric
|
52
|
-
a <= b
|
53
|
-
end
|
54
|
-
|
55
|
-
def number?(a)
|
56
|
-
a.kind_of?(Numeric)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,21 +0,0 @@
|
|
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
|
-
define_method 'if' do |a, b, c|
|
9
|
-
a ? b : c
|
10
|
-
end
|
11
|
-
|
12
|
-
def or(a, b)
|
13
|
-
a || b
|
14
|
-
end
|
15
|
-
|
16
|
-
def and(a, b)
|
17
|
-
a && b
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module Kl
|
2
|
-
module Primitives
|
3
|
-
# Extensions to the official set of K Lambda primitives.
|
4
|
-
# Unlike the official primitives, these are allowed to be overridden
|
5
|
-
# by the Shen sources later.
|
6
|
-
module Extensions
|
7
|
-
define_method 'do' do |a, b|
|
8
|
-
b
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,29 +0,0 @@
|
|
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
|
-
|
21
|
-
# Freeze is also provided as a normal function to support
|
22
|
-
# the partial application of zero arguments case. In this
|
23
|
-
# case it becomes a non-special-form.
|
24
|
-
def freeze(exp)
|
25
|
-
Kernel.lambda { exp }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/lib/kl/primitives/lists.rb
DELETED
@@ -1,23 +0,0 @@
|
|
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
|
-
raise Kl::Error, "#{a} is not a list" unless a.kind_of? Kl::Cons
|
10
|
-
a.hd
|
11
|
-
end
|
12
|
-
|
13
|
-
def tl(a)
|
14
|
-
raise Kl::Error, "#{a} is not a list" unless a.kind_of? Kl::Cons
|
15
|
-
a.tl
|
16
|
-
end
|
17
|
-
|
18
|
-
def cons?(a)
|
19
|
-
a.kind_of? Kl::Cons
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Kl
|
2
|
-
module Primitives
|
3
|
-
module Streams
|
4
|
-
define_method 'read-byte' do |stream|
|
5
|
-
if stream.eof?
|
6
|
-
-1
|
7
|
-
else
|
8
|
-
stream.readbyte
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
define_method 'write-byte' do |byte, stream|
|
13
|
-
stream.putc byte
|
14
|
-
byte
|
15
|
-
end
|
16
|
-
|
17
|
-
def open(name, direction)
|
18
|
-
File.open(File.expand_path(name, value(:'*home-directory*')),
|
19
|
-
direction == :out ? 'w' : 'r')
|
20
|
-
end
|
21
|
-
|
22
|
-
def close(stream)
|
23
|
-
stream.close
|
24
|
-
:NIL
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,63 +0,0 @@
|
|
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
|
-
raise Kl::Error, "#{s} is not a string" unless s.kind_of? String
|
9
|
-
raise Kl::Error, "#{n} is not an integer" unless n.kind_of? Fixnum
|
10
|
-
if n < 0 || n >= s.length
|
11
|
-
raise Kl::Error, "out of bounds"
|
12
|
-
end
|
13
|
-
s.byteslice(n)
|
14
|
-
end
|
15
|
-
|
16
|
-
def tlstr(s)
|
17
|
-
raise Kl::Error, "#{s} is not a string" unless s.kind_of? String
|
18
|
-
raise Kl::Error, "attempted to take tail of an empty string" if s.empty?
|
19
|
-
s.byteslice(1, s.bytesize - 1)
|
20
|
-
end
|
21
|
-
|
22
|
-
def cn(s1, s2)
|
23
|
-
raise Kl::Error, "#{s1} is not a string" unless s1.kind_of? String
|
24
|
-
raise Kl::Error, "#{s2} is not a string" unless s2.kind_of? String
|
25
|
-
s1 + s2
|
26
|
-
end
|
27
|
-
|
28
|
-
def str(x)
|
29
|
-
case x
|
30
|
-
when String
|
31
|
-
'"' + x + '"'
|
32
|
-
when Symbol
|
33
|
-
x.to_s
|
34
|
-
when Numeric
|
35
|
-
x.to_s
|
36
|
-
when TrueClass, FalseClass
|
37
|
-
x.to_s
|
38
|
-
when Proc
|
39
|
-
x.to_s
|
40
|
-
when IO
|
41
|
-
x.to_s
|
42
|
-
else
|
43
|
-
raise Kl::Error, "str applied to non-atomic type: #{x.class}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def string?(x)
|
48
|
-
x.kind_of? String
|
49
|
-
end
|
50
|
-
|
51
|
-
define_method 'n->string' do |n|
|
52
|
-
raise Kl::Error, "#{n} is not an integer" unless n.kind_of? Fixnum
|
53
|
-
"" << n
|
54
|
-
end
|
55
|
-
|
56
|
-
define_method 'string->n' do |s|
|
57
|
-
raise Kl::Error, "#{s} is not a string" unless s.kind_of? String
|
58
|
-
raise Kl::Error, 'attempted to get code point of empty string' if s.empty?
|
59
|
-
s.bytes.to_a.first
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|