Skip to content

Commit 9ded835

Browse files
Merge pull request #1513 from andrew-johnson-4/start-porting-match-macro
Start porting match macro
2 parents 5c9e68c + bbc9e27 commit 9ded835

17 files changed

+30601
-30451
lines changed

BOOTSTRAP/cli.c

+30,524-30,427
Large diffs are not rendered by default.

PLATFORM/C/LIB/common-macros.lsts

+22-1
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,26 @@ typed macro macro::while(cond: lazy, body: lazy): lazy = (
6868
);
6969

7070
typed macro macro::assert(cond: lazy): lazy = (
71-
if not(cond) then fail("Assertion Failed", macro::location(cond))
71+
if not(cond) then fail("Assertion Failed", macro::location(here))
72+
);
73+
74+
typed macro macro::match(t: lazy, ps: lazy): lazy = (
75+
let uuid(term) = open(t);
76+
macro::match-pats( uuid(term), ps );
77+
);
78+
79+
typed macro macro::match-case(lhs: lazy, rhs: lazy, remainder: lazy): lazy = (
80+
lhs; rhs; remainder
81+
);
82+
83+
typed macro macro::match-pats(term: lazy, remainder: lazy): lazy = (
84+
remainder
85+
);
86+
87+
typed macro macro::match-pats(term: lazy, lhs rhs remainder: macro::match-case): lazy = (
88+
scope(if macro::match-arm(lhs,term) then rhs else macro::match-pats(term,remainder))
89+
);
90+
91+
typed macro macro::match-arm(v: macro::variable, term: lazy): lazy = (
92+
(let v = term; true)
7293
);

