KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > standard > define_syntax


1 // Copyright (C) 2005 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ../../COPYING.
3

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 JavaDoc 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 JavaDoc st_cdr = st.cdr;
49     while (st_cdr instanceof SyntaxForm)
50       {
51     syntax = (SyntaxForm) st_cdr;
52     st_cdr = syntax.form;
53       }
54     Object JavaDoc p = st_cdr;
55     Object JavaDoc 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 JavaDoc || 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