@@ -10,43 +10,54 @@ let std-apply-macro(tctx: Maybe<TContext>, t: AST): (TContext?, AST) = (
1010let std-apply-macro(tctx: Maybe<TContext>, mname: CString, margs: AST): (TContext?, AST) = std-apply-macro(tctx, mname, margs, true);
1111let 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+
1320let 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);
0 commit comments