Skip to content

Commit d1c8f48

Browse files
Merge pull request #1510 from andrew-johnson-4/port-more-macros-to-lsts
Port more macros to lsts
2 parents 43c3c76 + 3a9038b commit d1c8f48

File tree

8 files changed

+30564
-30484
lines changed

8 files changed

+30564
-30484
lines changed

BOOTSTRAP/cli.c

Lines changed: 30481 additions & 30424 deletions
Large diffs are not rendered by default.

PLATFORM/C/LIB/common-macros.lsts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ typed macro macro::set(base index: macro::lhs-index, rhs: lazy): lazy = (
1111
$"set[]"( base, index, rhs )
1212
);
1313

14-
#typed macro macro::set(base field: macro::lhs-field, rhs: lazy): lazy = (
15-
# macro::concat(l"set.", field) (base, rhs)
16-
#);
14+
typed macro macro::set(base field: macro::lhs-field, rhs: lazy): lazy = (
15+
macro::concat($"set.", field) (base, rhs)
16+
);
1717

1818
typed macro macro::lhs-as-rhs(v: macro::variable): lazy = (
1919
v
@@ -27,12 +27,20 @@ typed macro macro::lhs-address-of(base: lazy): lazy = (
2727
base
2828
);
2929

30+
typed macro macro::lhs-field(base: lazy, field: lazy): lazy = (
31+
base; field
32+
);
33+
3034
typed macro macro::lhs-as-rhs(base field: macro::lhs-index): lazy = (
3135
macro::concat(l".", field)(base)
3236
);
3337

34-
typed macro macro::lhs-index(base: lazy, field: lazy): lazy = (
35-
base; field
38+
typed macro macro::lhs-index(base: lazy, index: lazy): lazy = (
39+
base; index
40+
);
41+
42+
typed macro macro::lhs-index(base field: macro::lhs-field, index: lazy): lazy = (
43+
macro::concat($".", field)(base); index
3644
);
3745

3846
typed macro macro::for(item: lazy, iter: List<?>, loop: lazy): lazy = (

PLUGINS/FRONTEND/LSTS/lsts-parse.lsts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ let lsts-parse-identifier(tokens: List<Token>): Tuple<CString, List<Token>> = (
3535
if lsts-parse-head(tokens)==c"." { name = c"."; tokens = tail(tokens); };
3636
lsts-parse-expect(c"Identifier", lsts-is-ident-head(lsts-parse-head(tokens)), tokens);
3737
name = name + lsts-unwrap-identifier(lsts-parse-head(tokens)); tokens = tail(tokens);
38-
while lsts-parse-head(tokens)==c":" && lsts-parse-head(tail(tokens))==c":" {
38+
while lsts-parse-head(tokens)==c":" && lsts-parse-head(tail(tokens))==c":" && lsts-is-ident-head(lsts-parse-head(tail(tail(tokens)))) {
3939
name = name + c"::"; tokens = tail(tokens); tokens = tail(tokens);
4040
lsts-parse-expect(c"Identifier", lsts-is-ident-head(lsts-parse-head(tokens)), tokens);
4141
name = name + lsts-unwrap-identifier(lsts-parse-head(tokens)); tokens = tail(tokens);
@@ -497,12 +497,10 @@ let lsts-parse-lhs(tokens: List<Token>): Tuple<AST,List<Token>> = (
497497
[Token{key:c"."}.. rest] => (
498498
let loc = head(tokens).location;
499499
lsts-parse-expect(c".", tokens); tokens = tail(tokens);
500-
let next-rest = lsts-parse-lhs-one(tokens);
501-
let next = next-rest.first;
502-
tokens = next-rest.second;
500+
(let field-name, tokens) = lsts-parse-identifier(tokens);
503501
base = mk-app(
504502
Var{ c"macro::lhs-field", with-location(mk-token("macro::lhs-field"),loc) },
505-
mk-cons(base, next)
503+
mk-cons(base, mk-var(field-name))
506504
);
507505
);
508506
[Token{key:c"["}.. rest] => (
@@ -527,10 +525,14 @@ let lsts-make-maybe-var(tokens: List<Token>): Tuple<AST,List<Token>> = (
527525
lsts-parse-lit(tokens)
528526
} else {
529527
if not(non-zero(tokens)) { lsts-parse-expect(c"Identifier", tokens); };
530-
let t = head(tokens);
531-
let base = Var { lsts-unwrap-identifier(t.key), lsts-unwrap-identifier(t) };
532-
if lsts-is-lit(t.key) { base = lsts-make-lit(t); };
533-
tokens = tail(tokens);
528+
let base = ASTEOF;
529+
if lsts-is-lit(head(tokens).key) {
530+
base = lsts-make-lit(head(tokens));
531+
tokens = tail(tokens);
532+
} else {
533+
(let var-name, tokens) = lsts-parse-identifier(tokens);
534+
base = mk-var(var-name);
535+
};
534536
Tuple { base, tokens }
535537
}
536538
);
@@ -1235,12 +1237,9 @@ let lsts-parse-assign(tokens: List<Token>): Tuple<AST,List<Token>> = (
12351237
ASTOrIdentIgnore {} => ();
12361238

12371239
ASTOrIdentAST { ast=ast } => (
1238-
let x = mk-cons(
1239-
mk-cons(
1240-
Var{ c"set", with-location(mk-token("set"),loc) },
1241-
ast
1242-
),
1243-
rexpr
1240+
let x = mk-app(
1241+
Var{ c"macro::set", with-location(mk-token("macro::set"),loc) },
1242+
mk-cons(ast, rexpr)
12441243
);
12451244
base = mk-cons(base, x);
12461245
);
@@ -1261,12 +1260,12 @@ let lsts-parse-assign(tokens: List<Token>): Tuple<AST,List<Token>> = (
12611260
lsts-parse-expect(c"=", tokens); tokens = tail(tokens);
12621261
let rhs-rest = lsts-parse-small-expression(tokens);
12631262
tokens = rhs-rest.second;
1264-
base = mk-cons(
1263+
base = mk-app(
1264+
Var{ c"macro::set", with-location(mk-token("macro::set"),loc) },
12651265
mk-cons(
1266-
Var{ c"set", with-location(mk-token("set"),loc) },
1267-
lhs-rest.first
1268-
),
1269-
rhs-rest.first
1266+
lhs-rest.first,
1267+
rhs-rest.first
1268+
)
12701269
);
12711270
};
12721271
} else {

SRC/macro-table.lsts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
let index-macro-table = {} :: HashtableEq<CString,List<(Type,Type,AST)>>;
3+
index-macro-table = index-macro-table.bind(c"macro::concat", [] :: List<(Type,Type,AST)>);
34

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

SRC/std-apply-macro.lsts

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,54 @@ let std-apply-macro(tctx: Maybe<TContext>, t: AST): (TContext?, AST) = (
1010
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = std-apply-macro(tctx, mname, margs, true);
1111
let std-apply-macro-weak(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = std-apply-macro(tctx, mname, margs, false);
1212

13+
let std-apply-macro-concat(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = (
14+
match margs {
15+
App{ left:Var{left-key=key}, right:Var{right-key=key} } => (tctx, mk-var(left-key + right-key));
16+
_ => (tctx, ASTEOF);
17+
}
18+
);
19+
1320
let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST, strong: Bool): (TContext?, AST) = (
14-
let row = index-macro-table.lookup(mname, [] :: List<(Type,Type,AST)>);
15-
let peep-holes = TAny;
16-
let peeped = TAny;
17-
for Tuple{mtype=first, peep=second, mterm=third} in row {
18-
if non-zero(peep-holes) {
19-
if peep-holes != peep then fail("Error: Macros must have the same pre-inference expectation.\n\{mname} : \{peeped}\n\{mname} : \{mtype}\n");
20-
} else {
21-
peep-holes = peep;
22-
peeped = mtype;
21+
let result = ASTEOF;
22+
if mname==c"macro::concat" then (tctx, result) = std-apply-macro-concat(tctx, mname, margs)
23+
else {
24+
let row = index-macro-table.lookup(mname, [] :: List<(Type,Type,AST)>);
25+
let peep-holes = TAny;
26+
let peeped = TAny;
27+
for Tuple{mtype=first, peep=second, mterm=third} in row {
28+
if non-zero(peep-holes) {
29+
if peep-holes != peep then fail("Error: Macros must have the same pre-inference expectation.\n\{mname} : \{peeped}\n\{mname} : \{mtype}\n");
30+
} else {
31+
peep-holes = peep;
32+
peeped = mtype;
33+
};
2334
};
24-
};
25-
(let peeped-type, margs) = std-infer-peeped-arguments(tctx, margs, peep-holes);
35+
(let peeped-type, margs) = std-infer-peeped-arguments(tctx, margs, peep-holes);
2636

27-
let matched = [] :: List<(Type,AST)>;
28-
for Tuple{mtype=first, mterm=third} in row {
29-
if can-unify(mtype, peeped-type) then matched = cons( (mtype,mterm), matched );
30-
};
37+
let matched = [] :: List<(Type,AST)>;
38+
for Tuple{mtype=first, mterm=third} in row {
39+
if can-unify(mtype, peeped-type) then matched = cons( (mtype,mterm), matched );
40+
};
3141

32-
let dominant-type = TAny;
33-
let candidates = [] :: List<(Type,AST)>;
34-
for Tuple{mtype=first, mterm=second} in matched {
35-
if non-zero(dominant-type) {
36-
if can-unify(mtype,dominant-type) && can-unify(dominant-type,mtype) {
37-
candidates = cons( (mtype,mterm), candidates );
38-
} else if can-unify(dominant-type,mtype) {
42+
let dominant-type = TAny;
43+
let candidates = [] :: List<(Type,AST)>;
44+
for Tuple{mtype=first, mterm=second} in matched {
45+
if non-zero(dominant-type) {
46+
if can-unify(mtype,dominant-type) && can-unify(dominant-type,mtype) {
47+
candidates = cons( (mtype,mterm), candidates );
48+
} else if can-unify(dominant-type,mtype) {
49+
dominant-type = mtype;
50+
candidates = [(mtype,mterm)];
51+
} else if can-unify(mtype,dominant-type) { # existing is dominant, keep existing and ignore new
52+
} else fail("Conflicting type candidates encountered during macro specialization:\n\{mname} : \{dominant-type}\n\{mname} : \{mtype}\n");
53+
} else {
3954
dominant-type = mtype;
4055
candidates = [(mtype,mterm)];
41-
} else if can-unify(mtype,dominant-type) { # existing is dominant, keep existing and ignore new
42-
} else fail("Conflicting type candidates encountered during macro specialization:\n\{mname} : \{dominant-type}\n\{mname} : \{mtype}\n");
43-
} else {
44-
dominant-type = mtype;
45-
candidates = [(mtype,mterm)];
46-
}
56+
}
57+
};
58+
(tctx, result) = std-apply-macro-candidates(tctx, mname, margs, candidates);
4759
};
48-
(tctx, let result) = std-apply-macro-candidates(tctx, mname, margs, candidates);
49-
if strong && not(non-zero(result)) then exit-error("Failed to Apply Macro: \{mname}", margs);
60+
if strong && not(non-zero(result)) then exit-error("Failed to Apply Macro: \{mname}\nArgs: \{margs}\n", margs);
5061
if strong then (tctx, result) = std-infer-expr(tctx, result, false, Used, TAny);
5162
(tctx, result)
5263
);

SRC/std-direct-destructure-macro.lsts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ let std-direct-destructure-macro(margs: AST, mstruct: AST): AContext? = (
33
let no = None :: AContext?;
44
match (margs, mstruct) {
55
Tuple{ val=first, second:Var{key=key} } => Some{[(key,val)]};
6-
Tuple{
7-
first:App{is-cons:1_u8, lrest=left, val=right },
8-
second:App{is-cons:1_u8, rrest=left, right:Var{key=key} }
9-
} => (
6+
Tuple{ first:App{lrest=left, val=right}, second:App{rrest=left, right:Var{key=key}} } => (
107
let ctx = std-direct-destructure-macro(lrest, rrest);
118
if ctx.is-some then Some{cons((key,val), ctx.get-or-panic)} else no;
129
);

tests/unit/ast-macros.lsts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,12 @@ assert( ast-macros-test-add(2_i64, 3_i64) == 5_i64 );
1818
print(x);
1919
);
2020

21+
type A = A{a:U64};
22+
(
23+
let a = A{1};
24+
$"macro::set"($"macro::lhs-field"(a,a), 2);
25+
print(a.a);
26+
);
27+
2128
#$"macro::for"(x, [1, 2], print(x));
2229
#$"macro::for"(x, mk-vector(type(U64)).push(3).push(4), print(x));

tests/unit/ast-macros.lsts.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[3,4]
1+
[3,4]2

0 commit comments

Comments
 (0)