PLUGINS/BACKEND/C/cc-blob.lm

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cc-blob := λ(: caller-ctx FContext)(: function-name String)(: args AST)(: offse
44
# caller context is provided but not propagated
55
(let r (mk-fragment()))
66

7-
(let f (find-global-callable( function-name (typeof args) )))
7+
(let f (find-global-callable( function-name (typeof args) args )))
88
(match f (
99
()
1010
( (Glb( _ (Abs( lhs rhs tlt )) )) (
@@ -21,7 +21,7 @@ cc-blob := λ(: caller-ctx FContext)(: function-name String)(: args AST)(: offse
2121

2222
cc-blob := λ(: callee-ctx FContext)(: function-name String)(: args-tt Type)(: offset I64)(: blame AST). (: (
2323
(let r (mk-fragment()))
24-
(let f (find-global-callable( function-name args-tt )))
24+
(let f (find-global-callable( function-name args-tt blame )))
2525
(match f (
2626
()
2727
( (Glb( _ (Abs( lhs rhs tlt )) )) (

PLUGINS/BACKEND/C/compile-expr.lm

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ compile-expr := λ(: ctx FContext)(: term AST)(: stack-offset I64)(: used IsUsed
44
(match used (
55
()
66
( Return (
7-
(let fterm (find-global-callable( 'cdecl::return_s (typeof term) )))
7+
(let fterm (find-global-callable( 'cdecl::return_s (typeof term) term )))
88
(set e (std-c-compile-call( ctx 'cdecl::return_s fterm term )))
99
))
1010
( _ (

PLUGINS/BACKEND/C/std-c-compile-call.lsts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
let std-c-compile-call(ctx: FContext, fname: CString, fterm: AST, args: AST): Fragment = (
3-
fterm = find-global-callable(fname, typeof(args));
3+
fterm = find-global-callable(fname, typeof(args), args);
44
if not(non-zero(fterm)) then fail("std-c-compile-call Function was null: \{fterm}\nArguments: \{typeof(args)}\n");
55
if typeof(fterm).is-t(c"Blob") {
66
let r = mk-fragment();
@@ -21,7 +21,7 @@ let std-c-compile-call(ctx: FContext, fname: CString, fterm: AST, args: AST): Fr
2121
let inner-ctx = mk-fctx().bind(c"ictx", t1(c"ImplicitContext"), ictx)
2222
.bind(c"args", typeof(args), push-args);
2323
let r = mk-fragment();
24-
match find-global-callable(c"primitive::call", t3(c"Cons",t1(c"ImplicitContext"),typeof(args))) {
24+
match find-global-callable(c"primitive::call", t3(c"Cons",t1(c"ImplicitContext"),typeof(args)), args) {
2525
Glb{val:Abs{lhs=lhs, rhs=rhs}} => (
2626
r = blob-render(inner-ctx, rhs, r, 0);
2727
r.context = close(ctx);

PLUGINS/BACKEND/C/std-c-compile-expr.lsts

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ let std-c-compile-expr(ctx: FContext, t: AST, is-stmt: Bool): Fragment = (
6666
guid = uuid();
6767
compile-smart-string-index = compile-smart-string-index.bind(val,guid);
6868
let lit = mk-lit(val); ascript-normal(lit, t1(c"String"));
69-
let intern-ss = std-c-compile-call(ctx, c"intern", find-global-callable(c"intern", t1(c"String")), lit);
69+
let intern-ss = std-c-compile-call(ctx, c"intern", find-global-callable(c"intern", t1(c"String"), t), lit);
7070
assemble-header-section = assemble-header-section +
7171
mangle-c-type(typeof(t)) + SAtom{c" "} + SAtom{guid} + SAtom{c";\n"};
7272
assemble-string-initializer-section = assemble-string-initializer-section +

PLUGINS/FRONTEND/LSTS/lsts-parse.lsts

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ let lsts-parse-typed-macro(tokens: List<Token>): (AST, List<Token>) = (
296296
lsts-parse-expect(c";", tokens); tokens = tail(tokens);
297297
(mk-glb(
298298
mk-token(mname),
299-
mk-abs(margs, mk-app(mk-lit(c":"), mk-cons(mbody,mk-atype(mrett))), t1(c"TypedMacro"))
299+
mk-abs(margs, mk-app(mk-lit(c":"), mk-cons(without-location(mbody),mk-atype(mrett))), t1(c"TypedMacro"))
300300
), tokens)
301301
);
302302

SRC/find-global-callable.lsts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
let find-global-callable(fname: CString, arg-types: Type): AST = (
2+
let find-global-callable(fname: CString, arg-types: Type, blame: AST): AST = (
33
arg-types = denormalize-strong(arg-types);
44
fname = find-alias(fname, arg-types);
55
let match-set = mk-vector(type((Type,AST)), 16);
@@ -24,7 +24,7 @@ let find-global-callable(fname: CString, arg-types: Type): AST = (
2424
};
2525
exit(1);
2626
};
27-
if not(non-zero(result)) then fail("Unable to find appropriate global callable: \{fname} \{arg-types}\n");
27+
if not(non-zero(result)) then fail("Unable to find appropriate global callable: \{fname} \{arg-types}\nAt: \{blame.location}\n");
2828
result
2929
);
3030

SRC/macro-table.lsts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
let index-macro-table = {} :: HashtableEq<CString,List<(Type,Type,AST)>>;
33
index-macro-table = index-macro-table.bind(c"macro::concat", [] :: List<(Type,Type,AST)>);
44
index-macro-table = index-macro-table.bind(c"macro::location", [] :: List<(Type,Type,AST)>);
5+
index-macro-table = index-macro-table.bind(c"macro::variable", [] :: List<(Type,Type,AST)>);
56

67
let bind-new-macro(mname: CString, mterm: AST): Nil = (
78
let row = index-macro-table.lookup(mname, [] :: List<(Type,Type,AST)>);

SRC/std-apply-macro-candidates.lsts

+9-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,20 @@ let std-try-destructure-macro(tctx: TContext?, margs: AST, mtype: Type, mcandida
4646
match margs {
4747
App{left:Var{maybe-helper=key}, helper-args=right} => (
4848
if macro-helper==maybe-helper {
49-
(tctx, let helped) = std-apply-macro-weak(tctx, macro-helper, helper-args);
49+
(tctx, let helped) = std-apply-macro-weak(tctx, macro-helper, helper-args, Used);
50+
if non-zero(helped)
51+
then (tctx, std-direct-destructure-macro(helped, mstruct))
52+
else (tctx, no)
53+
} else (tctx, no)
54+
);
55+
_ => (
56+
if macro-helper==c"macro::variable" {
57+
(tctx, let helped) = std-apply-macro-weak(tctx, macro-helper, margs, Used);
5058
if non-zero(helped)
5159
then (tctx, std-direct-destructure-macro(helped, mstruct))
5260
else (tctx, no)
5361
} else (tctx, no)
5462
);
55-
_ => (tctx, no);
5663
}
5764
} else (tctx, std-direct-destructure-macro(margs, mstruct))
5865
);

SRC/std-apply-macro.lsts

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11

2-
let std-apply-macro(tctx: Maybe<TContext>, t: AST): (TContext?, AST) = (
2+
let std-apply-macro(tctx: Maybe<TContext>, t: AST, used: IsUsed): (TContext?, AST) = (
33
match t {
44
App{left:Var{mname=key}, margs=right} => (
5-
std-apply-macro(tctx, mname, margs);
5+
std-apply-macro(tctx, mname, margs, used);
66
);
77
}
88
);
99

10-
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = std-apply-macro(tctx, mname, margs, true);
11-
let std-apply-macro-weak(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = std-apply-macro(tctx, mname, margs, false);
10+
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST, used: IsUsed): (TContext?, AST) = std-apply-macro(tctx, mname, margs, used, true);
11+
let std-apply-macro-weak(tctx: Maybe<TContext>, mname: CString, margs: AST, used: IsUsed): (TContext?, AST) = std-apply-macro(tctx, mname, margs, used, false);
1212

1313
let std-apply-macro-concat(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = (
1414
match margs {
@@ -17,14 +17,22 @@ let std-apply-macro-concat(tctx: Maybe<TContext>, mname: CString, margs: AST): (
1717
}
1818
);
1919

20+
let std-apply-macro-variable(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = (
21+
match margs {
22+
Var{} => (tctx, margs);
23+
_ => (tctx, ASTEOF);
24+
}
25+
);
26+
2027
let std-apply-macro-location(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = (
2128
(tctx, mk-lit(to-smart-string(margs.location)).ascript(t1(c"SmartString")))
2229
);
2330

24-
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST, strong: Bool): (TContext?, AST) = (
31+
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST, used: IsUsed, strong: Bool): (TContext?, AST) = (
2532
let result = ASTEOF;
2633
if mname==c"macro::concat" then (tctx, result) = std-apply-macro-concat(tctx, mname, margs)
2734
else if mname==c"macro::location" then (tctx, result) = std-apply-macro-location(tctx, mname, margs)
35+
else if mname==c"macro::variable" then (tctx, result) = std-apply-macro-variable(tctx, mname, margs)
2836
else {
2937
let row = index-macro-table.lookup(mname, [] :: List<(Type,Type,AST)>);
3038
let peep-holes = TAny;
@@ -63,7 +71,7 @@ let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST, strong: B
6371
(tctx, result) = std-apply-macro-candidates(tctx, mname, margs, candidates);
6472
};
6573
if strong && not(non-zero(result)) then exit-error("Failed to Apply Macro: \{mname}\nArgs: \{margs}\n", margs);
66-
if strong then (tctx, result) = std-infer-expr(tctx, result, false, Used, TAny);
74+
if strong then (tctx, result) = std-infer-expr(tctx, result, false, used, TAny);
6775
(tctx, result)
6876
);
6977

SRC/std-infer-expr.lsts

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ let std-infer-expr(tctx: Maybe<TContext>, term: AST, is-scoped: Bool, used: IsUs
6666
);
6767
App{left:App{ left:App{ ifv=left:Var{key:c"if"}, cond=right }, t=right }, f=right} => (
6868
if is-scoped {
69-
(let tctx-inner, let new-cond) = std-infer-expr(tctx, cond, false, Used, TAny);
69+
(let tctx-inner, let new-cond) = std-infer-expr(tctx, cond, false, Tail, TAny);
7070
(_, let new-t) = std-infer-expr(tctx-inner, t, false, Tail, TAny);
7171
(_, let new-f) = std-infer-expr(tctx, f, false, Tail, TAny);
7272
if not(is(cond,new-cond)) || not(is(t,new-t)) || not(is(f,new-f))
7373
then { cond = new-cond; t = new-t; f = new-f; term = mk-app(mk-app(mk-app(ifv,new-cond),new-t),new-f) };
7474
} else {
75-
(tctx, let new-cond) = std-infer-expr(tctx, cond, false, Used, TAny);
75+
(tctx, let new-cond) = std-infer-expr(tctx, cond, false, Tail, TAny);
7676
(let tctx-t, let new-t) = std-infer-expr(tctx, t, false, Tail, TAny);
7777
(_, let new-f) = std-infer-expr(tctx, f, false, Tail, TAny);
7878
tctx = tctx-t;
@@ -160,7 +160,7 @@ let std-infer-expr(tctx: Maybe<TContext>, term: AST, is-scoped: Bool, used: IsUs
160160
}};
161161

162162
if index-macro-table.has(var-name-if-var(l)) {
163-
(tctx, term) = std-apply-macro(tctx, term);
163+
(tctx, term) = std-apply-macro(tctx, term, used);
164164
is-macro = true;
165165
} else {
166166
(tctx, let new-l) = std-infer-expr(tctx, l, false, used, TAny);

SRC/tctx-to-string.lsts

+10
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ let .into(tctx: Maybe<TContext>, tt: Type<String>): String = (
88
);
99

1010
let to-smart-string(tctx: Maybe<TContext>): String = tctx.into(type(String));
11+
12+
let .into(ctx: Maybe<AContext>, tt: Type<String>): String = (
13+
let result = "";
14+
for Tuple{first=first,second=second} in ctx.get-or([] :: AContext) {
15+
result = result + "\{first} : \{second}\n";
16+
};
17+
result
18+
);
19+
20+
let to-smart-string(ctx: Maybe<AContext>): String = ctx.into(type(String));

SRC/typeof-var-raw.lm

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ defof-var := λ(: sloc AST)(: tctx Maybe<TContext>)(: vname String)(: tt Type).
6969
(if (non-zero found) () (
7070
(if (.is-arrow kt) (
7171
(if (non-zero tt) (
72-
(set found (find-global-callable( vname tt )))
72+
(set found (find-global-callable( vname tt sloc )))
7373
) (set found t))
7474
) (
7575
(set found t)

SRC/without-location.lsts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ let without-location(term: AST): AST = (
55
match term {
66
Var{key=key,token=token} => Var{key,without-location(token)};
77
Lit{key=key,token=token} => Lit{key,without-location(token)};
8-
App{left=left,right=right} => App{close(without-location(left)),close(without-location(right))};
8+
App{is-cons=is-cons,left=left,right=right} => App{is-cons,close(without-location(left)),close(without-location(right))};
99
Seq{seq=seq} => (
1010
let ret = mk-vector(type(AST), seq.length);
1111
for vector s in seq { ret = ret.push(without-location(s)) };

tests/unit/ast-macros.lsts

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ type A = A{a:U64};
3232

3333
macro::assert(true);
3434

35+
(
36+
macro::match(123, macro::match-case(
37+
x, print(x), fail("Pattern Match Failure",macro::location(here))
38+
));
39+
);
40+
3541
# match
3642

3743
# for

tests/unit/ast-macros.lsts.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[3,4]20123
1+
[3,4]20123123

0 commit comments

Comments
 (0)