001: package gnu.expr;
002:
003: import gnu.mapping.*;
004: import gnu.lists.*;
005:
006: /**
007: * Abstract class for the dummy top-level function of a module.
008: *
009: * This provides the functionality of gnu.mapping.ApplyMethodContainer,
010: * but it is class rather than an interface (thus ModuleMethod can use
011: * faster virtual method calls instead of slower interface calls).
012: */
013:
014: // NICE: Avoid being dependent of gnu.mapping.MethodProc.
015: // NICE: This is bad because this class is needed at runtime.
016: public class ModuleBody extends ProcedureN// implements Runnable
017: {
018: /*
019: public void apply (CallContext stack)
020: {
021: }
022:
023: /** For backwards compatibily.
024: * Earlier versions of Kawa used this to initialize a module.
025: * Allows run(Consumer) to call those methods. */
026: /*
027: public Object run (Environment env)
028: {
029: return Values.empty;
030: }
031:
032: public void run ()
033: {
034: run (new VoidConsumer());
035: }
036:
037: public void run(Consumer out)
038: {
039: CallContext ctx = CallContext.getInstance();
040: // For backwards compatibility - see run(Environment).
041: run(ctx.getEnvironment());
042: Consumer save = ctx.consumer;
043: try
044: {
045: ctx.consumer = out;
046: ctx.values = Values.noArgs;
047: ctx.proc = this;
048: ctx.run();
049: }
050: finally
051: {
052: ctx.consumer = save;
053: }
054: }
055:
056: public Object apply0 () throws Throwable
057: {
058: CallContext ctx = CallContext.getInstance();
059: ctx.values = Values.noArgs;
060: ctx.proc = this;
061: return applyV(ctx);
062: }
063: */
064:
065: private static boolean mainPrintValues;
066:
067: /** True if runAsMain should print values (in top-level expressions). */
068: public static boolean getMainPrintValues() {
069: return mainPrintValues;
070: }
071:
072: public static void setMainPrintValues(boolean value) {
073: mainPrintValues = value;
074: }
075:
076: /** This is invoked by main when ModuleBody is compiled with --main. */
077: /*
078: public final void runAsMain (String[] args)
079: {
080: kawa.repl.setArgs(args, 0);
081: gnu.text.WriterManager.instance.registerShutdownHook();
082: try
083: {
084: CallContext ctx = CallContext.getInstance();
085: ctx.values = Values.noArgs;
086: ctx.proc = this;
087: ClassMemberConstraint.defineAll(this, ctx.getEnvironment());
088: if (getMainPrintValues())
089: {
090: OutPort out = OutPort.outDefault();
091: ctx.consumer = kawa.Shell.getOutputConsumer(out);
092: ctx.runUntilDone();
093: out.freshLine();
094: }
095: else
096: {
097: ctx.consumer = new VoidConsumer();
098: ctx.runUntilDone();
099: }
100: // Redundant if registerShutdownHook succeeded (e.g on JDK 1.3).
101: gnu.mapping.OutPort.runCleanups();
102: kawa.repl.exitDecrement();
103: }
104: catch (Throwable ex)
105: {
106: ex.printStackTrace();
107: gnu.mapping.OutPort.runCleanups();
108: System.exit(-1);
109: }
110: }
111: */
112:
113: // just to implement this abstract method
114: public Object applyN(Object[] o) {
115: throw new Error("Not implemented");
116: }
117:
118: /**
119: * A subclass will typically override this like:
120: * switch (method.selector) {
121: * case 3: return function3();
122: * case 5: return function5();
123: * default: super.apply0(method);
124: * }
125: */
126:
127: public Object apply0(ModuleMethod method) {
128: return applyN(method, ProcedureN.noArgs);
129: }
130:
131: public Object apply1(ModuleMethod method, Object arg1) {
132: Object[] args = new Object[1];
133: args[0] = arg1;
134: return applyN(method, args);
135: }
136:
137: public Object apply2(ModuleMethod method, Object arg1, Object arg2) {
138: Object[] args = new Object[2];
139: args[0] = arg1;
140: args[1] = arg2;
141: return applyN(method, args);
142: }
143:
144: public Object apply3(ModuleMethod method, Object arg1, Object arg2,
145: Object arg3) {
146: Object[] args = new Object[3];
147: args[0] = arg1;
148: args[1] = arg2;
149: args[2] = arg3;
150: return applyN(method, args);
151: }
152:
153: public Object apply4(ModuleMethod method, Object arg1, Object arg2,
154: Object arg3, Object arg4) {
155: Object[] args = new Object[4];
156: args[0] = arg1;
157: args[1] = arg2;
158: args[2] = arg3;
159: args[3] = arg4;
160: return applyN(method, args);
161: }
162:
163: public Object applyN(ModuleMethod method, Object[] args) {
164: int count = args.length;
165: int num = method.numArgs();
166: if (count >= (num & 0xFFF) && (num < 0 || count <= (num >> 12))) {
167: switch (count) {
168: case 0:
169: return apply0(method);
170: case 1:
171: return apply1(method, args[0]);
172: case 2:
173: return apply2(method, args[0], args[1]);
174: case 3:
175: return apply3(method, args[0], args[1], args[2]);
176: case 4:
177: return apply4(method, args[0], args[1], args[2],
178: args[3]);
179: }
180: }
181: throw new WrongArguments(method, count);
182: }
183:
184: }
|