01: package gnu.commonlisp.lang;
02:
03: import gnu.mapping.*;
04: import gnu.expr.*;
05: import gnu.lists.*;
06: import kawa.lang.*;
07:
08: /**
09: * The Syntax transformer that re-writes the `defun' ELisp builtin.
10: * @author Per Bothner
11: */
12:
13: public class defun extends Syntax {
14: kawa.lang.Lambda lambdaSyntax;
15:
16: public defun(kawa.lang.Lambda lambdaSyntax) {
17: this .lambdaSyntax = lambdaSyntax;
18: }
19:
20: public boolean scanForDefinitions(Pair st, java.util.Vector forms,
21: ScopeExp defs, Translator tr) {
22: Pair p;
23: if (!(st.cdr instanceof Pair)
24: || !(((p = (Pair) st.cdr).car instanceof String) || p.car instanceof Symbol))
25: return super .scanForDefinitions(st, forms, defs, tr);
26: Object sym = p.car;
27: Declaration decl = defs.lookup(sym);
28: if (decl == null) {
29: decl = new Declaration(sym);
30: decl.setProcedureDecl(true);
31: defs.addDeclaration(decl);
32: } else
33: tr.error('w', "duplicate declaration for `" + sym + "'");
34:
35: if (defs instanceof ModuleExp)
36: decl.setCanRead(true);
37: st = Translator.makePair(st, this , Translator.makePair(p, decl,
38: p.cdr));
39: forms.addElement(st);
40: return true;
41: }
42:
43: public Expression rewriteForm(Pair form, Translator tr) {
44: Object obj = form.cdr;
45: Object name = null;
46: Expression value = null;
47: Declaration decl = null;
48:
49: if (obj instanceof Pair) {
50: Pair p1 = (Pair) obj;
51:
52: if (p1.car instanceof Symbol || p1.car instanceof String) {
53: name = p1.car.toString();
54: } else if (p1.car instanceof Declaration) {
55: decl = (Declaration) p1.car;
56: name = decl.getSymbol();
57: }
58: if (name != null && p1.cdr instanceof Pair) {
59: Pair p2 = (Pair) p1.cdr;
60: LambdaExp lexp = new LambdaExp();
61: lambdaSyntax.rewrite(lexp, p2.car, p2.cdr, tr, null);
62: lexp.setSymbol(name);
63: if (p2 instanceof PairWithPosition)
64: lexp.setLocation((PairWithPosition) p2);
65: value = lexp;
66: SetExp sexp = new SetExp(name, value);
67: sexp.setDefining(true);
68: sexp.setFuncDef(true);
69: if (decl != null) {
70: sexp.setBinding(decl);
71: if (decl.context instanceof ModuleExp
72: && decl.getCanWrite())
73: value = null;
74: decl.noteValue(value);
75: }
76: return sexp;
77: }
78: }
79: return tr.syntaxError("invalid syntax for " + getName());
80: }
81: }
|