lasp 0.6.0 → 0.7.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/CHANGELOG.md +17 -0
- data/README.md +9 -0
- data/lib/lasp/eval.rb +41 -21
- data/lib/lasp/repl.rb +22 -3
- data/lib/lasp/stdlib.lasp +36 -5
- data/lib/lasp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6fb8d2312d17d1d15be5e17ad26569f839789b3
|
4
|
+
data.tar.gz: 7c473de16a4e3c017af92fa423ef976c04b369ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4a30a116ecfeefb43ea5f02c2dd11c4686da9d338625d70ecaa11cad37284b3de0a4e7110d80fda135da9ece294902a839b715676dfc3084eaba8863ca89c6a
|
7
|
+
data.tar.gz: 2d39bb873b1698e27f462c141185561582cf8749a8cc920b97041658b657207018ae7f28b2d485afe6c189c1ee5f63f2f80833222f4ac0f0c6a4ff9958763ab0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Läsp changelog
|
2
2
|
|
3
|
+
## v0.7.0
|
4
|
+
|
5
|
+
- Arity is now enforced in function calls and will throw errors when mismatched
|
6
|
+
- Add methods to stdlib:
|
7
|
+
- `zero?`
|
8
|
+
- `list->str`
|
9
|
+
- `str->list`
|
10
|
+
- `->str`
|
11
|
+
- `reverse-str`
|
12
|
+
- `ruby-method`
|
13
|
+
- `pipe`
|
14
|
+
- REPL improvements:
|
15
|
+
- Automatically close trailing parentheses
|
16
|
+
- Change error prompt from `*>` to `!>`
|
17
|
+
- Return nil when pressing Ctrl+D (this used to cause an error)
|
18
|
+
- Many refactorings
|
19
|
+
|
3
20
|
## v0.6.0
|
4
21
|
|
5
22
|
- `<` and `>` now return false when given a list of equal items, they all **have to** increase or decrease.
|
data/README.md
CHANGED
@@ -78,6 +78,8 @@ Implemented as Ruby lambdas.
|
|
78
78
|
- `/`
|
79
79
|
- `<`
|
80
80
|
- `>`
|
81
|
+
- `<=`
|
82
|
+
- `>=`
|
81
83
|
- `=`
|
82
84
|
- `list`
|
83
85
|
- `head`
|
@@ -113,6 +115,7 @@ Implemented in Läsp itself.
|
|
113
115
|
- `complement`
|
114
116
|
- `even?`
|
115
117
|
- `odd?`
|
118
|
+
- `zero?`
|
116
119
|
- `len`
|
117
120
|
- `nth`
|
118
121
|
- `last`
|
@@ -126,6 +129,12 @@ Implemented in Läsp itself.
|
|
126
129
|
- `range`
|
127
130
|
- `max`
|
128
131
|
- `min`
|
132
|
+
- `ruby-method`
|
133
|
+
- `str->list`
|
134
|
+
- `list->str`
|
135
|
+
- `->str`
|
136
|
+
- `pipe`
|
137
|
+
- `reverse-str`
|
129
138
|
|
130
139
|
## Developing
|
131
140
|
|
data/lib/lasp/eval.rb
CHANGED
@@ -4,33 +4,53 @@ require "lasp/env"
|
|
4
4
|
module Lasp
|
5
5
|
module_function
|
6
6
|
|
7
|
-
def eval(
|
8
|
-
case
|
9
|
-
when Symbol then env.fetch(
|
10
|
-
when Array then eval_form(
|
11
|
-
else
|
7
|
+
def eval(form, env)
|
8
|
+
case form
|
9
|
+
when Symbol then env.fetch(form)
|
10
|
+
when Array then eval_form(form, env)
|
11
|
+
else form
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def eval_form(form, env)
|
16
16
|
head, *tail = *form
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
tail.map { |form| Lasp::eval(form, env) }.last
|
26
|
-
elsif head == :if
|
27
|
-
conditional, true_form, false_form = tail
|
28
|
-
Lasp::eval(conditional, env) ? Lasp::eval(true_form, env) : Lasp::eval(false_form, env)
|
29
|
-
elsif Proc === head
|
30
|
-
head.(*tail)
|
31
|
-
else
|
32
|
-
fn = Lasp::eval(head, env)
|
33
|
-
fn.(*tail.map { |form| Lasp::eval(form, env) })
|
18
|
+
case head
|
19
|
+
when :def then def_special_form(tail, env)
|
20
|
+
when :fn then fn_special_form(tail, env)
|
21
|
+
when :do then do_special_form(tail, env)
|
22
|
+
when :if then if_special_form(tail, env)
|
23
|
+
when Proc then head.(*tail)
|
24
|
+
else call_function(head, tail, env)
|
34
25
|
end
|
35
26
|
end
|
27
|
+
|
28
|
+
def call_function(symbol, args, env)
|
29
|
+
fn = Lasp::eval(symbol, env)
|
30
|
+
fn.(*args.map { |form| Lasp::eval(form, env) })
|
31
|
+
end
|
32
|
+
|
33
|
+
def def_special_form(form, env)
|
34
|
+
key, value = form
|
35
|
+
env[key] = Lasp::eval(value, env)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fn_special_form(form, env)
|
39
|
+
params, func = form
|
40
|
+
-> (*args) {
|
41
|
+
unless args.count == params.count
|
42
|
+
fail ArgumentError, "wrong number of arguments (#{args.count} for #{params.count})"
|
43
|
+
end
|
44
|
+
Lasp::eval(func, env.merge(Hash[params.zip(args)]))
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def do_special_form(form, env)
|
49
|
+
form.map { |form| Lasp::eval(form, env) }.last
|
50
|
+
end
|
51
|
+
|
52
|
+
def if_special_form(form, env)
|
53
|
+
conditional, true_form, false_form = form
|
54
|
+
Lasp::eval(conditional, env) ? Lasp::eval(true_form, env) : Lasp::eval(false_form, env)
|
55
|
+
end
|
36
56
|
end
|
data/lib/lasp/repl.rb
CHANGED
@@ -10,12 +10,31 @@ module Lasp
|
|
10
10
|
puts "((( Läsp v#{Lasp::VERSION} REPL (ctrl+c to exit) )))\n\n"
|
11
11
|
loop do
|
12
12
|
begin
|
13
|
-
|
14
|
-
|
13
|
+
history = true
|
14
|
+
input = Readline.readline("lasp> ", history).to_s
|
15
|
+
input = autoclose_parentheses(input)
|
16
|
+
result = Lasp::execute(input)
|
15
17
|
puts " => #{result.inspect}"
|
16
18
|
rescue
|
17
|
-
puts "
|
19
|
+
puts " !> #{$!}"
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
23
|
+
|
24
|
+
def autoclose_parentheses(input)
|
25
|
+
num_opens = input.chars.select { |c| c == "(" }.count
|
26
|
+
num_closes = input.chars.select { |c| c == ")" }.count
|
27
|
+
|
28
|
+
if num_opens > num_closes
|
29
|
+
missing_closes = num_opens - num_closes
|
30
|
+
|
31
|
+
puts " ?> Appending #{missing_closes} missing closing parentheses:"
|
32
|
+
corrected_input = input + (")" * missing_closes)
|
33
|
+
puts " ?> #{corrected_input}"
|
34
|
+
|
35
|
+
corrected_input
|
36
|
+
else
|
37
|
+
input
|
38
|
+
end
|
39
|
+
end
|
21
40
|
end
|
data/lib/lasp/stdlib.lasp
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
; If a list is empty
|
12
12
|
(def empty?
|
13
13
|
(fn (coll)
|
14
|
-
(= (head coll)
|
14
|
+
(= nil (head coll))))
|
15
15
|
|
16
16
|
; Modulus
|
17
17
|
(def mod
|
@@ -23,11 +23,15 @@
|
|
23
23
|
|
24
24
|
; If a number is even
|
25
25
|
(def even?
|
26
|
-
(fn (x) (
|
26
|
+
(fn (x) (zero? (mod x 2))))
|
27
27
|
|
28
28
|
; If a number is odd
|
29
29
|
(def odd? (complement even?))
|
30
30
|
|
31
|
+
; If a number is zero
|
32
|
+
(def zero?
|
33
|
+
(fn (x) (= 0 x)))
|
34
|
+
|
31
35
|
; Length of a list
|
32
36
|
(def len
|
33
37
|
(fn (coll)
|
@@ -38,7 +42,7 @@
|
|
38
42
|
; Gets an item in a list by index
|
39
43
|
(def nth
|
40
44
|
(fn (index coll)
|
41
|
-
(if (
|
45
|
+
(if (zero? index)
|
42
46
|
(head coll)
|
43
47
|
(nth (dec index) (tail coll)))))
|
44
48
|
|
@@ -85,14 +89,14 @@
|
|
85
89
|
; Take x items from list
|
86
90
|
(def take
|
87
91
|
(fn (num coll)
|
88
|
-
(if (
|
92
|
+
(if (zero? num)
|
89
93
|
(list)
|
90
94
|
(cons (head coll) (take (dec num) (tail coll))))))
|
91
95
|
|
92
96
|
; Drop x items from list
|
93
97
|
(def drop
|
94
98
|
(fn (num coll)
|
95
|
-
(if (
|
99
|
+
(if (zero? num)
|
96
100
|
coll
|
97
101
|
(drop (dec num) (tail coll)))))
|
98
102
|
|
@@ -118,3 +122,30 @@
|
|
118
122
|
(fn (acc item) (if (> acc item) item acc))
|
119
123
|
(head coll)
|
120
124
|
(tail coll))))
|
125
|
+
|
126
|
+
; Takes a method from Ruby-land and returns a Lasp function
|
127
|
+
(def ruby-method
|
128
|
+
(fn (meth)
|
129
|
+
(fn (arg)
|
130
|
+
(. arg meth))))
|
131
|
+
|
132
|
+
; Convert string to list
|
133
|
+
(def str->list (ruby-method :chars))
|
134
|
+
|
135
|
+
; Convert list to string
|
136
|
+
(def list->str (ruby-method :join))
|
137
|
+
|
138
|
+
; Convert most things to a string
|
139
|
+
(def ->str (ruby-method :to_s))
|
140
|
+
|
141
|
+
; Pass a value in order through a list of functions
|
142
|
+
(def pipe
|
143
|
+
(fn (item fns)
|
144
|
+
(if (empty? fns)
|
145
|
+
item
|
146
|
+
(pipe ((head fns) item) (tail fns)))))
|
147
|
+
|
148
|
+
; Reverses a string
|
149
|
+
(def reverse-str
|
150
|
+
(fn (str)
|
151
|
+
(pipe str (list str->list reverse list->str))))
|
data/lib/lasp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lasp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jimmy Börjesson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|