1 4 package kawa.standard; 5 import kawa.lang.*; 6 import gnu.expr.*; 7 import gnu.bytecode.ClassType; 8 import gnu.mapping.*; 9 import gnu.lists.*; 10 11 public class define_syntax extends Syntax 12 { 13 public static final define_syntax define_macro 14 = new define_syntax("%define-macro", false); 15 16 public static final define_syntax define_syntax 17 = new define_syntax("%define-syntax", true); 18 19 public define_syntax () 20 { 21 this.hygienic = true; 22 } 23 24 public define_syntax (Object name, boolean hygienic) 25 { 26 super(name); 27 this.hygienic = hygienic; 28 } 29 30 static ClassType typeMacro = ClassType.make("kawa.lang.Macro"); 31 static PrimProcedure makeHygienic 32 = new PrimProcedure(typeMacro.getDeclaredMethod("make", 3)); 33 static PrimProcedure makeNonHygienic 34 = new PrimProcedure(typeMacro.getDeclaredMethod("makeNonHygienic", 3)); 35 static PrimProcedure setCapturedScope 36 = new PrimProcedure(typeMacro.getDeclaredMethod("setCapturedScope", 1)); 37 38 boolean hygienic; 39 40 public Expression rewriteForm (Pair form, Translator tr) 41 { 42 return tr.syntaxError("define-syntax not in a body"); 43 } 44 45 public void scanForm (Pair st, ScopeExp defs, Translator tr) 46 { 47 SyntaxForm syntax = null; 48 Object st_cdr = st.cdr; 49 while (st_cdr instanceof SyntaxForm) 50 { 51 syntax = (SyntaxForm) st_cdr; 52 st_cdr = syntax.form; 53 } 54 Object p = st_cdr; 55 Object name; 56 if (p instanceof Pair) 57 { 58 Pair pp = (Pair) p; 59 name = pp.car; 60 p = pp.cdr; 61 } 62 else 63 name = null; 64 SyntaxForm nameSyntax = syntax; 65 while (name instanceof SyntaxForm) 66 { 67 nameSyntax = (SyntaxForm) name; 68 name = nameSyntax.form; 69 } 70 name = tr.namespaceResolve(name); 71 if (! (name instanceof String || name instanceof Symbol)) 72 { 73 tr.formStack.addElement(tr.syntaxError("missing macro name for "+Translator.safeCar(st))); 74 return; 75 } 76 if (p == null || Translator.safeCdr(p) != LList.Empty) 77 { 78 tr.formStack.addElement(tr.syntaxError("invalid syntax for "+getName())); 79 return; 80 } 81 82 Declaration decl = tr.define(name, nameSyntax, defs); 83 decl.setType(typeMacro); 84 tr.push(decl); 85 86 Macro savedMacro = tr.currentMacroDefinition; 87 Macro macro = Macro.make(decl); 88 macro.setHygienic(hygienic); 89 tr.currentMacroDefinition = macro; 90 Expression rule = tr.rewrite_car((Pair) p, syntax); 91 tr.currentMacroDefinition = savedMacro; 92 macro.expander = rule; 93 94 if (rule instanceof LambdaExp) 95 ((LambdaExp) rule).setFlag(LambdaExp.NO_FIELD); 96 Expression args[] = new Expression[3]; 97 args[0] = new QuoteExp(name); 98 args[1] = rule; 99 args[2] = ThisExp.makeGivingContext(defs); 100 rule = new ApplyExp(hygienic ? makeHygienic : makeNonHygienic, 101 args); 102 decl.noteValue(rule); 103 decl.setProcedureDecl(true); 104 105 if (decl.context instanceof ModuleExp) 106 { 107 SetExp result = new SetExp (decl, rule); 108 result.setDefining (true); 109 if (tr.getLanguage().hasSeparateFunctionNamespace()) 110 result.setFuncDef(true); 111 112 tr.formStack.addElement(result); 113 114 if (tr.immediate) 115 { 116 args = new Expression[2]; 117 args[0] = new ReferenceExp(decl); 118 args[1] = new QuoteExp(defs); 119 tr.formStack.addElement(new ApplyExp(setCapturedScope, args)); 120 } 121 } 122 } 123 } 124 | Popular Tags |