1010//
1111// ===----------------------------------------------------------------------===//
1212
13+ #include " TemplateGen.h"
1314#include " heavy/Builtins.h"
1415#include " heavy/Context.h"
1516#include " heavy/Dialect.h"
@@ -37,7 +38,7 @@ heavy::ExternBuiltinSyntax cond_expand;
3738heavy::ExternBuiltinSyntax define;
3839heavy::ExternBuiltinSyntax define_syntax;
3940heavy::ExternBuiltinSyntax syntax_rules;
40- heavy::ExternBuiltinSyntax ir_macro_transformer ;
41+ heavy::ExternBuiltinSyntax syntax_fn ;
4142heavy::ExternBuiltinSyntax if_;
4243heavy::ExternBuiltinSyntax lambda;
4344heavy::ExternBuiltinSyntax quasiquote;
@@ -141,19 +142,35 @@ mlir::Value define_syntax(OpGen& OG, Pair* P) {
141142 return OG.createSyntaxSpec (P2, P);
142143}
143144
145+ namespace {
146+ std::pair<heavy::Value, heavy::Pair*> DestructureSyntaxSpec (OpGen& OG, Pair* P) {
147+ heavy::Value Keyword = P->Car ;
148+ heavy::Pair* P2 = dyn_cast<Pair>(P->Cdr );
149+ if (P2) {
150+ heavy::Pair* Spec = dyn_cast<Pair>(P2->Car );
151+ if (Spec) {
152+ if (heavy::Pair* SpecInput = dyn_cast<Pair>(Spec->Cdr ))
153+ return {Keyword, SpecInput};
154+ }
155+ }
156+ return {};
157+ }
158+ } // end anon namespace
159+
144160mlir::Value syntax_rules (OpGen& OG, Pair* P) {
145- // TODO Support SyntaxClosures. (ie do not use Symbol directly)
161+ auto [Keyword, SpecInput] = DestructureSyntaxSpec (OG, P);
162+
163+ if (!Keyword || !SpecInput)
164+ return OG.SetError (" invalid syntax-rules syntax" , P);
146165
147- // The input is the <Syntax Spec> (Keyword (syntax-rules ...))
148- // <Syntax Spec> has its own checks in createSyntaxSpec
149- Symbol* Keyword = dyn_cast<Symbol>(P->Car );
150- Pair* SpecInput = dyn_cast_or_null<Pair>(P->Cdr .car ().cdr ());
151- if (!SpecInput) return OG.SetError (" invalid syntax-rules syntax" , P);
152166 // Check for optional ellipsis identifier.
153- Symbol* Ellipsis = dyn_cast<Symbol>(SpecInput->Car );
167+ Value Ellipsis;
168+ if (isIdentifier (SpecInput->Car ))
169+ Ellipsis = SpecInput->Car ;
154170 if (Ellipsis) {
155171 Pair* Temp = dyn_cast<Pair>(SpecInput->Cdr );
156- if (!Temp) return OG.SetError (" invalid syntax-rules syntax." , SpecInput);
172+ if (!Temp)
173+ return OG.SetError (" invalid syntax-rules syntax." , SpecInput);
157174 SpecInput = Temp;
158175 } else {
159176 Ellipsis = OG.getContext ().CreateSymbol (" ..." );
@@ -162,28 +179,16 @@ mlir::Value syntax_rules(OpGen& OG, Pair* P) {
162179 SpecInput->Car , SpecInput->Cdr );
163180}
164181
165- mlir::Value ir_macro_transformer (OpGen& OG, Pair* P) {
166- #if 0
167- heavy::FuncOp FuncOp = createSyntaxFunction(Loc);
168- mlir::Block& Body = *FuncOp.addEntryBlock();
169- mlir::BlockArgument ExprArg = Body.getArgument(1);
170- mlir::BlockArgument EnvArg = Body.getArgument(2);
171- mlir::OpBuilder::InsertionGuard IG(Builder);
172- Builder.setInsertionPointToStart(&Body);
173-
174- // Compile the input which should be a lambda with:
175- // expr, inject, compare
176- heavy::Value ProvidedLambdaExpr = P->Cdr.car();
177- if (!ProvidedLambdaExpr && isa<Empty>(P->Cdr.cdr()))
178- return OG.SetError("invalid syntax for ir-macro-transformer");
179- mlir::Value ProvidedLambda = OpGen.GetSingleResult(ProvidedLambdaExpr);
180- if (OpGen.CheckError())
181- return;
182- mlir::Value Compare = create<LoadGlobalOp>(Loc, HEAVY_BASE_VAR_STR(equal));
183-
184- //heavy::Transformer Transformer(OG, /*IsImplicitRename=*/true);
185- #endif
186- return mlir::Value ();
182+ // Convert lambda syntax into heavy::Syntax function
183+ // (for use with define-syntax.)
184+ mlir::Value syntax_fn (OpGen& OG, Pair* P) {
185+ auto [Keyword, SpecInput] = DestructureSyntaxSpec (OG, P);
186+ if (!Keyword || !SpecInput || !isa<Empty>(SpecInput->Cdr ))
187+ return OG.SetError (" invalid syntax for syntax-fn" , P);
188+ heavy::SourceLocation Loc = P->getSourceLocation ();
189+ heavy::Value ProcExpr = SpecInput->Car ;
190+ heavy::FuncOp FuncOp = OG.createSyntaxFunction (Loc, ProcExpr);
191+ return OG.create <heavy::SyntaxOp>(Loc, FuncOp.getSymName ());
187192}
188193
189194mlir::Value lambda (OpGen& OG, Pair* P) {
@@ -909,6 +914,7 @@ void apply(Context& C, ValueRefs Args) {
909914}
910915
911916void make_syntactic_closure (Context& C, ValueRefs Args) {
917+ llvm_unreachable (" make-syntactic-closure is not supported" );
912918 if (Args.size () != 2 )
913919 return C.RaiseError (" invalid arity" );
914920 Value Expr = Args[0 ];
@@ -926,8 +932,7 @@ void HEAVY_BASE_INIT(heavy::Context& Context) {
926932 HEAVY_BASE_VAR (define) = heavy::builtins::define;
927933 HEAVY_BASE_VAR (define_syntax) = heavy::builtins::define_syntax;
928934 HEAVY_BASE_VAR (syntax_rules) = heavy::builtins::syntax_rules;
929- HEAVY_BASE_VAR (ir_macro_transformer)
930- = heavy::builtins::ir_macro_transformer;
935+ HEAVY_BASE_VAR (syntax_fn) = heavy::builtins::syntax_fn;
931936 HEAVY_BASE_VAR (if_) = heavy::builtins::if_;
932937 HEAVY_BASE_VAR (lambda) = heavy::builtins::lambda;
933938 HEAVY_BASE_VAR (quasiquote) = heavy::builtins::quasiquote;
@@ -1014,8 +1019,7 @@ void HEAVY_BASE_LOAD_MODULE(heavy::Context& Context) {
10141019 {" quote" , HEAVY_BASE_VAR (quote)},
10151020 {" set!" , HEAVY_BASE_VAR (set)},
10161021 {" syntax-rules" , HEAVY_BASE_VAR (syntax_rules)},
1017- {" ir-macro-transformer" ,
1018- HEAVY_BASE_VAR (ir_macro_transformer)},
1022+ {" syntax-fn" , HEAVY_BASE_VAR (syntax_fn)},
10191023 {" begin" , HEAVY_BASE_VAR (begin)},
10201024 {" cond-expand" , HEAVY_BASE_VAR (cond_expand)},
10211025 {" define-library" ,HEAVY_BASE_VAR (define_library)},
0 commit comments