missinglisp 0.0.0 → 0.0.2

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/missinglisp.rb +69 -7
  3. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42f4de8720dddb978bf21be93ef48d8aab819a588ac139245dcbafd541251e32
4
- data.tar.gz: e370720f4a3f0eadda1afa9f38fb371eb68be30b886e8274241786d0549dbda0
3
+ metadata.gz: 3d439126ef5936974b06ea17de05495349e19c0a11118edc19092e873a736436
4
+ data.tar.gz: f132a6e170876980329bd8b84d20aa1bd7e06f100bf3872b0c0e763535b30505
5
5
  SHA512:
6
- metadata.gz: e15a0228df6251a9615609bafdf2f182193ac01b71ef840640e14690571d3309eefe791fa1a76cfdc20db972dbc674de9fb45a413782560ba5bbf1e2d1912e50
7
- data.tar.gz: ca39b773ab93ad1e52a0867810faa28537761da5a7840988e9e8cf77f9cd17e1d8983147d3e320eb23748914e51878ae20f4e713742dcabb9971b5401d88908b
6
+ metadata.gz: 84dc4fadf2b03da0d3c6e155b8eacc056bd6565438a4dd08d32bfbdcb4197727ac3000317f8f0b612808af346fd77771385c7731be852a06af7de72f8fe170cb
7
+ data.tar.gz: 9995f555865a9813a2505c79f2abd9f6823fda4b81311ed312f314f3537f0020d2fe8162067b9bc3740726abc86c4753f02d7544ca990ef066a9584f7e2ca5c0
data/lib/missinglisp.rb CHANGED
@@ -16,14 +16,27 @@ class Lisp
16
16
  gt: ->(a, b, *) { a > b },
17
17
  geq: ->(a, b, *) { a >= b },
18
18
 
19
+ # string
20
+ aref: ->(s, at, *) { s[at] },
21
+ concatenate: ->(_type, *ls) { ls.reduce(:+) },
22
+
23
+ # char
24
+ codeChar: ->(c, *) { c.chr },
25
+
26
+ readLine: ->(*) { $stdin.readline.chomp },
27
+
19
28
  p: ->(*ls) { p ls },
29
+ print: ->(*ls) { p ls },
30
+ writeLine: ->(s, *) { puts s },
20
31
 
32
+ t: true,
21
33
  nil: []
22
34
  }
23
35
  end
24
36
 
25
37
  def eval(exp, env)
26
38
  return exp if exp.is_a? Numeric
39
+ return exp if exp.is_a? String
27
40
  return env[exp] if exp.is_a? Symbol
28
41
 
29
42
  # list
@@ -33,8 +46,11 @@ class Lisp
33
46
  elsif exp[0] == :if
34
47
  _, test, e1, e2 = exp
35
48
  test = self.eval(test, env)
36
- return self.eval(e1, env) if test.is_a?(Array) && !test.empty?
37
- return self.eval(e1, env) unless test.is_a?(Array) || !test
49
+ truthy = if test.is_a?(Array) then !test.empty? else test end
50
+
51
+ if truthy
52
+ return self.eval(e1, env)
53
+ end
38
54
 
39
55
  return self.eval(e2, env)
40
56
  elsif exp[0] == :define
@@ -46,9 +62,24 @@ class Lisp
46
62
  return ->(*args) { self.eval(e, env.merge(Hash[params.zip(args)])) }
47
63
  end
48
64
 
49
- args = exp[1..].map { |c| self.eval(c, env) }
50
- env[exp.first]
51
- .call(*args)
65
+ # function application
66
+ values = exp.map { |c| self.eval(c, env) }
67
+ values[0].call(*values[1..])
68
+ end
69
+
70
+ # Evaluates list of lisp values e.g. Ldefine_a_1JLp_a_J
71
+ def eval_stmts(exp, env)
72
+ if !exp.is_a?(Array)
73
+ STDERR.puts 'eval_stmts: not a list'
74
+ exit 1
75
+ end
76
+
77
+ res = nil
78
+ exp.each do |stmt|
79
+ res = self.eval(stmt, env)
80
+ end
81
+
82
+ res
52
83
  end
53
84
 
54
85
  def parse(program)
@@ -57,6 +88,15 @@ class Lisp
57
88
  end
58
89
 
59
90
  def _parse(tokens)
91
+ stmts = []
92
+ while !tokens.empty?
93
+ stmts << parse_stmt(tokens)
94
+ end
95
+
96
+ stmts
97
+ end
98
+
99
+ def parse_stmt(tokens)
60
100
  return if tokens.empty?
61
101
 
62
102
  token = tokens.shift
@@ -68,7 +108,7 @@ class Lisp
68
108
  while tokens.first != :J
69
109
  raise 'unexpected end of input' if tokens.empty?
70
110
 
71
- list << _parse(tokens)
111
+ list << parse_stmt(tokens)
72
112
  end
73
113
  tokens.shift
74
114
 
@@ -84,9 +124,12 @@ class Lisp
84
124
  res = []
85
125
  cur = ''
86
126
  is_reading_digit = false
127
+ is_reading_string = false
87
128
  s.each_char do |c|
88
129
  case c
89
130
  when '_'
131
+ cur += ' ' and next if is_reading_string
132
+
90
133
  if cur != ''
91
134
  if is_reading_digit
92
135
  res.push cur.to_i
@@ -125,6 +168,25 @@ class Lisp
125
168
  end
126
169
 
127
170
  res.push :J
171
+ when 'Q'
172
+ if is_reading_string
173
+ res.push cur
174
+ cur = ''
175
+ is_reading_string = false
176
+ next
177
+ elsif is_reading_digit
178
+ res.push cur.to_i
179
+ cur = ''
180
+ is_reading_digit = false
181
+ is_reading_string = true
182
+ next
183
+ end
184
+
185
+ if cur != ''
186
+ cur += 'Q'
187
+ else
188
+ is_reading_string = true
189
+ end
128
190
  when '0'..'9'
129
191
  cur += c and next if cur != ''
130
192
 
@@ -155,7 +217,7 @@ module Kernel
155
217
  def eval_lisp(s)
156
218
  @l ||= Lisp.new
157
219
  @e ||= @l.initial_env
158
- @l.eval(@l.parse(s), @e)
220
+ @l.eval_stmts(@l.parse(s), @e)
159
221
  end
160
222
 
161
223
  def method_missing(m, *args, &block)
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: missinglisp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yajima Soichi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-10 00:00:00.000000000 Z
10
+ date: 2025-05-11 00:00:00.000000000 Z
11
11
  dependencies: []
12
+ description: Lisp programming using Ruby variable names
12
13
  email: jajima.jp@gmail.com
13
14
  executables: []
14
15
  extensions: []
@@ -18,7 +19,8 @@ files:
18
19
  homepage: https://github.com/jajimajp/missinglisp
19
20
  licenses:
20
21
  - MIT
21
- metadata: {}
22
+ metadata:
23
+ source_code_uri: https://github.com/jajimajp/missinglisp
22
24
  rdoc_options: []
23
25
  require_paths:
24
26
  - lib
@@ -26,7 +28,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
26
28
  requirements:
27
29
  - - ">="
28
30
  - !ruby/object:Gem::Version
29
- version: '0'
31
+ version: '3.0'
30
32
  required_rubygems_version: !ruby/object:Gem::Requirement
31
33
  requirements:
32
34
  - - ">="