01: package kawa.standard;
02:
03: import kawa.lang.*;
04: import gnu.mapping.*;
05: import gnu.expr.*;
06: import gnu.lists.*;
07:
08: /** "define-variable" is like define, but ignored if variable already bound. */
09:
10: public class define_variable extends Syntax {
11: public static final define_variable define_variable = new define_variable();
12: static {
13: define_variable.setName("define-variable");
14: }
15:
16: public boolean scanForDefinitions(Pair st, java.util.Vector forms,
17: ScopeExp defs, Translator tr) {
18: if (!(st.cdr instanceof Pair))
19: return super .scanForDefinitions(st, forms, defs, tr);
20: Pair p = (Pair) st.cdr;
21: if (p.car instanceof String || p.car instanceof Symbol) {
22: Object sym = p.car;
23: if (!(defs instanceof ModuleExp))
24: tr.error('e', getName() + " must be at module level");
25: Declaration decl = defs.lookup(sym);
26: if (decl != null)
27: tr
28: .error('e', "duplicate declaration for '" + sym
29: + "'");
30: ModuleExp mod = defs.currentModule();
31: decl = mod.addDeclaration(sym);
32: tr.push(decl);
33: decl.setSimple(false);
34: decl.setPrivate(true);
35: decl.setFlag(Declaration.IS_DYNAMIC);
36: if (mod.isStatic())
37: decl.setFlag(Declaration.STATIC_SPECIFIED);
38: decl.setCanRead(true);
39: decl.setCanWrite(true);
40: decl.setIndirectBinding(true);
41: p = Translator.makePair(p, decl, p.cdr);
42: st = Translator.makePair(st, this , p);
43: }
44: forms.addElement(st);
45: return true;
46: }
47:
48: public Expression rewriteForm(Pair form, Translator tr) {
49: Object obj = form.cdr;
50: Expression value = null;
51: Declaration decl = null;
52:
53: if (obj instanceof Pair) {
54: Pair p1 = (Pair) obj;
55: obj = p1.car;
56: if (obj instanceof String || obj instanceof Symbol)
57: return tr.syntaxError(getName()
58: + " is only allowed in a <body>");
59: if (obj instanceof Declaration) {
60: decl = (Declaration) p1.car;
61: obj = p1.cdr;
62: if (obj instanceof Pair
63: && (p1 = (Pair) obj).cdr == LList.Empty)
64: value = tr.rewrite(p1.car);
65: else if (obj != LList.Empty)
66: decl = null;
67: }
68: }
69: if (decl == null)
70: return tr.syntaxError("invalid syntax for " + getName());
71: if (value == null)
72: return QuoteExp.voidExp;
73: SetExp sexp = new SetExp(decl, value);
74: sexp.setDefining(true);
75: sexp.setSetIfUnbound(true);
76:
77: if (decl != null) {
78: sexp.setBinding(decl);
79: if (decl.context instanceof ModuleExp && decl.getCanWrite())
80: value = null;
81: decl.noteValue(value);
82: }
83: return sexp;
84: }
85: }
|