01: package gnu.jemacs.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 lambda builtin.
10: * @author Per Bothner
11: */
12:
13: public class lambda extends Lambda {
14: /** True if parameters should be bound fluidly. */
15: boolean fluidBindings = true;
16:
17: public void rewriteBody(LambdaExp lexp, Object body, Translator tr) {
18: tr.push(lexp);
19: if (lexp.defaultArgs != null)
20: for (int i = 0, n = lexp.defaultArgs.length; i < n; i++)
21: lexp.defaultArgs[i] = tr.rewrite(lexp.defaultArgs[i]);
22:
23: Pair pair;
24: int i = 0;
25: if (body instanceof Pair
26: && (pair = (Pair) body).car instanceof FString) {
27: // Process documentation string. FIXME.
28: body = pair.cdr;
29: }
30: Object interactive = null;
31: if (body instanceof Pair
32: && (pair = (Pair) body).car instanceof Pair) {
33: Pair first_application = (Pair) pair.car;
34: Object first_function = first_application.car;
35: if (first_function instanceof Symbol
36: && ((Symbol) first_function).getName() == "interactive") {
37: interactive = first_application.cdr;
38: if (interactive != LList.Empty
39: && !(interactive instanceof Pair && ((Pair) interactive).cdr == LList.Empty)) {
40: tr
41: .syntaxError("missing 'interactive' specification");
42: interactive = null;
43: }
44: body = pair.cdr;
45: }
46: }
47: if (body instanceof PairWithPosition)
48: lexp.setFile(((PairWithPosition) body).getFileName());
49: FluidLetExp let = null;
50:
51: int decl_count = lexp.min_args;
52: if (lexp.defaultArgs != null)
53: decl_count += lexp.defaultArgs.length;
54: if (lexp.max_args < 0)
55: decl_count++;
56:
57: if (fluidBindings && decl_count > 0) {
58: Expression[] inits = new Expression[decl_count];
59: let = new FluidLetExp(inits);
60: i = 0;
61: for (Declaration arg = lexp.firstDecl(); arg != null; arg = arg
62: .nextDecl(), i++) {
63: Declaration decl = let.addDeclaration(arg.getSymbol());
64: decl.setFluid(true);
65: decl.setIndirectBinding(true);
66: inits[i] = new ReferenceExp(arg);
67: decl.noteValue(inits[i]);
68: }
69: tr.push(let);
70: let.body = tr.rewrite_body(body);
71: tr.pop(let);
72: lexp.body = let;
73: } else
74: lexp.body = tr.rewrite_body(body);
75: tr.pop(lexp);
76:
77: if (interactive != null) {
78: if (interactive == LList.Empty)
79: interactive = QuoteExp.nullExp;
80: else {
81: Object arg = ((Pair) interactive).car;
82: if (arg instanceof FString)
83: interactive = new QuoteExp(arg.toString());
84: else {
85: LambdaExp ilexp = new LambdaExp();
86: rewrite(ilexp, LList.Empty, interactive, tr, null);
87: ilexp.setCanRead(true);
88: interactive = ilexp;
89: }
90: }
91: lexp.setProperty("emacs-interactive", interactive);
92: }
93: }
94: }
|