nydp 0.0.10 → 0.0.10.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 878f0dba9573b146bf3bf438d5c8d7792f9fc1e9
4
- data.tar.gz: 57c14a21f93ec56968f9f4e3bae5ee634eac9608
3
+ metadata.gz: ebb185874a9dc692fc52b40620ef19385b49d644
4
+ data.tar.gz: 6e63e8ffcf047ee20894abde0b0bb9ed497ba6ca
5
5
  SHA512:
6
- metadata.gz: 2f8fa342fe36104a3d957bb3bd354b79f185948fc9779abd7c146dbe092065a29ad31cb4193ae8a8aeded94b4a4671c3075d05e9a112404dde554dbbe1887290
7
- data.tar.gz: 6999b8761df3c3d19909d0341d208b08fb9793e926066838ab99329c6b87fece28dd085e56ba82970e96ebbd10a439137ce76b12f6513c853fd83f09eb7dbbff
6
+ metadata.gz: a80c411a9b87d57de98530cb1729b4b10e9b406b09ca6a21a1fb7d0b40afa5323e9a2b545aa202faab76332b3eff0c32297677c3816f26a46e4715ef419ca1db
7
+ data.tar.gz: ddc4305e8078bfb08e78b1b9c8891788d5501a3c085ba03a970ca6d59408deea2c6984f04d8d6579daa9e44596da1001dceee45af95f03d3b0a4c5a9e2b1e21f
data/.gitignore CHANGED
@@ -15,5 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- lib/lisp/scratch.nydp
18
+ lib/lisp/scratch
19
19
  .#*
