atomy 0.1.1 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +13 -0
- data/LICENSE.md +201 -0
- data/bin/atomy +16 -133
- data/kernel/array.ay +6 -0
- data/kernel/atomy.ay +18 -0
- data/kernel/condition.ay +171 -271
- data/kernel/control-flow.ay +197 -192
- data/kernel/core.ay +120 -0
- data/kernel/data.ay +83 -39
- data/kernel/define.ay +84 -93
- data/kernel/doc.ay +282 -449
- data/kernel/dynamic.ay +25 -29
- data/kernel/file.ay +9 -0
- data/kernel/grammar.ay +267 -0
- data/kernel/hash.ay +17 -0
- data/kernel/interpolation.ay +59 -0
- data/kernel/io.ay +70 -244
- data/kernel/let-macro.ay +24 -0
- data/kernel/let-pattern.ay +24 -0
- data/kernel/loop.ay +80 -0
- data/kernel/mutation.ay +53 -0
- data/kernel/particles.ay +176 -39
- data/kernel/patterns.ay +527 -191
- data/kernel/pretty.ay +311 -277
- data/kernel/quotes.ay +29 -0
- data/kernel/range.ay +4 -0
- data/kernel/regexp.ay +23 -0
- data/kernel/repl.ay +83 -109
- data/kernel/stack-local.ay +21 -0
- data/lib/atomy.rb +37 -0
- data/lib/atomy/bootstrap.rb +256 -0
- data/lib/atomy/code/assign.rb +64 -0
- data/lib/atomy/code/block.rb +98 -0
- data/lib/atomy/code/class_variable.rb +17 -0
- data/lib/atomy/code/constant.rb +21 -0
- data/lib/atomy/code/define.rb +242 -0
- data/lib/atomy/code/define_function.rb +51 -0
- data/lib/atomy/code/define_method.rb +20 -0
- data/lib/atomy/code/false.rb +9 -0
- data/lib/atomy/code/instance_variable.rb +15 -0
- data/lib/atomy/code/integer.rb +13 -0
- data/lib/atomy/code/list.rb +17 -0
- data/lib/atomy/code/nil.rb +9 -0
- data/lib/atomy/code/pattern.rb +23 -0
- data/lib/atomy/code/pattern/and.rb +61 -0
- data/lib/atomy/code/pattern/quasi_quote.rb +185 -0
- data/lib/atomy/code/pattern/splat.rb +29 -0
- data/lib/atomy/code/pattern/wildcard.rb +37 -0
- data/lib/atomy/code/quasi_quote.rb +118 -0
- data/lib/atomy/code/quote.rb +13 -0
- data/lib/atomy/code/self.rb +9 -0
- data/lib/atomy/code/send.rb +110 -0
- data/lib/atomy/code/sequence.rb +23 -0
- data/lib/atomy/code/string_literal.rb +53 -0
- data/lib/atomy/code/symbol.rb +13 -0
- data/lib/atomy/code/true.rb +9 -0
- data/lib/atomy/code/undefined.rb +9 -0
- data/lib/atomy/code/variable.rb +17 -0
- data/lib/atomy/codeloader.rb +218 -0
- data/lib/atomy/compiler.rb +57 -0
- data/lib/atomy/errors.rb +54 -0
- data/lib/atomy/grammar.rb +2278 -0
- data/lib/atomy/locals.rb +75 -0
- data/lib/atomy/message_structure.rb +277 -0
- data/lib/atomy/method.rb +343 -0
- data/lib/atomy/module.rb +144 -0
- data/lib/atomy/node/constructable.rb +169 -0
- data/lib/atomy/node/equality.rb +113 -0
- data/lib/atomy/node/meta.rb +206 -0
- data/lib/atomy/node/pretty.rb +108 -0
- data/lib/atomy/parser.rb +21 -0
- data/lib/atomy/pattern.rb +26 -0
- data/lib/atomy/pattern/and.rb +59 -0
- data/lib/atomy/pattern/attribute.rb +16 -0
- data/lib/atomy/pattern/class_variable.rb +15 -0
- data/lib/atomy/pattern/equality.rb +42 -0
- data/lib/atomy/pattern/instance_variable.rb +15 -0
- data/lib/atomy/pattern/kind_of.rb +20 -0
- data/lib/atomy/pattern/or.rb +48 -0
- data/lib/atomy/pattern/quasi_quote.rb +164 -0
- data/lib/atomy/pattern/splat.rb +15 -0
- data/lib/atomy/pattern/wildcard.rb +18 -0
- data/lib/atomy/rubygems.rb +48 -0
- data/lib/atomy/version.rb +3 -0
- metadata +169 -134
- data/COPYING +0 -30
- data/README.md +0 -1
- data/kernel/block.ay +0 -30
- data/kernel/boot.ay +0 -10
- data/kernel/comparison.ay +0 -61
- data/kernel/concurrency.ay +0 -84
- data/kernel/cosmetics.ay +0 -3
- data/kernel/data-delta.ay +0 -105
- data/kernel/documentation.ay +0 -135
- data/kernel/errors.ay +0 -6
- data/kernel/format.ay +0 -13
- data/kernel/format/data.ay +0 -89
- data/kernel/format/formatter.ay +0 -345
- data/kernel/format/parser.ay +0 -13
- data/kernel/hashes.ay +0 -39
- data/kernel/namespaces.ay +0 -63
- data/kernel/node.ay +0 -48
- data/kernel/operators.ay +0 -28
- data/kernel/precision.ay +0 -148
- data/kernel/therie.ay +0 -204
- data/lib/ast/binary_send.rb +0 -44
- data/lib/ast/block.rb +0 -268
- data/lib/ast/constant.rb +0 -88
- data/lib/ast/internal/assign.rb +0 -19
- data/lib/ast/internal/block_pass.rb +0 -21
- data/lib/ast/internal/catch.rb +0 -247
- data/lib/ast/internal/class.rb +0 -30
- data/lib/ast/internal/class_variable.rb +0 -23
- data/lib/ast/internal/define.rb +0 -174
- data/lib/ast/internal/ensure.rb +0 -135
- data/lib/ast/internal/file.rb +0 -14
- data/lib/ast/internal/global_variable.rb +0 -20
- data/lib/ast/internal/if_then_else.rb +0 -24
- data/lib/ast/internal/instance_variable.rb +0 -17
- data/lib/ast/internal/let_macro.rb +0 -35
- data/lib/ast/internal/macro_quote.rb +0 -23
- data/lib/ast/internal/match.rb +0 -53
- data/lib/ast/internal/module.rb +0 -30
- data/lib/ast/internal/pattern.rb +0 -17
- data/lib/ast/internal/return.rb +0 -29
- data/lib/ast/internal/set.rb +0 -19
- data/lib/ast/internal/singleton_class.rb +0 -18
- data/lib/ast/internal/splat.rb +0 -14
- data/lib/ast/internal/when.rb +0 -24
- data/lib/ast/list.rb +0 -25
- data/lib/ast/macro.rb +0 -37
- data/lib/ast/node.rb +0 -599
- data/lib/ast/operator.rb +0 -21
- data/lib/ast/particle.rb +0 -13
- data/lib/ast/primitive.rb +0 -20
- data/lib/ast/quasi_quote.rb +0 -20
- data/lib/ast/quote.rb +0 -13
- data/lib/ast/send.rb +0 -104
- data/lib/ast/splice.rb +0 -32
- data/lib/ast/string.rb +0 -23
- data/lib/ast/unary.rb +0 -44
- data/lib/ast/unquote.rb +0 -45
- data/lib/ast/variable.rb +0 -64
- data/lib/atomy.kpeg.rb +0 -3995
- data/lib/code_loader.rb +0 -137
- data/lib/compiler/compiler.rb +0 -155
- data/lib/compiler/stages.rb +0 -81
- data/lib/formatter.kpeg.rb +0 -1394
- data/lib/macros.rb +0 -317
- data/lib/method.rb +0 -261
- data/lib/namespace.rb +0 -236
- data/lib/parser.rb +0 -28
- data/lib/patterns.rb +0 -276
- data/lib/patterns/any.rb +0 -21
- data/lib/patterns/attribute.rb +0 -59
- data/lib/patterns/block_pass.rb +0 -54
- data/lib/patterns/constant.rb +0 -33
- data/lib/patterns/default.rb +0 -44
- data/lib/patterns/head_tail.rb +0 -63
- data/lib/patterns/list.rb +0 -77
- data/lib/patterns/match.rb +0 -45
- data/lib/patterns/named.rb +0 -55
- data/lib/patterns/named_class.rb +0 -46
- data/lib/patterns/named_global.rb +0 -46
- data/lib/patterns/named_instance.rb +0 -46
- data/lib/patterns/particle.rb +0 -29
- data/lib/patterns/quasi_quote.rb +0 -184
- data/lib/patterns/quote.rb +0 -33
- data/lib/patterns/singleton_class.rb +0 -31
- data/lib/patterns/splat.rb +0 -57
- data/lib/util.rb +0 -37
data/kernel/let-macro.ay
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
use(require("core"))
|
2
|
+
use(require("define"))
|
3
|
+
use(require("patterns"))
|
4
|
+
|
5
|
+
require("atomy/bootstrap")
|
6
|
+
|
7
|
+
let-macro = class:
|
8
|
+
def(initialize(@body, @macros)) {}
|
9
|
+
|
10
|
+
def(bytecode(gen, mod)):
|
11
|
+
new = Atomy Module new: use(mod)
|
12
|
+
|
13
|
+
@macros each [`(~pat = ~exp)]:
|
14
|
+
definer = Atomy Bootstrap macro-definer(
|
15
|
+
Atomy Grammar AST QuasiQuote new(pat)
|
16
|
+
exp
|
17
|
+
)
|
18
|
+
|
19
|
+
new evaluate(definer, new compile-context)
|
20
|
+
|
21
|
+
new compile(gen, @body)
|
22
|
+
|
23
|
+
macro(let-macro(~*ms): ~*body):
|
24
|
+
let-macro new(`(do: ~*body), ms)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
use(require("core"))
|
2
|
+
use(require("define"))
|
3
|
+
use(require("patterns"))
|
4
|
+
|
5
|
+
require("atomy/bootstrap")
|
6
|
+
|
7
|
+
let-pattern = class:
|
8
|
+
def(initialize(@body, @patterns)) {}
|
9
|
+
|
10
|
+
def(bytecode(gen, mod)):
|
11
|
+
new = Atomy Module new: use(mod)
|
12
|
+
|
13
|
+
@patterns each [`(~pat = ~exp)]:
|
14
|
+
definer = Atomy Bootstrap pattern-definer(
|
15
|
+
Atomy Grammar AST QuasiQuote new(pat)
|
16
|
+
exp
|
17
|
+
)
|
18
|
+
|
19
|
+
new evaluate(definer, new compile-context)
|
20
|
+
|
21
|
+
new compile(gen, @body)
|
22
|
+
|
23
|
+
macro(let-pattern(~*ms): ~*body):
|
24
|
+
let-pattern new(`(do: ~*body), ms)
|
data/kernel/loop.ay
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
use(require("core"))
|
2
|
+
use(require("define"))
|
3
|
+
use(require("dynamic"))
|
4
|
+
use(require("control-flow"))
|
5
|
+
use(require("patterns"))
|
6
|
+
use(require("let-macro"))
|
7
|
+
use(require("data"))
|
8
|
+
use(require("mutation"))
|
9
|
+
|
10
|
+
tags = dynamic(Hash new)
|
11
|
+
|
12
|
+
Atomy Grammar AST open:
|
13
|
+
data(GoTo(@name))
|
14
|
+
|
15
|
+
def(GoTo bytecode(gen, mod)):
|
16
|
+
gen goto(^tags fetch(@name))
|
17
|
+
|
18
|
+
labels = class:
|
19
|
+
def(initialize(@branches)) {}
|
20
|
+
|
21
|
+
def(bytecode(gen, mod)):
|
22
|
+
new-tags = Hash new
|
23
|
+
|
24
|
+
lbls = @branches collect [name, body]:
|
25
|
+
new-tags[name] = gen new-label
|
26
|
+
|
27
|
+
with(tags = new-tags):
|
28
|
+
lbls zip(@branches) each [l, [_, body]]:
|
29
|
+
l set!
|
30
|
+
mod compile(gen, body)
|
31
|
+
gen pop
|
32
|
+
|
33
|
+
gen push-nil
|
34
|
+
|
35
|
+
|
36
|
+
macro(labels: ~*branches):
|
37
|
+
branch-pairs = branches collect [`(~n: ~*body)]:
|
38
|
+
[n text, `(do: ~*body)]
|
39
|
+
|
40
|
+
`(let-macro(go(~'~name) = GoTo new(name text)):
|
41
|
+
~(labels new(branch-pairs)))
|
42
|
+
|
43
|
+
macro(while(~test): ~*body):
|
44
|
+
`(labels:
|
45
|
+
loop:
|
46
|
+
unless(~test):
|
47
|
+
go(done)
|
48
|
+
|
49
|
+
let-macro(break = 'go(done),
|
50
|
+
next = 'go(loop)):
|
51
|
+
~*body
|
52
|
+
|
53
|
+
go(loop)
|
54
|
+
|
55
|
+
done {})
|
56
|
+
|
57
|
+
macro(until(~test): ~*body):
|
58
|
+
`(labels:
|
59
|
+
loop:
|
60
|
+
when(~test):
|
61
|
+
go(done)
|
62
|
+
|
63
|
+
let-macro(break = 'go(done),
|
64
|
+
next = 'go(loop)):
|
65
|
+
~*body
|
66
|
+
|
67
|
+
go(loop)
|
68
|
+
|
69
|
+
done {})
|
70
|
+
|
71
|
+
macro(loop: ~*body):
|
72
|
+
`(labels:
|
73
|
+
loop:
|
74
|
+
let-macro(break = 'go(done),
|
75
|
+
next = 'go(loop)):
|
76
|
+
~*body
|
77
|
+
|
78
|
+
go(loop)
|
79
|
+
|
80
|
+
done {})
|
data/kernel/mutation.ay
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
use(require("define"))
|
2
|
+
use(require("patterns"))
|
3
|
+
use(require("let-pattern"))
|
4
|
+
sl = require("stack-local")
|
5
|
+
|
6
|
+
-- variable mutation
|
7
|
+
let-pattern(Identifier = pattern(`(Word | (`(~Word)! | `(~Word)?)))):
|
8
|
+
macro(~(x & Identifier) += ~y): `(&~x = (~x + ~y))
|
9
|
+
macro(~(x & Identifier) -= ~y): `(&~x = (~x - ~y))
|
10
|
+
macro(~(x & Identifier) *= ~y): `(&~x = (~x * ~y))
|
11
|
+
macro(~(x & Identifier) **= ~y): `(&~x = (~x ** ~y))
|
12
|
+
macro(~(x & Identifier) /= ~y): `(&~x = (~x / ~y))
|
13
|
+
macro(~(x & Identifier) &= ~y): `(&~x = (~x & ~y))
|
14
|
+
macro(~(x & Identifier) |= ~y): `(&~x = (~x | ~y))
|
15
|
+
|
16
|
+
fn(attr-mutator(recv, attr, op, val)):
|
17
|
+
r = sl Local new
|
18
|
+
`(do:
|
19
|
+
~(r set(recv))
|
20
|
+
~r ~attr = ~(Atomy Grammar AST Infix new(`(~r ~attr), val, op)))
|
21
|
+
|
22
|
+
fn(index-mutator(recv, args, op, val)):
|
23
|
+
r = sl Local new
|
24
|
+
als = args collect [a]: sl Local new
|
25
|
+
`(do:
|
26
|
+
~(r set(recv))
|
27
|
+
~*(als zip(args) collect [[l, v]]: l set(v))
|
28
|
+
~r[~*als] = ~(Atomy Grammar AST Infix new(`(~r[~*als]), val, op)))
|
29
|
+
|
30
|
+
macro(~r ~(x & Identifier) += ~y): attr-mutator(r, x, ."+", y)
|
31
|
+
macro(~r ~(x & Identifier) -= ~y): attr-mutator(r, x, ."-", y)
|
32
|
+
macro(~r ~(x & Identifier) *= ~y): attr-mutator(r, x, ."*", y)
|
33
|
+
macro(~r ~(x & Identifier) **= ~y): attr-mutator(r, x, ."**", y)
|
34
|
+
macro(~r ~(x & Identifier) /= ~y): attr-mutator(r, x, ."/", y)
|
35
|
+
macro(~r ~(x & Identifier) &= ~y): attr-mutator(r, x, ."&", y)
|
36
|
+
macro(~r ~(x & Identifier) |= ~y): attr-mutator(r, x, ."|", y)
|
37
|
+
|
38
|
+
macro(~r[~*x] += ~y): index-mutator(r, x, ."+", y)
|
39
|
+
macro(~r[~*x] -= ~y): index-mutator(r, x, ."-", y)
|
40
|
+
macro(~r[~*x] *= ~y): index-mutator(r, x, ."*", y)
|
41
|
+
macro(~r[~*x] **= ~y): index-mutator(r, x, ."**", y)
|
42
|
+
macro(~r[~*x] /= ~y): index-mutator(r, x, ."/", y)
|
43
|
+
macro(~r[~*x] &= ~y): index-mutator(r, x, ."&", y)
|
44
|
+
macro(~r[~*x] |= ~y): index-mutator(r, x, ."|", y)
|
45
|
+
|
46
|
+
-- other (ivar) mutation
|
47
|
+
macro(~x += ~y): `(~x = (~x + ~y))
|
48
|
+
macro(~x -= ~y): `(~x = (~x - ~y))
|
49
|
+
macro(~x *= ~y): `(~x = (~x * ~y))
|
50
|
+
macro(~x **= ~y): `(~x = (~x ** ~y))
|
51
|
+
macro(~x /= ~y): `(~x = (~x / ~y))
|
52
|
+
macro(~x &= ~y): `(~x = (~x & ~y))
|
53
|
+
macro(~x |= ~y): `(~x = (~x | ~y))
|
data/kernel/particles.ay
CHANGED
@@ -1,53 +1,190 @@
|
|
1
|
-
|
1
|
+
use(require("core"))
|
2
|
+
use(require("define"))
|
3
|
+
use(require("data"))
|
4
|
+
use(require("control-flow"))
|
5
|
+
use(require("patterns"))
|
6
|
+
use(require("mutation"))
|
2
7
|
|
3
|
-
|
4
|
-
wildcard('_) := '_undefined
|
5
|
-
wildcard(x) := x
|
8
|
+
data(Particle(@receiver, @message, @arguments))
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
~(if(x private)
|
10
|
-
then: '_undefined
|
11
|
-
else: wildcard(x receiver))
|
12
|
-
~(Atomy::AST::Particle new(0, x method-name))
|
13
|
-
~*(x arguments collect [c]: wildcard(c))
|
14
|
-
])
|
10
|
+
def(Particle call(*args) &blk):
|
11
|
+
to-proc call(*args) &blk
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
~(if(x private)
|
19
|
-
then: '_undefined
|
20
|
-
else: wildcard(x lhs))
|
21
|
-
~(Atomy::AST::Particle new(0, x operator))
|
22
|
-
~(wildcard(x rhs))
|
23
|
-
])
|
13
|
+
Particle open:
|
14
|
+
alias-method(.[], .call)
|
24
15
|
|
25
|
-
|
26
|
-
|
27
|
-
|
16
|
+
def(Particle to-proc):
|
17
|
+
[*args] &blk:
|
18
|
+
unless(args size >= arity):
|
19
|
+
raise(ArgumentError new((("given " + args size to-s) + ", expected ") + arity to-s))
|
28
20
|
|
29
|
-
|
30
|
-
|
21
|
+
[recv, cur] =
|
22
|
+
if(@receiver equal?(_))
|
23
|
+
then: [args[0], 1]
|
24
|
+
else: [@receiver, 0]
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
filled =
|
27
|
+
@arguments collect [v]:
|
28
|
+
if(v equal?(_) && (args size >= cur))
|
29
|
+
then:
|
30
|
+
cur += 1
|
31
|
+
args[cur - 1]
|
32
|
+
else:
|
33
|
+
v
|
35
34
|
|
36
|
-
|
37
|
-
x [idx] = a
|
35
|
+
recv __send__(@message, *filled) &blk
|
38
36
|
|
39
|
-
|
37
|
+
def(Particle arity):
|
38
|
+
required-args = 0
|
39
|
+
when(@receiver equal?(_)):
|
40
|
+
required-args += 1
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
@arguments each [v]:
|
43
|
+
when(v equal?(_)):
|
44
|
+
required-args += 1
|
43
45
|
|
44
|
-
|
46
|
+
required-args
|
45
47
|
|
46
|
-
|
48
|
+
def(Particle == other):
|
49
|
+
other is-a?(self class) && (
|
50
|
+
(other receiver == @receiver) && (
|
51
|
+
(other message == @message) && (
|
52
|
+
other arguments == @arguments)))
|
47
53
|
|
48
|
-
|
54
|
+
def(Symbol call(recv)): to-proc call(recv)
|
49
55
|
|
50
|
-
|
51
|
-
call(*args) := to-proc [*args]
|
56
|
+
def(Symbol arity): 1
|
52
57
|
|
53
|
-
|
58
|
+
macro(.[~a, ~*as]):
|
59
|
+
`(Particle new(_, .[], [~a, ~*as]))
|
60
|
+
|
61
|
+
macro(.((~x)(~*as))):
|
62
|
+
`(Particle new(_, .~x, [~*as]))
|
63
|
+
|
64
|
+
macro(.(~r (~x)(~*as))):
|
65
|
+
`(Particle new(~r, .~x, [~*as]))
|
66
|
+
|
67
|
+
macro(.(~r [~*as])):
|
68
|
+
`(Particle new(~r, .[], [~*as]))
|
69
|
+
|
70
|
+
macro(.~(x & Infix)):
|
71
|
+
`(Particle new(
|
72
|
+
~(x left || '_)
|
73
|
+
.~(StringLiteral new(x operator to-s))
|
74
|
+
[~(x right)]))
|
75
|
+
|
76
|
+
particle-klass = Particle
|
77
|
+
|
78
|
+
Atomy Pattern open:
|
79
|
+
self data(Particle(@receiver, @message, @arguments))
|
80
|
+
|
81
|
+
def(Particle target): particle-klass
|
82
|
+
|
83
|
+
def(Particle matches?(value)):
|
84
|
+
when(value is-a?(Symbol)):
|
85
|
+
&value = particle-klass new(_, value, [])
|
86
|
+
|
87
|
+
unless(value is-a?(particle-klass)):
|
88
|
+
return(false)
|
89
|
+
|
90
|
+
when(value message != @message):
|
91
|
+
return(false)
|
92
|
+
|
93
|
+
unless(@receiver matches?(value receiver)):
|
94
|
+
return(false)
|
95
|
+
|
96
|
+
@arguments matches?(value arguments)
|
97
|
+
|
98
|
+
def(Particle assign(scope, value)):
|
99
|
+
when(value is-a?(Symbol)):
|
100
|
+
&value = particle-klass new(_, value, [])
|
101
|
+
|
102
|
+
@receiver assign(scope, value receiver)
|
103
|
+
@arguments assign(scope, value arguments)
|
104
|
+
|
105
|
+
particle-pattern-code = Atomy Code Pattern class:
|
106
|
+
def(initialize(@receiver, @message, @arguments)) {}
|
107
|
+
|
108
|
+
def(bytecode(gen, mod)):
|
109
|
+
mod compile(gen, `(//Atomy Pattern Particle new(
|
110
|
+
~@receiver
|
111
|
+
~@message
|
112
|
+
~@arguments
|
113
|
+
)))
|
114
|
+
|
115
|
+
def(assign(gen)):
|
116
|
+
assign-symbol = gen new-label
|
117
|
+
done = gen new-label
|
118
|
+
|
119
|
+
gen dup
|
120
|
+
gen push-cpath-top
|
121
|
+
gen find-const(.Symbol)
|
122
|
+
gen swap
|
123
|
+
gen kind-of
|
124
|
+
gen git(assign-symbol)
|
125
|
+
|
126
|
+
gen dup-many(2)
|
127
|
+
gen send(.receiver, 0)
|
128
|
+
gen swap
|
129
|
+
gen send(.receiver, 0)
|
130
|
+
gen swap
|
131
|
+
@receiver assign(gen)
|
132
|
+
gen pop-many(2)
|
133
|
+
|
134
|
+
gen dup-many(2)
|
135
|
+
gen send(.arguments, 0)
|
136
|
+
gen swap
|
137
|
+
gen send(.arguments, 0)
|
138
|
+
gen swap
|
139
|
+
@arguments assign(gen)
|
140
|
+
gen pop-many(2)
|
141
|
+
|
142
|
+
gen goto(done)
|
143
|
+
|
144
|
+
assign-symbol set!
|
145
|
+
|
146
|
+
gen dup-many(2)
|
147
|
+
gen pop
|
148
|
+
gen send(.receiver, 0)
|
149
|
+
gen push-undef
|
150
|
+
@receiver assign(gen)
|
151
|
+
gen pop-many(2)
|
152
|
+
|
153
|
+
gen dup-many(2)
|
154
|
+
gen pop
|
155
|
+
gen send(.arguments, 0)
|
156
|
+
gen make-array(0)
|
157
|
+
@arguments assign(gen)
|
158
|
+
gen pop-many(2)
|
159
|
+
|
160
|
+
done set!
|
161
|
+
|
162
|
+
pattern(.(~r [~*as])):
|
163
|
+
particle-pattern-code new(
|
164
|
+
pattern(r)
|
165
|
+
.[]
|
166
|
+
pattern(`[~*as]))
|
167
|
+
|
168
|
+
pattern(.[]):
|
169
|
+
Atomy Code Pattern new(`(Atomy Pattern Equality new(.[])))
|
170
|
+
|
171
|
+
pattern(.~(x & Word)):
|
172
|
+
Atomy Code Pattern new(`(Atomy Pattern Equality new(.~x)))
|
173
|
+
|
174
|
+
pattern(.(~(x & Word))!):
|
175
|
+
Atomy Code Pattern new(`(Atomy Pattern Equality new(.(~x)!)))
|
176
|
+
|
177
|
+
pattern(.(~(x & Word))?):
|
178
|
+
Atomy Code Pattern new(`(Atomy Pattern Equality new(.(~x)?)))
|
179
|
+
|
180
|
+
pattern(.[~a, ~*as]):
|
181
|
+
particle-pattern-code new(pattern('_), '.[], pattern(`[~a, ~*as]))
|
182
|
+
|
183
|
+
pattern(.~(x & Infix)):
|
184
|
+
particle-pattern-code new(pattern(x left || '_), `.~(StringLiteral new(x operator to-s)), pattern(`[~(x right)]))
|
185
|
+
|
186
|
+
pattern(.((~x)(~*as))):
|
187
|
+
particle-pattern-code new(pattern('_), `.~x, pattern(`[~*as]))
|
188
|
+
|
189
|
+
pattern(.(~r (~x)(~*as))):
|
190
|
+
particle-pattern-code new(pattern(r), `.~x, pattern(`[~*as]))
|
data/kernel/patterns.ay
CHANGED
@@ -1,256 +1,592 @@
|
|
1
|
-
|
1
|
+
use(require("core"))
|
2
|
+
use(require("define"))
|
3
|
+
use(require("control-flow"))
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
require("atomy/pattern/class_variable")
|
6
|
+
require("atomy/pattern/instance_variable")
|
7
|
+
require("atomy/pattern/attribute")
|
8
|
+
require("atomy/pattern/or")
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@body compile(g)
|
12
|
-
g send(#name, 0)
|
13
|
-
g send(#new, 2)
|
10
|
+
instance-variable-pattern-code = Atomy Code Pattern class:
|
11
|
+
def(initialize(name)):
|
12
|
+
instance-variable-set("@name", name)
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
@body == b body &&
|
18
|
-
@name == b name
|
14
|
+
def(bytecode(gen, mod)):
|
15
|
+
mod compile(gen, `(//Atomy Pattern Wildcard new))
|
19
16
|
|
20
|
-
|
21
|
-
|
17
|
+
def(assign(gen)):
|
18
|
+
gen set-ivar(("@" + @name to-s) to-sym)
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
g swap
|
26
|
-
g kind-of
|
20
|
+
pattern(@~(name & Word)):
|
21
|
+
instance-variable-pattern-code new(name text)
|
27
22
|
|
28
|
-
|
29
|
-
|
23
|
+
pattern(@(~(name & Word))?):
|
24
|
+
instance-variable-pattern-code new((name text to-s + "?") to-sym)
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
@pattern construct(g)
|
34
|
-
@test construct(g)
|
35
|
-
g send(#new, 2)
|
36
|
-
|
37
|
-
(== b) :=
|
38
|
-
b kind-of?(Predicate) &&
|
39
|
-
@pattern == b pattern &&
|
40
|
-
@test == b test
|
26
|
+
pattern(@(~(name & Word))!):
|
27
|
+
instance-variable-pattern-code new((name text to-s + "!") to-sym)
|
41
28
|
|
42
|
-
|
29
|
+
kind-of-pattern-code = Atomy Code Pattern class:
|
30
|
+
def(initialize(@parent, @constant)) {}
|
43
31
|
|
44
|
-
|
45
|
-
|
46
|
-
done = g new-label
|
32
|
+
def(bytecode(gen, mod)):
|
33
|
+
mod compile(gen, `(//Atomy Pattern KindOf new(~@parent ~@constant)))
|
47
34
|
|
48
|
-
|
49
|
-
|
50
|
-
g gif(mismatch)
|
35
|
+
pattern(~parent ~(constant & Constant)):
|
36
|
+
kind-of-pattern-code new(parent, constant)
|
51
37
|
|
52
|
-
|
53
|
-
|
54
|
-
g swap
|
55
|
-
g send(#call-on-instance, 1)
|
56
|
-
g goto(done)
|
38
|
+
attribute-pattern-code = Atomy Code Pattern class:
|
39
|
+
def(initialize(@attribute, @receiver, @arguments)) {}
|
57
40
|
|
58
|
-
|
59
|
-
|
60
|
-
g push-false
|
41
|
+
def(bytecode(gen, mod)):
|
42
|
+
mod compile(gen, `(//Atomy Pattern Attribute new(~@receiver, [~*@arguments])))
|
61
43
|
|
62
|
-
|
44
|
+
def(assign(gen)):
|
45
|
+
-- [value, pattern, value, pattern]
|
46
|
+
gen dup-many(2)
|
47
|
+
-- [pattern, value, value, pattern]
|
48
|
+
gen swap
|
49
|
+
-- [pattern, pattern, value, value, pattern]
|
50
|
+
gen dup
|
51
|
+
-- [receiver, pattern, value, value, pattern]
|
52
|
+
gen send(.receiver, 0)
|
53
|
+
-- [pattern, value, receiver, value, pattern]
|
54
|
+
gen move-down(2)
|
55
|
+
-- [[arguments], value, receiver, value, pattern]
|
56
|
+
gen send(.arguments, 0)
|
57
|
+
-- [<nil block>, [arguments], value, receiver, value, pattern]
|
58
|
+
gen push-nil
|
59
|
+
-- [assign result, value, pattern]
|
60
|
+
gen set-call-flags(2) -- CALL_FLAG_CONCAT
|
61
|
+
gen send-with-splat(((@attribute to-s) + "=") to-sym, 1)
|
62
|
+
-- [value, pattern]
|
63
|
+
gen pop
|
63
64
|
|
64
|
-
|
65
|
-
|
65
|
+
pattern(~receiver ~(attribute & Word)):
|
66
|
+
attribute-pattern-code new(attribute text, receiver, [])
|
66
67
|
|
67
|
-
|
68
|
+
pattern(~receiver (~(attribute & Word))?):
|
69
|
+
attribute-pattern-code new((attribute text to-s + "?") to-sym, receiver, [])
|
68
70
|
|
69
|
-
|
71
|
+
pattern(~receiver (~(attribute & Word))!):
|
72
|
+
attribute-pattern-code new((attribute text to-s + "!") to-sym, receiver, [])
|
70
73
|
|
71
|
-
|
72
|
-
|
74
|
+
pattern(~receiver [~*arguments]):
|
75
|
+
attribute-pattern-code new("[]" to-sym, receiver, arguments)
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
@expression construct(g)
|
77
|
-
@pattern construct(g)
|
78
|
-
g send(#new, 2)
|
77
|
+
class-variable-pattern-code = Atomy Code Pattern class:
|
78
|
+
def(initialize(@name)) {}
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
@expression == b expression &&
|
83
|
-
@pattern == b pattern
|
80
|
+
def(bytecode(gen, mod)):
|
81
|
+
mod compile(gen, `(//Atomy Pattern Wildcard new))
|
84
82
|
|
85
|
-
|
83
|
+
def(assign(gen)):
|
84
|
+
gen dup
|
85
|
+
gen push-scope
|
86
|
+
gen swap
|
87
|
+
gen push-literal(("@@" + @name to-s) to-sym)
|
88
|
+
gen swap
|
89
|
+
gen send(.class-variable-set, 2)
|
90
|
+
gen pop
|
86
91
|
|
87
|
-
matches?(g) := do:
|
88
|
-
`{ ~@expression } bytecode(g)
|
89
|
-
g send(#block, 0)
|
90
|
-
g swap
|
91
|
-
g send(#call-on-instance, 1)
|
92
|
-
@pattern matches?(g)
|
93
92
|
|
94
|
-
|
95
|
-
|
96
|
-
g send(#block, 0)
|
97
|
-
g swap
|
98
|
-
g send(#call-on-instance, 1)
|
99
|
-
@pattern deconstruct(g, locals)
|
93
|
+
pattern(@@~(name & Word)):
|
94
|
+
class-variable-pattern-code new(name text)
|
100
95
|
|
101
|
-
|
96
|
+
pattern(@@(~(name & Word))?):
|
97
|
+
class-variable-pattern-code new((name text to-s + "?") to-sym)
|
102
98
|
|
103
|
-
|
99
|
+
pattern(@@(~(name & Word))!):
|
100
|
+
class-variable-pattern-code new((name text to-s + "!") to-sym)
|
104
101
|
|
105
|
-
|
106
|
-
|
102
|
+
pattern($~(name & Word)):
|
103
|
+
pattern(`(//Rubinius Globals[~(Atomy Code Symbol new(("$" + name text to-s) to-sym))]))
|
107
104
|
|
108
|
-
|
109
|
-
|
110
|
-
@a construct(g)
|
111
|
-
@b construct(g)
|
112
|
-
g send(#new, 2)
|
105
|
+
pattern($(~(name & Word))?):
|
106
|
+
pattern(`(//Rubinius Globals[~(Atomy Code Symbol new(("$" + (name text to-s + "?")) to-sym))]))
|
113
107
|
|
114
|
-
|
115
|
-
|
116
|
-
@a == b a &&
|
117
|
-
@b == b b
|
108
|
+
pattern($(~(name & Word))!):
|
109
|
+
pattern(`(//Rubinius Globals[~(Atomy Code Symbol new(("$" + (name text to-s + "!")) to-sym))]))
|
118
110
|
|
119
|
-
|
120
|
-
|
111
|
+
pattern(nil):
|
112
|
+
Atomy Code Pattern new(`(//Atomy Pattern Equality new(nil)))
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
done = g new-label
|
114
|
+
pattern(true):
|
115
|
+
Atomy Code Pattern new(`(//Atomy Pattern Equality new(true)))
|
125
116
|
|
126
|
-
|
127
|
-
|
128
|
-
g gif(mismatch)
|
117
|
+
pattern(false):
|
118
|
+
Atomy Code Pattern new(`(//Atomy Pattern Equality new(false)))
|
129
119
|
|
130
|
-
|
131
|
-
|
132
|
-
g git(done)
|
120
|
+
pattern(~(x & StringLiteral)):
|
121
|
+
Atomy Code Pattern new(`(//Atomy Pattern Equality new(~x)))
|
133
122
|
|
134
|
-
|
135
|
-
|
136
|
-
g push-false
|
123
|
+
or-pattern-code = Atomy Code Pattern class:
|
124
|
+
def(initialize(@a, @b)) {}
|
137
125
|
|
138
|
-
|
126
|
+
def(bytecode(gen, mod)):
|
127
|
+
mod compile(gen, `(//Atomy Pattern Or new(~@a, ~@b)))
|
139
128
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
@b deconstruct(g, locals)
|
129
|
+
def(assign(gen)):
|
130
|
+
done = gen new-label
|
131
|
+
assign-b = gen new-label
|
144
132
|
|
145
|
-
|
133
|
+
gen dup-many(2)
|
134
|
+
gen swap
|
135
|
+
gen send(.a, 0)
|
136
|
+
gen swap
|
137
|
+
gen send(.matches?, 1)
|
138
|
+
gen gif(assign-b)
|
146
139
|
|
147
|
-
|
148
|
-
|
140
|
+
gen dup-many(2)
|
141
|
+
gen swap
|
142
|
+
gen send(.a, 0)
|
143
|
+
gen swap
|
144
|
+
@a assign(gen)
|
145
|
+
gen pop-many(2)
|
149
146
|
|
150
|
-
|
151
|
-
get(g)
|
152
|
-
@a construct(g)
|
153
|
-
@b construct(g)
|
154
|
-
g send(#new, 2)
|
147
|
+
gen goto(done)
|
155
148
|
|
156
|
-
|
157
|
-
b kind-of?(Or) &&
|
158
|
-
@a == b a &&
|
159
|
-
@b == b b
|
149
|
+
assign-b set!
|
160
150
|
|
161
|
-
|
162
|
-
|
151
|
+
gen dup-many(2)
|
152
|
+
gen swap
|
153
|
+
gen send(.b, 0)
|
154
|
+
gen swap
|
155
|
+
@b assign(gen)
|
156
|
+
gen pop-many(2)
|
163
157
|
|
164
|
-
|
165
|
-
matched = g new-label
|
166
|
-
done = g new-label
|
158
|
+
done set!
|
167
159
|
|
168
|
-
|
169
|
-
|
170
|
-
g git(matched)
|
160
|
+
pattern(~a | ~b):
|
161
|
+
or-pattern-code new(pattern(a), pattern(b))
|
171
162
|
|
172
|
-
|
173
|
-
|
174
|
-
|
163
|
+
Atomy Pattern open:
|
164
|
+
self class(With):
|
165
|
+
attr-reader(.block, .pattern)
|
175
166
|
|
176
|
-
|
177
|
-
g pop
|
178
|
-
g push-true
|
167
|
+
def(initialize(@block, @pattern)) {}
|
179
168
|
|
180
|
-
|
169
|
+
def(matches?(val)):
|
170
|
+
@pattern matches?(@block call-on-object(val))
|
181
171
|
|
182
|
-
|
183
|
-
|
184
|
-
done = g new-label
|
172
|
+
def(target):
|
173
|
+
Object
|
185
174
|
|
186
|
-
|
187
|
-
|
188
|
-
@a matches?(g)
|
189
|
-
g gif(b)
|
175
|
+
with-pattern-code = Atomy Code Pattern class:
|
176
|
+
def(initialize(@expr, @sub-pattern)) {}
|
190
177
|
|
191
|
-
|
192
|
-
|
193
|
-
g goto(done)
|
178
|
+
def(bytecode(gen, mod)):
|
179
|
+
mod compile(gen, `(//Atomy Pattern With new({ ~@expr }, ~@sub-pattern)))
|
194
180
|
|
195
|
-
|
196
|
-
|
197
|
-
|
181
|
+
def(assign(gen)):
|
182
|
+
-- [value, pattern, value, pattern]
|
183
|
+
gen dup-many(2)
|
198
184
|
|
199
|
-
|
185
|
+
-- [pattern, value, value, pattern]
|
186
|
+
gen swap
|
200
187
|
|
201
|
-
|
188
|
+
-- [pattern, pattern, value, value, pattern]
|
189
|
+
gen dup
|
202
190
|
|
191
|
+
-- [with-block, pattern, value, value, pattern]
|
192
|
+
gen send(.block, 0)
|
203
193
|
|
204
|
-
--
|
205
|
-
|
206
|
-
export:
|
207
|
-
Variable pattern :=
|
208
|
-
Atomy::Patterns::Named new $:
|
209
|
-
@name
|
210
|
-
Atomy::Patterns::Any new
|
194
|
+
-- [pattern, with-block, value, value, pattern]
|
195
|
+
gen swap
|
211
196
|
|
212
|
-
|
213
|
-
|
197
|
+
-- [with-pattern, with-block, value, value, pattern]
|
198
|
+
gen send(.pattern, 0)
|
214
199
|
|
215
|
-
|
216
|
-
|
217
|
-
@elements collect [e]: e to-pattern
|
200
|
+
-- [with-block, value, with-pattern, value, pattern]
|
201
|
+
gen move-down(2)
|
218
202
|
|
219
|
-
|
220
|
-
|
203
|
+
-- [value, with-block, with-pattern, value, pattern]
|
204
|
+
gen swap
|
221
205
|
|
222
|
-
|
223
|
-
|
206
|
+
-- [block-result, with-pattern, value, pattern]
|
207
|
+
gen send(.call-on-object, 1)
|
224
208
|
|
225
|
-
|
226
|
-
|
209
|
+
-- [block-result, with-pattern, value, pattern]
|
210
|
+
@sub-pattern assign(gen)
|
227
211
|
|
228
|
-
|
229
|
-
|
212
|
+
-- [value, pattern]
|
213
|
+
gen pop-many(2)
|
230
214
|
|
231
|
-
|
232
|
-
|
215
|
+
pattern(with(~expr, ~pat)):
|
216
|
+
with-pattern-code new(expr, pattern(pat))
|
233
217
|
|
234
|
-
|
235
|
-
|
218
|
+
Atomy Pattern open:
|
219
|
+
self class(Predicate):
|
220
|
+
def(initialize(@block)) {}
|
236
221
|
|
237
|
-
|
238
|
-
|
222
|
+
def(matches?(val)):
|
223
|
+
@block call-on-object(val)
|
239
224
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
225
|
+
def(target):
|
226
|
+
Object
|
227
|
+
|
228
|
+
pattern({ ~*pred-body }):
|
229
|
+
Atomy Code Pattern new(`(//Atomy Pattern Predicate new({ ~*pred-body })))
|
230
|
+
|
231
|
+
Atomy Pattern open:
|
232
|
+
self class(List):
|
233
|
+
attr-reader(.patterns, .splat)
|
234
|
+
|
235
|
+
def(initialize(@patterns, @splat)) {}
|
236
|
+
|
237
|
+
def(matches?(val)):
|
238
|
+
unless(val is-a?(Array)):
|
239
|
+
return(false)
|
240
|
+
|
241
|
+
when(@splat && (val size < @patterns size)):
|
242
|
+
return(false)
|
243
|
+
|
244
|
+
when(!@splat && (val size != @patterns size)):
|
245
|
+
return(false)
|
246
|
+
|
247
|
+
idx = 0
|
248
|
+
mismatch = false
|
249
|
+
@patterns each [p]:
|
250
|
+
unless(p matches?(val[idx])):
|
251
|
+
&mismatch = true
|
252
|
+
-- TODO: break, or return false
|
253
|
+
|
254
|
+
&idx = (idx + 1)
|
255
|
+
|
256
|
+
if(mismatch)
|
257
|
+
then: false
|
246
258
|
else:
|
247
|
-
Atomy::Patterns::Attribute new $:
|
248
|
-
@receiver
|
249
|
-
@method-name
|
250
|
-
@arguments
|
251
259
|
|
252
|
-
|
253
|
-
|
260
|
+
if(@splat)
|
261
|
+
then: @splat matches?(val drop(idx))
|
262
|
+
else: true
|
263
|
+
|
264
|
+
def(assign(scope, val)):
|
265
|
+
idx = 0
|
266
|
+
@patterns each [p]:
|
267
|
+
p assign(scope, val[idx])
|
268
|
+
&idx = (idx + 1)
|
269
|
+
|
270
|
+
when(@splat):
|
271
|
+
@splat assign(scope, val drop(idx))
|
272
|
+
|
273
|
+
list-pattern-code = Atomy Code Pattern class:
|
274
|
+
def(initialize(patterns)):
|
275
|
+
@patterns = []
|
276
|
+
@splat = nil
|
277
|
+
|
278
|
+
patterns each [p]:
|
279
|
+
if(p splat?)
|
280
|
+
then: @splat = p
|
281
|
+
else: @patterns << p
|
282
|
+
|
283
|
+
def(bytecode(gen, mod)):
|
284
|
+
splat-node = (@splat || 'nil)
|
285
|
+
mod compile(gen, `(//Atomy Pattern List new([~*@patterns], ~splat-node)))
|
286
|
+
|
287
|
+
def(assign(gen)):
|
288
|
+
-- [[value], pattern, [value], pattern]
|
289
|
+
gen dup-many(2)
|
290
|
+
|
291
|
+
-- [pattern, [value], [value], pattern]
|
292
|
+
gen swap
|
293
|
+
|
294
|
+
-- [[pattern], [value], [value], pattern]
|
295
|
+
gen send(.patterns, 0)
|
296
|
+
|
297
|
+
@patterns each with-index [p, i]:
|
298
|
+
-- [pattern, [pattern], [value], [value], pattern]
|
299
|
+
gen shift-array
|
300
|
+
|
301
|
+
-- [[pattern], pattern, [value], [value], pattern]
|
302
|
+
gen swap
|
303
|
+
|
304
|
+
-- [[value], pattern, [pattern], [value], pattern]
|
305
|
+
gen rotate(3)
|
306
|
+
|
307
|
+
-- [value, [value], pattern, [pattern], [value], pattern]
|
308
|
+
gen shift-array
|
309
|
+
|
310
|
+
-- [[value], value, pattern, [pattern], [value], pattern]
|
311
|
+
gen swap
|
312
|
+
|
313
|
+
-- [value, pattern, [value], [pattern], [value], pattern]
|
314
|
+
gen move-down(2)
|
315
|
+
|
316
|
+
-- [value, pattern, [value], [pattern], [value], pattern]
|
317
|
+
p assign(gen)
|
318
|
+
|
319
|
+
-- [[value], [pattern], [value], pattern]
|
320
|
+
gen pop-many(2)
|
321
|
+
|
322
|
+
-- [[pattern], [value], [value], pattern]
|
323
|
+
gen swap
|
324
|
+
|
325
|
+
when(@splat):
|
326
|
+
-- [[remaining values], [value], pattern]
|
327
|
+
gen pop
|
328
|
+
|
329
|
+
-- [[value], [remaining values], pattern]
|
330
|
+
gen swap
|
331
|
+
|
332
|
+
-- [pattern, [remaining values], [value]]
|
333
|
+
gen rotate(3)
|
334
|
+
|
335
|
+
-- [pattern, pattern, [remaining values], [value]]
|
336
|
+
gen dup
|
337
|
+
|
338
|
+
-- [splat pattern, pattern, [remaining values], [value]]
|
339
|
+
gen send(.splat, 0)
|
340
|
+
|
341
|
+
-- [splatted pattern, pattern, [remaining values], [value]]
|
342
|
+
gen send(.pattern, 0)
|
343
|
+
|
344
|
+
-- [pattern, [remaining values], splatted pattern, [value]]
|
345
|
+
gen move-down(2)
|
346
|
+
|
347
|
+
-- [[remaining values], splatted pattern, [value], pattern]
|
348
|
+
gen move-down(3)
|
349
|
+
|
350
|
+
-- [[remaining values], splatted pattern, [value], pattern]
|
351
|
+
@splat assign(gen)
|
352
|
+
|
353
|
+
-- either pop the splatted values/pattern, or the two empty arrays if no splat
|
354
|
+
-- [[value], pattern]
|
355
|
+
gen pop-many(2)
|
356
|
+
|
357
|
+
-- list-pattern
|
358
|
+
pattern([~*pats]):
|
359
|
+
list-pattern-code new(pats collect [p]: pattern(p))
|
360
|
+
|
361
|
+
match = class:
|
362
|
+
def(initialize(@node, @branches)) {}
|
363
|
+
|
364
|
+
def(bytecode(gen, mod)):
|
365
|
+
gen create-block(build-block(gen state scope, mod))
|
366
|
+
mod compile(gen, @node)
|
367
|
+
gen send(.call, 1)
|
368
|
+
|
369
|
+
|
370
|
+
def(build-block(scope, mod)):
|
371
|
+
Atomy Compiler generate(mod file) [blk]:
|
372
|
+
-- close over the outer scope
|
373
|
+
blk state scope parent = scope
|
374
|
+
|
375
|
+
blk total-args = 1
|
376
|
+
blk required-args = 1
|
377
|
+
blk arity = 1
|
378
|
+
|
379
|
+
pairs = @branches collect [`(~pat: ~*body)]:
|
380
|
+
[mod pattern(pat), `(do: ~*body)]
|
381
|
+
|
382
|
+
-- create a local for the value being matched against
|
383
|
+
blk state scope new-local(."arg:match-value")
|
384
|
+
|
385
|
+
-- [node]
|
386
|
+
blk push-local(0)
|
387
|
+
|
388
|
+
done = blk new-label
|
389
|
+
|
390
|
+
pairs each [pat, body]:
|
391
|
+
skip = blk new-label
|
392
|
+
|
393
|
+
-- [pattern, node]
|
394
|
+
mod compile(blk, pat)
|
395
|
+
|
396
|
+
-- [pattern, node, pattern, node]
|
397
|
+
blk dup-many(2)
|
398
|
+
|
399
|
+
-- [node, pattern, pattern, node]
|
400
|
+
blk swap
|
401
|
+
|
402
|
+
-- [bool, pattern, node]
|
403
|
+
blk send(.matches?, 1)
|
404
|
+
|
405
|
+
-- [pattern, node]
|
406
|
+
blk gif(skip)
|
407
|
+
|
408
|
+
-- [node, pattern]
|
409
|
+
blk swap
|
410
|
+
|
411
|
+
-- [node, pattern]
|
412
|
+
pat assign(blk)
|
413
|
+
|
414
|
+
-- []
|
415
|
+
blk pop-many(2)
|
416
|
+
|
417
|
+
-- [value]
|
418
|
+
mod compile(blk, body)
|
419
|
+
|
420
|
+
-- [value]
|
421
|
+
blk goto(done)
|
422
|
+
|
423
|
+
-- [pattern, node]
|
424
|
+
skip set!
|
425
|
+
|
426
|
+
-- [node]
|
427
|
+
blk pop
|
428
|
+
|
429
|
+
-- []
|
430
|
+
blk pop
|
431
|
+
|
432
|
+
-- [value]
|
433
|
+
blk push-nil
|
434
|
+
|
435
|
+
-- [value]
|
436
|
+
done set!
|
437
|
+
|
438
|
+
def(assignment-local(gen, name)):
|
439
|
+
var = gen state scope search-local(name)
|
440
|
+
|
441
|
+
if(var && (var depth == 0))
|
442
|
+
then: [var, false]
|
443
|
+
else: [gen state scope new-local(name) nested-reference, true]
|
444
|
+
|
445
|
+
|
446
|
+
macro(~x match: ~*branches):
|
447
|
+
match new(x, branches)
|
448
|
+
|
449
|
+
rescue = class:
|
450
|
+
def(initialize(@node, @branches)) {}
|
451
|
+
|
452
|
+
-- TODO: this is pretty barebones compared to:
|
453
|
+
-- https://github.com/rubinius/rubinius-ast/blob/aa5ff6260a7647a9ef1035feb66b6d4b632d4211/lib/rubinius/ast/exceptions.rb
|
454
|
+
-- i'd rather prove out the complexity than blindly mirror it
|
455
|
+
def(bytecode(gen, mod)):
|
456
|
+
ok = gen new-label
|
457
|
+
ex = gen new-label
|
458
|
+
rescued = gen new-label
|
459
|
+
|
460
|
+
-- []
|
461
|
+
gen setup-unwind(ex, 0) -- RescueType
|
462
|
+
|
463
|
+
-- [value]
|
464
|
+
mod compile(gen, @node)
|
465
|
+
|
466
|
+
-- [value]
|
467
|
+
gen pop-unwind
|
468
|
+
|
469
|
+
-- [value]
|
470
|
+
gen goto(ok)
|
471
|
+
|
472
|
+
ex set!
|
473
|
+
|
474
|
+
-- []
|
475
|
+
-- gen pop
|
476
|
+
|
477
|
+
-- [exc_state]
|
478
|
+
gen push-exception-state
|
479
|
+
|
480
|
+
-- [block, exc_state]
|
481
|
+
gen create-block(build-block(gen state scope, mod))
|
482
|
+
|
483
|
+
-- [exc, block, exc_state]
|
484
|
+
gen push-current-exception
|
485
|
+
|
486
|
+
-- [value, exc_state]
|
487
|
+
gen send(.call, 1)
|
488
|
+
|
489
|
+
-- [value, value, exc_state]
|
490
|
+
gen dup
|
491
|
+
|
492
|
+
-- [value, exc_state]
|
493
|
+
gen goto-if-not-undefined(rescued)
|
494
|
+
|
495
|
+
-- [exc_state]
|
496
|
+
gen pop
|
497
|
+
|
498
|
+
-- []
|
499
|
+
gen restore-exception-state
|
500
|
+
|
501
|
+
-- []
|
502
|
+
gen reraise
|
503
|
+
|
504
|
+
-- [value, exc_state]
|
505
|
+
rescued set!
|
506
|
+
|
507
|
+
-- [exc_state, value]
|
508
|
+
gen swap
|
509
|
+
|
510
|
+
-- [value]
|
511
|
+
gen pop
|
512
|
+
|
513
|
+
-- [value]
|
514
|
+
ok set!
|
515
|
+
|
516
|
+
def(build-block(scope, mod)):
|
517
|
+
Atomy Compiler generate(mod file) [blk]:
|
518
|
+
-- close over the outer scope
|
519
|
+
blk state scope parent = scope
|
520
|
+
|
521
|
+
blk total-args = 1
|
522
|
+
blk required-args = 1
|
523
|
+
blk arity = 1
|
524
|
+
|
525
|
+
pairs = @branches collect [`(~pat: ~*body)]:
|
526
|
+
[mod pattern(pat), `(do: ~*body)]
|
527
|
+
|
528
|
+
-- create a local for the value being matched against
|
529
|
+
blk state scope new-local(."arg:match-value")
|
530
|
+
|
531
|
+
-- [node]
|
532
|
+
blk push-local(0)
|
533
|
+
|
534
|
+
done = blk new-label
|
535
|
+
|
536
|
+
pairs each [pat, body]:
|
537
|
+
skip = blk new-label
|
538
|
+
|
539
|
+
-- [pattern, node]
|
540
|
+
mod compile(blk, pat)
|
541
|
+
|
542
|
+
-- [pattern, node, pattern, node]
|
543
|
+
blk dup-many(2)
|
544
|
+
|
545
|
+
-- [node, pattern, pattern, node]
|
546
|
+
blk swap
|
547
|
+
|
548
|
+
-- [bool, pattern, node]
|
549
|
+
blk send(.matches?, 1)
|
550
|
+
|
551
|
+
-- [pattern, node]
|
552
|
+
blk gif(skip)
|
553
|
+
|
554
|
+
-- [node, pattern]
|
555
|
+
blk swap
|
556
|
+
|
557
|
+
-- [node, pattern]
|
558
|
+
pat assign(blk)
|
559
|
+
|
560
|
+
-- []
|
561
|
+
blk pop-many(2)
|
562
|
+
|
563
|
+
-- [value]
|
564
|
+
mod compile(blk, body)
|
565
|
+
|
566
|
+
-- [value]
|
567
|
+
blk goto(done)
|
568
|
+
|
569
|
+
-- [pattern, node]
|
570
|
+
skip set!
|
571
|
+
|
572
|
+
-- [node]
|
573
|
+
blk pop
|
574
|
+
|
575
|
+
-- []
|
576
|
+
blk pop
|
577
|
+
|
578
|
+
-- [value]
|
579
|
+
blk push-undef
|
580
|
+
|
581
|
+
-- [value]
|
582
|
+
done set!
|
583
|
+
|
584
|
+
def(assignment-local(gen, name)):
|
585
|
+
var = gen state scope search-local(name)
|
586
|
+
|
587
|
+
if(var && (var depth == 0))
|
588
|
+
then: [var, false]
|
589
|
+
else: [gen state scope new-local(name) nested-reference, true]
|
254
590
|
|
255
|
-
|
256
|
-
|
591
|
+
macro(~x rescue: ~*branches):
|
592
|
+
rescue new(x, branches)
|