nydp 0.0.10 → 0.0.10.1

Sign up to get free protection for your applications and to get access to all the features.
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))