@@ -0,0 +1,13 @@
1
+ ; -*- lisp -*-
2
+ ;;
3
+ ;; Acknowledgements to Paul Graham. Some nydp features (including,
4
+ ;; but not limited to, 'do, 'rfn, 'loop, 'for) are stolen directly from arc.arc
5
+ ;;
6
+
7
+ (assign list (fn args args))
8
+ (assign caar (fn (arg) (car (car arg))))
9
+ (assign cadr (fn (arg) (car (cdr arg))))
10
+ (assign cdar (fn (arg) (cdr (car arg))))
11
+ (assign cddr (fn (arg) (cdr (cdr arg))))
12
+ (assign no (fn (arg) (cond arg nil t)))
13
+ (assign just (fn (arg) arg))
@@ -0,0 +1,130 @@
1
+
2
+
3
+ (assign mac-expand (fn (macfn name body)
4
+ (cond macfn
5
+ (pre-compile (apply macfn body))
6
+ (cons name body))))
7
+
8
+ (assign macs (hash))
9
+
10
+ (assign pre-compile-expr
11
+ (fn (name body)
12
+ (mac-expand (hash-get macs name) name body)))
13
+
14
+ (assign pre-compile-each
15
+ (fn (args)
16
+ (cond args
17
+ (cond (pair? args)
18
+ (cons (pre-compile (car args))
19
+ (pre-compile-each (cdr args)))
20
+ args))))
21
+
22
+ (assign pre-compile-msg
23
+ (fn (src compiled)
24
+ (pre-compile-msg "pre-compile" src "\n -> " compiled)
25
+ compiled))
26
+
27
+ (assign pre-compile-raw
28
+ (fn (arg)
29
+ (cond (pair? arg)
30
+ (cond (eq? (car arg) 'quote)
31
+ arg
32
+ (pre-compile-each (pre-compile-expr (car arg) (cdr arg))))
33
+ arg)))
34
+
35
+ (assign pre-compile-debug
36
+ (fn (arg)
37
+ (pre-compile-msg arg (pre-compile-raw arg))))
38
+
39
+ (assign debug-pre-compile
40
+ (fn (arg)
41
+ (assign pre-compile (cond arg pre-compile-debug pre-compile-raw))))
42
+
43
+ (debug-pre-compile nil)
44
+
45
+ (hash-set macs 'def
46
+ (fn (name args . body)
47
+ (list 'assign
48
+ name
49
+ (+ (list 'fn args)
50
+ body))))
51
+
52
+ (def qq-handle-unquote-splicing (arg rest level)
53
+ (cond (eq? level 0)
54
+ (qq-do-unquote-splicing arg rest level)
55
+ (qq-skip-unquote-splicing arg rest level)))
56
+
57
+ (def qq-do-unquote-splicing (arg rest level)
58
+ (cond (no rest)
59
+ arg
60
+ (list '+
61
+ (pre-compile arg)
62
+ (qq-quasiquote rest level))))
63
+
64
+ (def qq-skip-unquote-splicing (arg rest level)
65
+ (list 'cons
66
+ (list 'list ''unquote-splicing (qq-quasiquote arg (- level 1)))
67
+ (qq-quasiquote rest level)))
68
+
69
+ (def qq-handle-quasiquote (arg rest level)
70
+ (list 'cons
71
+ (list 'list ''quasiquote (qq-quasiquote arg (+ level 1)))
72
+ (qq-quasiquote rest level)))
73
+
74
+ (def qq-handle-unquote (arg rest level)
75
+ (list 'cons
76
+ (qq-maybe-unquote arg level)
77
+ (qq-quasiquote rest level)))
78
+
79
+ (def qq-unquote-recurse (arg rest level)
80
+ (list 'cons
81
+ (qq-quasiquote arg level)
82
+ (qq-quasiquote rest level)))
83
+
84
+ (def qq-handle-plain (arg rest level)
85
+ (list 'cons
86
+ (list 'quote arg)
87
+ (qq-quasiquote rest level)))
88
+
89
+ (def qq-unquote? (arg rest level)
90
+ (cond (pair? arg)
91
+ (cond (eq? (car arg) 'unquote)
92
+ (qq-handle-unquote (cadr arg) rest level)
93
+ (cond (eq? (car arg) 'unquote-splicing)
94
+ (qq-handle-unquote-splicing (cadr arg) rest level)
95
+ (cond (eq? (car arg) 'quasiquote)
96
+ (qq-handle-quasiquote (cadr arg) rest level)
97
+ (qq-unquote-recurse arg rest level))))
98
+ (qq-handle-plain arg rest level)))
99
+
100
+ (def qq-maybe-unquote (xs level)
101
+ (cond (eq? level 0)
102
+ (pre-compile xs)
103
+ (list 'list ''unquote (qq-quasiquote xs (- level 1)))))
104
+
105
+ (def qq-quasiquote (xs level)
106
+ (cond (no xs)
107
+ nil
108
+ (cond (pair? xs)
109
+ (cond (eq? (car xs) 'unquote)
110
+ (qq-maybe-unquote (cadr xs) level)
111
+ (cond (eq? (car xs) 'unquote-splicing)
112
+ (qq-handle-unquote-splicing (cadr xs) nil level)
113
+ (cond (eq? (car xs) 'quasiquote)
114
+ (list 'list ''quasiquote (qq-quasiquote (cdr xs) (+ level 1)))
115
+ (qq-unquote? (car xs) (cdr xs) level))))
116
+ (list 'quote xs))))
117
+
118
+ (hash-set macs 'quasiquote
119
+ (fn (arg) (qq-quasiquote arg 0)))
120
+
121
+ (hash-set macs 'mac (fn (name args . body)
122
+ `(hash-set macs ',name (fn ,args ,@body))))
123
+
124
+ (mac if args
125
+ (cond (no args) nil
126
+ (cond (cdr args)
127
+ (cond (cddr args)
128
+ `(cond ,(car args) ,(cadr args) (if ,@(cddr args)))
129
+ `(cond ,(car args) ,(cadr args)))
130
+ (car args))))
@@ -0,0 +1,8 @@
1
+ ; -*- lisp -*-
2
+
3
+ (def map (f things)
4
+ (if (no things)
5
+ nil
6
+ (pair? things)
7
+ (cons (f (car things)) (map f (cdr things)))
8
+ (map f (list things))))
@@ -0,0 +1,148 @@
1
+ ; -*- lisp -*-
2
+
3
+ (mac unless (arg . body)
4
+ `(if (no ,arg) (do ,@body)))
5
+
6
+ (def expand-colon-syntax (first rest)
7
+ (if (no rest)
8
+ `(apply ,first args)
9
+ `(,first ,(expand-colon-syntax (car rest) (cdr rest)))))
10
+
11
+ (mac colon-syntax args
12
+ (if (eq? (car args) '||)
13
+ (error "Irregular ': syntax: got ~(inspect args) : not prefix-syntax : in ~(joinstr ":" (cons pfx rest))")
14
+ `(fn args ,(expand-colon-syntax (car args) (cdr args)))))
15
+
16
+ (mac bang-syntax (pfx . rest)
17
+ (if (no (eq? pfx '||))
18
+ (error "Irregular '! syntax: got prefix ~(inspect pfx) in ~(joinstr "!" (cons pfx rest))"))
19
+ (if (cdr rest)
20
+ (error "Irregular '! syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "!" (cons pfx rest))")
21
+ (if (caris 'colon-syntax (car rest))
22
+ `(colon-syntax no ,@(cdar rest))
23
+ `(colon-syntax no ,(car rest)))))
24
+
25
+ (mac and args
26
+ (if args
27
+ (if (cdr args)
28
+ `(if ,(car args) (and ,@(cdr args)))
29
+ (car args))
30
+ 't))
31
+
32
+ (mac do args
33
+ `((fn nil ,@args)))
34
+
35
+ (mac when (condition . body)
36
+ `(cond ,condition (do ,@body)))
37
+
38
+ (def pairs (things)
39
+ (if (no things) nil
40
+ (no (cdr things)) (list (list (car things)))
41
+ (cons (list (car things) (cadr things))
42
+ (pairs (cddr things)))))
43
+
44
+ (mac with (parms . body)
45
+ `((fn ,(map car (pairs parms))
46
+ ,@body)
47
+ ,@(map cadr (pairs parms))))
48
+
49
+ (mac let (var val . body)
50
+ `(with (,var ,val) ,@body))
51
+
52
+ (let uniq-counter 0
53
+ (def uniq (prefix)
54
+ (sym (joinstr "-"
55
+ (list prefix
56
+ (assign uniq-counter
57
+ (+ uniq-counter 1))))))
58
+ (def reset-uniq-counter ()
59
+ (assign uniq-counter 0)))
60
+
61
+ (mac w/uniq (vars . body)
62
+ (if (pair? vars)
63
+ `(with ,(apply + (map (fn (n) (list n '(uniq ',n))) vars))
64
+ ,@body)
65
+ `(let ,vars (uniq ',vars) ,@body)))
66
+
67
+ (mac or args
68
+ (cond args
69
+ (w/uniq ora
70
+ `(let ,ora ,(car args)
71
+ (cond ,ora ,ora (or ,@(cdr args)))))))
72
+
73
+ (mac pop (xs)
74
+ (w/uniq gp
75
+ `(let ,gp (car ,xs)
76
+ (assign ,xs (cdr ,xs))
77
+ ,gp)))
78
+
79
+ (def build-keyword-args (pairs)
80
+ (map (fn (ab) `(list (quote ,(car ab)) ,@(cdr ab))) pairs))
81
+
82
+ (def build-hash-get-key (name)
83
+ (if (pair? name)
84
+ (if (caris 'unquote name)
85
+ (cadr name)
86
+ name)
87
+ (list 'quote name)))
88
+
89
+ ;; (build-hash-getters '(a b c))
90
+ ;; => (hash-get (hash-get a 'b) 'c)
91
+ (def build-hash-getters (names acc)
92
+ (if (no acc)
93
+ (build-hash-getters (cdr names) (car names))
94
+ names
95
+ (build-hash-getters (cdr names) `(hash-get ,acc ,(build-hash-get-key (car names))))
96
+ acc))
97
+
98
+ (def build-hash-lookup-from (root names)
99
+ (build-hash-getters (cons root names) nil))
100
+
101
+ (mac hash-lookup (names)
102
+ (build-hash-getters names nil))
103
+
104
+ (mac dot-syntax names `(hash-lookup ,names))
105
+ (mac dollar-syntax (_ name) `(,name))
106
+
107
+ (def dot-syntax-assignment (names value-expr)
108
+ (let rnames (rev names)
109
+ `(hash-set ,(build-hash-getters (rev (cdr rnames)) nil)
110
+ ,(build-hash-get-key:car rnames)
111
+ ,value-expr)))
112
+
113
+ (mac = (name value)
114
+ (if (isa 'symbol name)
115
+ `(assign ,name ,value)
116
+ (caris 'dot-syntax name)
117
+ (dot-syntax-assignment (cdr name) value)))
118
+
119
+ (def brace-list-hash-key (k)
120
+ (if (isa 'symbol k) `(quote ,k)
121
+ (caris 'unquote k) (cadr k)
122
+ k))
123
+
124
+ (def brace-list-build-hash (args)
125
+ (w/uniq hash
126
+ (let mappings (pairs args)
127
+ `(let ,hash (hash)
128
+ ,@(map (fn (m) `(hash-set ,hash ,(brace-list-hash-key (car m)) ,(cadr m))) mappings)
129
+ ,hash))))
130
+
131
+ (def build-ampersand-syntax (arg)
132
+ (if (caris 'dot-syntax arg)
133
+ `(fn (obj) ,(build-hash-lookup-from 'obj (cdr arg)))
134
+ `(fn (obj) ,(build-hash-lookup-from 'obj (list arg)))))
135
+
136
+ (mac ampersand-syntax (pfx . rest)
137
+ (if (no (eq? pfx '||))
138
+ (error "Irregular '& syntax: got prefix ~(inspect pfx) in ~(joinstr "&" (cons pfx rest))"))
139
+ (if (cdr rest)
140
+ (error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "&" (cons pfx rest))")
141
+ (build-ampersand-syntax (car rest))))
142
+
143
+ (mac brace-list-mono (arg) arg)
144
+
145
+ (mac brace-list args
146
+ (if (no (cdr args))
147
+ `(brace-list-mono ,(car args))
148
+ (brace-list-build-hash args)))
@@ -0,0 +1,122 @@
1
+ ; -*- lisp -*-
2
+
3
+ (def each (f acc things)
4
+ (if things
5
+ (each f (f acc (car things)) (cdr things))
6
+ acc))
7
+
8
+ (def eachr (f things)
9
+ (when things
10
+ (eachr f (cdr things))
11
+ (f (car things))))
12
+
13
+ (def zip (a b)
14
+ (if a
15
+ (cons (list (car a) (car b))
16
+ (zip (cdr a) (cdr b)))))
17
+
18
+ (def reversify (things acc)
19
+ (if (no things)
20
+ acc
21
+ (reversify (cdr things)
22
+ (cons (car things) acc))))
23
+
24
+ (def rev (things) (reversify things nil))
25
+
26
+ (mac push (x things)
27
+ `(assign ,things (cons ,x ,things)))
28
+
29
+ (def flatten (things)
30
+ (let acc nil
31
+ (let flattenize nil
32
+ (assign flattenize (fn (x)
33
+ (if (pair? x)
34
+ (eachr flattenize x)
35
+ (push x acc))))
36
+ (flattenize things))
37
+ acc))
38
+
39
+ (def joinstr (txt . things)
40
+ (let joinables (flatten things)
41
+ (apply +
42
+ (to-string (car joinables))
43
+ (flatten (zip (map (fn (_) txt) (cdr joinables))
44
+ (map to-string (cdr joinables)))))))
45
+
46
+ (def string-pieces pieces
47
+ (joinstr "" pieces))
48
+
49
+ (def nth (n things)
50
+ (if (eq? n 0)
51
+ (car things)
52
+ (nth (- n 1) (cdr things))))
53
+
54
+ (def iso (x y)
55
+ (or (eq? x y)
56
+ (and (pair? x)
57
+ (pair? y)
58
+ (iso (car x) (car y))
59
+ (iso (cdr x) (cdr y)))))
60
+
61
+ (def isa (type obj) (eq? (type-of obj) type))
62
+ (def sym? (arg) (isa 'symbol arg))
63
+ (def string? (arg) (isa 'string arg))
64
+ (mac just (arg) arg)
65
+ (def quotify (arg) `(quote ,arg))
66
+
67
+ (def caris (obj things)
68
+ (and (isa 'pair things)
69
+ (eq? (car things) obj)))
70
+
71
+ (def len (xs)
72
+ (if (pair? xs) (+ 1 (len (cdr xs)))
73
+ (string? xs) (string-length xs)
74
+ 0))
75
+
76
+ (assign dynamics (hash))
77
+
78
+ (mac dynamic (name)
79
+ (hash-set dynamics name t)
80
+ (let with-mac-name (sym "w/~name")
81
+ (w/uniq prev
82
+ `(do
83
+ (mac ,with-mac-name (new-value . body)
84
+ (w/uniq result
85
+ `(let ,',prev (hash-get (thread-locals) ',',name)
86
+ (hash-set (thread-locals) ',',name ,new-value)
87
+ (let ,result (do ,@body)
88
+ (hash-set (thread-locals) ',',name ,',prev)
89
+ ,result))))
90
+ (def ,name () (hash-get (thread-locals) ',name))))))
91
+
92
+ (mac on-err (handler . body)
93
+ `(handle-error (fn (err) ,handler)
94
+ (fn () ,@body)))
95
+
96
+ (mac ensure (protection . body)
97
+ `(ensuring (fn () ,protection)
98
+ (fn () ,@body)))
99
+
100
+ (mac rfn (name parms . body)
101
+ `(let ,name nil
102
+ (assign ,name (fn ,parms ,@body))))
103
+
104
+ (mac afn (parms . body)
105
+ `(rfn self ,parms ,@body))
106
+
107
+ (mac loop (start test update . body)
108
+ (w/uniq (gfn gparm)
109
+ `(do ,start
110
+ ((rfn ,gfn (,gparm)
111
+ (if ,gparm
112
+ (do ,@body ,update (,gfn ,test))))
113
+ ,test))))
114
+
115
+ (mac for (v init max . body)
116
+ (w/uniq (gi gm)
117
+ `(with (,v nil ,gi ,init ,gm (+ ,max 1))
118
+ (loop (assign ,v ,gi) (< ,v ,gm) (assign ,v (+ ,v 1))
119
+ ,@body))))
120
+
121
+ (mac mapx (things x expr)
122
+ `(map (fn (,x) ,expr) ,things))
@@ -106,7 +106,18 @@
106
106
 
107
107
  ("recursive hash assignment with embedded dollar-syntax"
108
108
  (pre-compile '(= a.$b.,c.d 42))
109
- (hash-set (hash-get (hash-get a (b)) c) 'd 42)))
109
+ (hash-set (hash-get (hash-get a (b)) c) 'd 42))
110
+
111
+ (suite "merge"
112
+ ("merge with symbol keys"
113
+ (let h (hash-merge { a 1 b 2 c 3 } { a 99 c 98 d 97 })
114
+ (list h.a h.b h.c h.d (hash-keys h) ))
115
+ (99 2 98 97 (a b c d )))
116
+
117
+ ("merge with mixed symbol and string and int keys"
118
+ (let h (hash-merge { a 1 "b" 2 3 'c } { a 99 b 98 3 "foo" })
119
+ (cons (hash-keys h) (mapx (hash-keys h) k h.,k)))
120
+ ((a "b" 3 b) 99 2 "foo" 98))))
110
121
 
111
122
  (suite "isa"
112
123
  ("t for 'pair for list"
@@ -54,3 +54,14 @@ class Nydp::Builtin::HashKeys
54
54
  end
55
55
  end
56
56
  end
57
+
58
+ class Nydp::Builtin::HashMerge
59
+ include Nydp::Helper, Nydp::Builtin::Base
60
+
61
+ def builtin_invoke vm, args
62
+ hash_0 = args.car
63
+ hash_1 = args.cdr.car
64
+
65
+ vm.push_arg hash_0.merge hash_1
66
+ end
67
+ end
@@ -13,9 +13,7 @@ module Nydp
13
13
  end
14
14
 
15
15
  def loadfiles
16
- b = relative_path('../lisp/boot.nydp')
17
- t = relative_path('../lisp/test-runner.nydp')
18
- [b,t]
16
+ Dir.glob(relative_path '../lisp/core-*.nydp').sort
19
17
  end
20
18
 
21
19
  def testfiles
@@ -64,6 +62,7 @@ module Nydp
64
62
  Symbol.mk(:"hash-get", ns).assign(Nydp::Builtin::HashGet.new ns)
65
63
  Symbol.mk(:"hash-set", ns).assign(Nydp::Builtin::HashSet.new)
66
64
  Symbol.mk(:"hash-keys", ns).assign(Nydp::Builtin::HashKeys.new(ns))
65
+ Symbol.mk(:"hash-merge", ns).assign(Nydp::Builtin::HashMerge.new)
67
66
  Symbol.mk(:"vm-info", ns).assign Nydp::Builtin::VmInfo.new
68
67
  Symbol.mk(:"pre-compile", ns).assign Nydp::Builtin::PreCompile.new
69
68
  end
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.10.1"
3
3
  end
@@ -30,6 +30,19 @@ describe Nydp::Hash do
30
30
  end
31
31
  end
32
32
 
33
+ describe "hash merge" do
34
+ it "merges two hashes" do
35
+ ns = { }
36
+ Nydp.setup(ns)
37
+ hash_0 = { foo: 12, bar: 34}
38
+ hash_1 = { foo: 49, zap: 87}
39
+
40
+ merged = Nydp.apply_function ns, "hash-merge", hash_0, hash_1
41
+
42
+ expect(merged).to eq({ foo: 49, bar: 34, zap: 87 })
43
+ end
44
+ end
45
+
33
46
  describe "nydp hashes" do
34
47
  describe "new hash" do
35
48
  it "returns a new Nydp hash" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nydp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conan Dalton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-24 00:00:00.000000000 Z
11
+ date: 2015-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,9 +84,12 @@ files:
84
84
  - Rakefile
85
85
  - bin/nydp
86
86
  - bin/nydp-tests
87
- - lib/lisp/bm.nydp
88
- - lib/lisp/boot.nydp
89
- - lib/lisp/test-runner.nydp
87
+ - lib/lisp/core-00.nydp
88
+ - lib/lisp/core-01-precompile.nydp
89
+ - lib/lisp/core-02-utils.nydp
90
+ - lib/lisp/core-03-syntax.nydp
91
+ - lib/lisp/core-04-utils.nydp
92
+ - lib/lisp/core-05-test-runner.nydp
90
93
  - lib/lisp/tests/boot-tests.nydp
91
94
  - lib/lisp/tests/dynamic-scope-test.nydp
92
95
  - lib/lisp/tests/error-tests.nydp
@@ -1,18 +0,0 @@
1
- (def bm-pythag ()
2
- (for i 1 100
3
- (for j 1 100
4
- (sqrt (+ (* i i) (* j j))))))
5
-
6
- (def bmf (f n)
7
- (for b 1 n (f)))
8
-
9
- (def bm (f n)
10
- (let time (millisecs)
11
- (bmf f n)
12
- (let elapsed (- (millisecs) time)
13
- (p "took: ~elapsed ms")
14
- (p "~n iterations, ~(/ elapsed n) ms per iteration")))
15
- nil)
16
-
17
- (def rbs ()
18
- (bm bm-pythag 20))
@@ -1,429 +0,0 @@
1
- ; -*- lisp -*-
2
-
3
- ;;
4
- ;; Acknowledgements to Paul Graham. Some nydp features defined in this file (including,
5
- ;; but not limited to, 'do, 'rfn, 'loop, 'for) are stolen directly from arc.arc
6
- ;;
7
-
8
- (assign last-cons (fn (xs)
9
- (cond (pair? (cdr xs))
10
- (last-cons (cdr xs))
11
- xs)))
12
-
13
-
14
- (assign append-list (fn (list-1 list-2)
15
- (cdr-set (last-cons list-1) list-2)
16
- list-1))
17
-
18
- (assign list (fn args args))
19
- (assign last (fn (arg) (car (last-cons arg))))
20
- (assign caar (fn (arg) (car (car arg))))
21
- (assign cadr (fn (arg) (car (cdr arg))))
22
- (assign cdar (fn (arg) (cdr (car arg))))
23
- (assign cddr (fn (arg) (cdr (cdr arg))))
24
- (assign no (fn (arg) (cond arg nil t)))
25
- (assign just (fn (arg) arg))
26
-
27
- (assign mac-expand (fn (macfn name body)
28
- (cond macfn
29
- (pre-compile (apply macfn body))
30
- (cons name body))))
31
-
32
- (assign macs (hash))
33
-
34
- (assign pre-compile-expr
35
- (fn (name body)
36
- (mac-expand (hash-get macs name) name body)))
37
-
38
- (assign pre-compile-each
39
- (fn (args)
40
- (cond args
41
- (cond (pair? args)
42
- (cons (pre-compile (car args))
43
- (pre-compile-each (cdr args)))
44
- args))))
45
-
46
- (assign pre-compile-msg
47
- (fn (src compiled)
48
- (pre-compile-msg "pre-compile" src "\n -> " compiled)
49
- compiled))
50
-
51
- (assign pre-compile-raw
52
- (fn (arg)
53
- (cond (pair? arg)
54
- (cond (eq? (car arg) 'quote)
55
- arg
56
- (pre-compile-each (pre-compile-expr (car arg) (cdr arg))))
57
- arg)))
58
-
59
- (assign pre-compile-debug
60
- (fn (arg)
61
- (pre-compile-msg arg (pre-compile-raw arg))))
62
-
63
- (assign debug-pre-compile
64
- (fn (arg)
65
- (assign pre-compile (cond arg pre-compile-debug pre-compile-raw))))
66
-
67
- (debug-pre-compile nil)
68
-
69
- (hash-set macs 'def
70
- (fn (name args . body)
71
- (list 'assign
72
- name
73
- (+ (list 'fn args)
74
- body))))
75
-
76
- (def qq-handle-unquote-splicing (arg rest level)
77
- (cond (eq? level 0)
78
- (qq-do-unquote-splicing arg rest level)
79
- (qq-skip-unquote-splicing arg rest level)))
80
-
81
- (def qq-do-unquote-splicing (arg rest level)
82
- (cond (no rest)
83
- arg
84
- (list '+
85
- (pre-compile arg)
86
- (qq-quasiquote rest level))))
87
-
88
- (def qq-skip-unquote-splicing (arg rest level)
89
- (list 'cons
90
- (list 'list ''unquote-splicing (qq-quasiquote arg (- level 1)))
91
- (qq-quasiquote rest level)))
92
-
93
- (def qq-handle-quasiquote (arg rest level)
94
- (list 'cons
95
- (list 'list ''quasiquote (qq-quasiquote arg (+ level 1)))
96
- (qq-quasiquote rest level)))
97
-
98
- (def qq-handle-unquote (arg rest level)
99
- (list 'cons
100
- (qq-maybe-unquote arg level)
101
- (qq-quasiquote rest level)))
102
-
103
- (def qq-unquote-recurse (arg rest level)
104
- (list 'cons
105
- (qq-quasiquote arg level)
106
- (qq-quasiquote rest level)))
107
-
108
- (def qq-handle-plain (arg rest level)
109
- (list 'cons
110
- (list 'quote arg)
111
- (qq-quasiquote rest level)))
112
-
113
- (def qq-unquote? (arg rest level)
114
- (cond (pair? arg)
115
- (cond (eq? (car arg) 'unquote)
116
- (qq-handle-unquote (cadr arg) rest level)
117
- (cond (eq? (car arg) 'unquote-splicing)
118
- (qq-handle-unquote-splicing (cadr arg) rest level)
119
- (cond (eq? (car arg) 'quasiquote)
120
- (qq-handle-quasiquote (cadr arg) rest level)
121
- (qq-unquote-recurse arg rest level))))
122
- (qq-handle-plain arg rest level)))
123
-
124
- (def qq-maybe-unquote (xs level)
125
- (cond (eq? level 0)
126
- (pre-compile xs)
127
- (list 'list ''unquote (qq-quasiquote xs (- level 1)))))
128
-
129
- (def qq-quasiquote (xs level)
130
- (cond (no xs)
131
- nil
132
- (cond (pair? xs)
133
- (cond (eq? (car xs) 'unquote)
134
- (qq-maybe-unquote (cadr xs) level)
135
- (cond (eq? (car xs) 'unquote-splicing)
136
- (qq-handle-unquote-splicing (cadr xs) nil level)
137
- (cond (eq? (car xs) 'quasiquote)
138
- (list 'list ''quasiquote (qq-quasiquote (cdr xs) (+ level 1)))
139
- (qq-unquote? (car xs) (cdr xs) level))))
140
- (list 'quote xs))))
141
-
142
- (hash-set macs 'quasiquote
143
- (fn (arg) (qq-quasiquote arg 0)))
144
-
145
- (hash-set macs 'mac (fn (name args . body)
146
- `(hash-set macs ',name (fn ,args ,@body))))
147
-
148
- (mac if args
149
- (cond (no args) nil
150
- (cond (cdr args)
151
- (cond (cddr args)
152
- `(cond ,(car args) ,(cadr args) (if ,@(cddr args)))
153
- `(cond ,(car args) ,(cadr args)))
154
- (car args))))
155
-
156
- (mac unless (arg . body)
157
- `(if (no ,arg) (do ,@body)))
158
-
159
- (def expand-colon-syntax (first rest)
160
- (if (no rest)
161
- `(apply ,first args)
162
- `(,first ,(expand-colon-syntax (car rest) (cdr rest)))))
163
-
164
- (mac colon-syntax args
165
- (if (eq? (car args) '||)
166
- (error "Irregular ': syntax: got ~(inspect args) : not prefix-syntax : in ~(joinstr ":" (cons pfx rest))")
167
- `(fn args ,(expand-colon-syntax (car args) (cdr args)))))
168
-
169
- (mac bang-syntax (pfx . rest)
170
- (if (no (eq? pfx '||))
171
- (error "Irregular '! syntax: got prefix ~(inspect pfx) in ~(joinstr "!" (cons pfx rest))"))
172
- (if (cdr rest)
173
- (error "Irregular '! syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "!" (cons pfx rest))")
174
- (if (caris 'colon-syntax (car rest))
175
- `(colon-syntax no ,@(cdar rest))
176
- `(colon-syntax no ,(car rest)))))
177
-
178
- (mac and args
179
- (if args
180
- (if (cdr args)
181
- `(if ,(car args) (and ,@(cdr args)))
182
- (car args))
183
- 't))
184
-
185
- (mac do args
186
- `((fn nil ,@args)))
187
-
188
- (mac when (condition . body)
189
- `(cond ,condition (do ,@body)))
190
-
191
- (def map (f things)
192
- (if (no things)
193
- nil
194
- (pair? things)
195
- (cons (f (car things)) (map f (cdr things)))
196
- (map f (list things))))
197
-
198
- (def pairs (things)
199
- (if (no things) nil
200
- (no (cdr things)) (list (list (car things)))
201
- (cons (list (car things) (cadr things))
202
- (pairs (cddr things)))))
203
-
204
- (mac with (parms . body)
205
- `((fn ,(map car (pairs parms))
206
- ,@body)
207
- ,@(map cadr (pairs parms))))
208
-
209
- (mac let (var val . body)
210
- `(with (,var ,val) ,@body))
211
-
212
- (def each (f acc things)
213
- (if things
214
- (each f (f acc (car things)) (cdr things))
215
- acc))
216
-
217
- (def eachr (f things)
218
- (when things
219
- (eachr f (cdr things))
220
- (f (car things))))
221
-
222
- (def zip (a b)
223
- (if a
224
- (cons (list (car a) (car b))
225
- (zip (cdr a) (cdr b)))))
226
-
227
- (def reversify (things acc)
228
- (if (no things)
229
- acc
230
- (reversify (cdr things)
231
- (cons (car things) acc))))
232
-
233
- (def rev (things) (reversify things nil))
234
-
235
- (mac push (x things)
236
- `(assign ,things (cons ,x ,things)))
237
-
238
- (def flatten (things)
239
- (let acc nil
240
- (let flattenize nil
241
- (assign flattenize (fn (x)
242
- (if (pair? x)
243
- (eachr flattenize x)
244
- (push x acc))))
245
- (flattenize things))
246
- acc))
247
-
248
- (def joinstr (txt . things)
249
- (let joinables (flatten things)
250
- (apply +
251
- (to-string (car joinables))
252
- (flatten (zip (map (fn (_) txt) (cdr joinables))
253
- (map to-string (cdr joinables)))))))
254
-
255
- (def string-pieces pieces
256
- (joinstr "" pieces))
257
-
258
- (let uniq-counter 0
259
- (def uniq (prefix)
260
- (sym (joinstr "-"
261
- (list prefix
262
- (assign uniq-counter
263
- (+ uniq-counter 1))))))
264
- (def reset-uniq-counter ()
265
- (assign uniq-counter 0)))
266
-
267
- (mac w/uniq (vars . body)
268
- (if (pair? vars)
269
- `(with ,(apply + (map (fn (n) (list n '(uniq ',n))) vars))
270
- ,@body)
271
- `(let ,vars (uniq ',vars) ,@body)))
272
-
273
- (mac or args
274
- (cond args
275
- (w/uniq ora
276
- `(let ,ora ,(car args)
277
- (cond ,ora ,ora (or ,@(cdr args)))))))
278
-
279
- (mac pop (xs)
280
- (w/uniq gp
281
- `(let ,gp (car ,xs)
282
- (assign ,xs (cdr ,xs))
283
- ,gp)))
284
-
285
- (def nth (n things)
286
- (if (eq? n 0)
287
- (car things)
288
- (nth (- n 1) (cdr things))))
289
-
290
- (def iso (x y)
291
- (or (eq? x y)
292
- (and (pair? x)
293
- (pair? y)
294
- (iso (car x) (car y))
295
- (iso (cdr x) (cdr y)))))
296
-
297
- (def isa (type obj) (eq? (type-of obj) type))
298
- (def sym? (arg) (isa 'symbol arg))
299
- (def string? (arg) (isa 'string arg))
300
- (mac just (arg) arg)
301
- (def quotify (arg) `(quote ,arg))
302
-
303
- (def caris (obj things)
304
- (and (isa 'pair things)
305
- (eq? (car things) obj)))
306
-
307
- (def len (xs)
308
- (if (pair? xs) (+ 1 (len (cdr xs)))
309
- (string? xs) (string-length xs)
310
- 0))
311
-
312
- (def build-keyword-args (pairs)
313
- (map (fn (ab) `(list (quote ,(car ab)) ,@(cdr ab))) pairs))
314
-
315
- (assign dynamics (hash))
316
-
317
- (mac dynamic (name)
318
- (hash-set dynamics name t)
319
- (let with-mac-name (sym "w/~name")
320
- (w/uniq prev
321
- `(do
322
- (mac ,with-mac-name (new-value . body)
323
- (w/uniq result
324
- `(let ,',prev (hash-get (thread-locals) ',',name)
325
- (hash-set (thread-locals) ',',name ,new-value)
326
- (let ,result (do ,@body)
327
- (hash-set (thread-locals) ',',name ,',prev)
328
- ,result))))
329
- (def ,name () (hash-get (thread-locals) ',name))))))
330
-
331
- (def build-hash-get-key (name)
332
- (if (pair? name)
333
- (if (caris 'unquote name)
334
- (cadr name)
335
- name)
336
- (list 'quote name)))
337
-
338
- ;; (build-hash-getters '(a b c))
339
- ;; => (hash-get (hash-get a 'b) 'c)
340
- (def build-hash-getters (names acc)
341
- (if (no acc)
342
- (build-hash-getters (cdr names) (car names))
343
- names
344
- (build-hash-getters (cdr names) `(hash-get ,acc ,(build-hash-get-key (car names))))
345
- acc))
346
-
347
- (def build-hash-lookup-from (root names)
348
- (build-hash-getters (cons root names) nil))
349
-
350
- (mac hash-lookup (names)
351
- (build-hash-getters names nil))
352
-
353
- (mac dot-syntax names `(hash-lookup ,names))
354
- (mac dollar-syntax (_ name) `(,name))
355
-
356
- (def dot-syntax-assignment (names value-expr)
357
- (let rnames (rev names)
358
- `(hash-set ,(build-hash-getters (rev (cdr rnames)) nil)
359
- ,(build-hash-get-key:car rnames)
360
- ,value-expr)))
361
-
362
- (mac = (name value)
363
- (if (isa 'symbol name)
364
- `(assign ,name ,value)
365
- (caris 'dot-syntax name)
366
- (dot-syntax-assignment (cdr name) value)))
367
-
368
- (def brace-list-hash-key (k)
369
- (if (isa 'symbol k) `(quote ,k)
370
- (caris 'unquote k) (cadr k)
371
- k))
372
-
373
- (def brace-list-build-hash (args)
374
- (w/uniq hash
375
- (let mappings (pairs args)
376
- `(let ,hash (hash)
377
- ,@(map (fn (m) `(hash-set ,hash ,(brace-list-hash-key (car m)) ,(cadr m))) mappings)
378
- ,hash))))
379
-
380
- (def build-ampersand-syntax (arg)
381
- (if (caris 'dot-syntax arg)
382
- `(fn (obj) ,(build-hash-lookup-from 'obj (cdr arg)))
383
- `(fn (obj) ,(build-hash-lookup-from 'obj (list arg)))))
384
-
385
- (mac ampersand-syntax (pfx . rest)
386
- (if (no (eq? pfx '||))
387
- (error "Irregular '& syntax: got prefix ~(inspect pfx) in ~(joinstr "&" (cons pfx rest))"))
388
- (if (cdr rest)
389
- (error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "&" (cons pfx rest))")
390
- (build-ampersand-syntax (car rest))))
391
-
392
- (mac brace-list-mono (arg) arg)
393
-
394
- (mac brace-list args
395
- (if (no (cdr args))
396
- `(brace-list-mono ,(car args))
397
- (brace-list-build-hash args)))
398
-
399
- (mac on-err (handler . body)
400
- `(handle-error (fn (err) ,handler)
401
- (fn () ,@body)))
402
-
403
- (mac ensure (protection . body)
404
- `(ensuring (fn () ,protection)
405
- (fn () ,@body)))
406
-
407
- (mac rfn (name parms . body)
408
- `(let ,name nil
409
- (assign ,name (fn ,parms ,@body))))
410
-
411
- (mac afn (parms . body)
412
- `(rfn self ,parms ,@body))
413
-
414
- (mac loop (start test update . body)
415
- (w/uniq (gfn gparm)
416
- `(do ,start
417
- ((rfn ,gfn (,gparm)
418
- (if ,gparm
419
- (do ,@body ,update (,gfn ,test))))
420
- ,test))))
421
-
422
- (mac for (v init max . body)
423
- (w/uniq (gi gm)
424
- `(with (,v nil ,gi ,init ,gm (+ ,max 1))
425
- (loop (assign ,v ,gi) (< ,v ,gm) (assign ,v (+ ,v 1))
426
- ,@body))))
427
-
428
- (mac mapx (things x expr)
429
- `(map (fn (,x) ,expr) ,things))