lasp 0.8.0 → 0.9.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 +30 -0
- data/DOCUMENTATION.md +942 -0
- data/EXAMPLES.md +57 -34
- data/README.md +7 -92
- data/bin/lasp +1 -1
- data/lib/lasp.rb +4 -2
- data/lib/lasp/corelib.rb +24 -22
- data/lib/lasp/errors.rb +4 -1
- data/lib/lasp/ext.rb +33 -0
- data/lib/lasp/fn.rb +2 -2
- data/lib/lasp/interpreter.rb +79 -0
- data/lib/lasp/params.rb +17 -8
- data/lib/lasp/parser.rb +22 -12
- data/lib/lasp/repl.rb +50 -29
- data/lib/lasp/stdlib.lasp +113 -109
- data/lib/lasp/stdmacros.lasp +31 -0
- data/lib/lasp/version.rb +1 -1
- metadata +5 -5
- data/lib/lasp/eval.rb +0 -66
- data/lib/lasp/parameters.rb +0 -93
- data/lib/lasp/representation.rb +0 -17
data/lib/lasp/stdmacros.lasp
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
(list 'def name
|
9
9
|
(list 'macro params body))))
|
10
10
|
|
11
|
+
|
11
12
|
; Shorthand for defining functions
|
12
13
|
;
|
13
14
|
; (defn f (x) (+ x 1))
|
@@ -18,6 +19,36 @@
|
|
18
19
|
(list 'def name
|
19
20
|
(list 'fn params (cons 'do body))))
|
20
21
|
|
22
|
+
|
23
|
+
; Creates local bindings.
|
24
|
+
;
|
25
|
+
; It does this by (ab)using closures. It rewrites the form as a recursively
|
26
|
+
; nested tree of functions, declaring parameters and instantly executing the
|
27
|
+
; function passing in corresponding arguments. This should be considered an
|
28
|
+
; implementation detail, let can (and should) be used without knowledge or
|
29
|
+
; regard to that it creates closures behind the scenes.
|
30
|
+
|
31
|
+
; Example:
|
32
|
+
; (let (one 1
|
33
|
+
; two (+ one 1)) ; Previous bindings are available
|
34
|
+
; (+ one two))
|
35
|
+
; ; => 3
|
36
|
+
;
|
37
|
+
; expands to:
|
38
|
+
; ((fn (one) ((fn (two) (do (+ one two))) (+ one 1))) 1)
|
39
|
+
(defn let*
|
40
|
+
(bindings body)
|
41
|
+
(if (empty? bindings)
|
42
|
+
(cons 'do body)
|
43
|
+
(list
|
44
|
+
(list 'fn (list (first bindings)) (let* (drop 2 bindings) body))
|
45
|
+
(second bindings))))
|
46
|
+
|
47
|
+
(defm let
|
48
|
+
(bindings & body)
|
49
|
+
(let* bindings body))
|
50
|
+
|
51
|
+
|
21
52
|
; See unevaluated form the macro expands to for debugging macros
|
22
53
|
;
|
23
54
|
; This simply uses the fact that `apply` already has this effect
|
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.9.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-02-
|
11
|
+
date: 2016-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -48,6 +48,7 @@ extra_rdoc_files: []
|
|
48
48
|
files:
|
49
49
|
- ".gitignore"
|
50
50
|
- CHANGELOG.md
|
51
|
+
- DOCUMENTATION.md
|
51
52
|
- EXAMPLES.md
|
52
53
|
- Gemfile
|
53
54
|
- LICENSE.txt
|
@@ -59,14 +60,13 @@ files:
|
|
59
60
|
- lib/lasp/corelib.rb
|
60
61
|
- lib/lasp/env.rb
|
61
62
|
- lib/lasp/errors.rb
|
62
|
-
- lib/lasp/
|
63
|
+
- lib/lasp/ext.rb
|
63
64
|
- lib/lasp/fn.rb
|
65
|
+
- lib/lasp/interpreter.rb
|
64
66
|
- lib/lasp/macro.rb
|
65
|
-
- lib/lasp/parameters.rb
|
66
67
|
- lib/lasp/params.rb
|
67
68
|
- lib/lasp/parser.rb
|
68
69
|
- lib/lasp/repl.rb
|
69
|
-
- lib/lasp/representation.rb
|
70
70
|
- lib/lasp/stdlib.lasp
|
71
71
|
- lib/lasp/stdmacros.lasp
|
72
72
|
- lib/lasp/version.rb
|
data/lib/lasp/eval.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require "lasp/env"
|
2
|
-
require "lasp/fn"
|
3
|
-
require "lasp/macro"
|
4
|
-
|
5
|
-
module Lasp
|
6
|
-
module_function
|
7
|
-
|
8
|
-
def eval(form, env)
|
9
|
-
case form
|
10
|
-
when Symbol then env.fetch(form)
|
11
|
-
when Array then eval_form(form, env)
|
12
|
-
else form
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def eval_form(form, env)
|
17
|
-
head, *tail = *form
|
18
|
-
|
19
|
-
case head
|
20
|
-
when :def then def_special_form(tail, env)
|
21
|
-
when :fn then fn_special_form(tail, env)
|
22
|
-
when :do then do_special_form(tail, env)
|
23
|
-
when :if then if_special_form(tail, env)
|
24
|
-
when :quote then quote_special_form(tail, env)
|
25
|
-
when :macro then macro_special_form(tail, env)
|
26
|
-
else call_function(head, tail, env)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def call_function(symbol, args, env)
|
31
|
-
fn = Lasp::eval(symbol, env)
|
32
|
-
|
33
|
-
case fn
|
34
|
-
when Macro then Lasp::eval(fn.(*args), env)
|
35
|
-
else fn.(*args.map { |form| Lasp::eval(form, env) })
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def def_special_form(form, env)
|
40
|
-
key, value = form
|
41
|
-
env[key] = Lasp::eval(value, env)
|
42
|
-
end
|
43
|
-
|
44
|
-
def fn_special_form(form, env)
|
45
|
-
params, func = form
|
46
|
-
Fn.new(params, func, env)
|
47
|
-
end
|
48
|
-
|
49
|
-
def do_special_form(form, env)
|
50
|
-
form.map { |form| Lasp::eval(form, env) }.last
|
51
|
-
end
|
52
|
-
|
53
|
-
def if_special_form(form, env)
|
54
|
-
conditional, true_form, false_form = form
|
55
|
-
Lasp::eval(conditional, env) ? Lasp::eval(true_form, env) : Lasp::eval(false_form, env)
|
56
|
-
end
|
57
|
-
|
58
|
-
def quote_special_form(form, _)
|
59
|
-
form.first
|
60
|
-
end
|
61
|
-
|
62
|
-
def macro_special_form(form, env)
|
63
|
-
params, func = form
|
64
|
-
Macro.new(params, func, env)
|
65
|
-
end
|
66
|
-
end
|
data/lib/lasp/parameters.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
module Lasp
|
2
|
-
module Parameters
|
3
|
-
def self.new(params)
|
4
|
-
if params.include?(:&)
|
5
|
-
RestParameters.new(params)
|
6
|
-
else
|
7
|
-
FixedParameters.new(params)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class FixedParameters
|
12
|
-
attr_reader :parameter_list
|
13
|
-
|
14
|
-
def initialize(parameter_list)
|
15
|
-
@parameter_list = parameter_list
|
16
|
-
valid_signature!
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_h(args)
|
20
|
-
enforce_arity!(args)
|
21
|
-
Hash[parameter_list.zip(args)]
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_s
|
25
|
-
"(" + parameter_list.join(" ") + ")"
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def enforce_arity!(args)
|
31
|
-
if args.count != arity
|
32
|
-
fail ArgumentError, "wrong number of arguments (#{args.count} for #{arity})"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def valid_signature!
|
37
|
-
if duplicate_parameter?
|
38
|
-
fail SyntaxError, "Parameter names have to be unique. a is used more than once"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def duplicate_parameter?
|
43
|
-
parameter_list.uniq.length != parameter_list.length
|
44
|
-
end
|
45
|
-
|
46
|
-
def arity
|
47
|
-
parameter_list.count
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class RestParameters < FixedParameters
|
52
|
-
def to_h(args)
|
53
|
-
enforce_arity!(args)
|
54
|
-
|
55
|
-
ordered = parameter_list[0, minimum_arguments]
|
56
|
-
rest = parameter_list.last
|
57
|
-
|
58
|
-
env = ordered.zip(args.take(ordered.length))
|
59
|
-
env << [ rest, args.drop(ordered.length) ]
|
60
|
-
|
61
|
-
Hash[env]
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def valid_signature!
|
67
|
-
if multiple_rest_arguments? || ampersand_not_second_to_last?
|
68
|
-
fail SyntaxError, "Rest-arguments may only be used once, at the end, with a single binding."
|
69
|
-
end
|
70
|
-
super
|
71
|
-
end
|
72
|
-
|
73
|
-
def multiple_rest_arguments?
|
74
|
-
parameter_list.select { |b| b == :& }.length > 1
|
75
|
-
end
|
76
|
-
|
77
|
-
def ampersand_not_second_to_last?
|
78
|
-
parameter_list.find_index(:&) != minimum_arguments
|
79
|
-
end
|
80
|
-
|
81
|
-
def minimum_arguments
|
82
|
-
parameter_list.count - 2
|
83
|
-
end
|
84
|
-
|
85
|
-
def enforce_arity!(args)
|
86
|
-
if args.count < minimum_arguments
|
87
|
-
fail ArgumentError, "wrong number of arguments (#{args.count} for #{minimum_arguments}+)"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
data/lib/lasp/representation.rb
DELETED