001: package gnu.mapping;
002:
003: //import gnu.math.*;
004: import gnu.lists.*;
005:
006: /** A procedure activation stack (when compiled with explicit stacks). */
007:
008: public class CallContext implements Runnable
009: // extends ValueStack ??? FIXME
010: {
011: public Procedure proc;
012:
013: /* CPS: ??
014: CallFrame frame;
015: */
016:
017: /** The program location in the current procedure. */
018: public int pc;
019:
020: /** Default place for function results.
021: * In the future, function arguments will also use vstack. */
022: public ValueStack vstack = new ValueStack(); // ?? super
023: /** Function results are written to this Consumer.
024: * This may point to vstack - or some other Consumer. */
025: public Consumer consumer = vstack;
026:
027: /** Used for passing parameters. (Will be replaced by vstack.) */
028: public Object value1;
029: public Object value2;
030: public Object value3;
031: public Object value4;
032: public Object[] values;
033: public int ivalue1;
034: public int ivalue2;
035:
036: /** Number of actual arguments. */
037: public int count;
038:
039: /** Index of next argument.
040: * This is used by methods like getNextArg, used by callees. */
041: public int next;
042:
043: /** Encoding of where the arguments are.
044: * Each argument uses 4 bits.
045: * Arguments beyond 8 are implicitly ARG_IN_VALUES_ARRAY.
046: */
047: int where;
048: final static int ARG_IN_VALUES_ARRAY = 0;
049: final static int ARG_IN_VALUE1 = 1;
050: final static int ARG_IN_VALUE2 = 2;
051: final static int ARG_IN_VALUE3 = 3;
052: final static int ARG_IN_VALUE4 = 4;
053: final static int ARG_IN_IVALUE1 = 5;
054: final static int ARG_IN_IVALUE2 = 6;
055:
056: public Object getArgAsObject(int i) {
057: if (i < 8) {
058: switch ((this .where >> (4 * i)) & 15) {
059: case ARG_IN_VALUE1:
060: return value1;
061: case ARG_IN_VALUE2:
062: return value2;
063: case ARG_IN_VALUE3:
064: return value3;
065: case ARG_IN_VALUE4:
066: return value4;
067: //case ARG_IN_IVALUE1: return IntNum.make(ivalue1);
068: //case ARG_IN_IVALUE2: return IntNum.make(ivalue2);
069: }
070: }
071: return values[i];
072: }
073:
074: /** Get the next incoming argument.
075: * Throw WrongArguments if there are no more arguments.
076: */
077: public Object getNextArg() {
078: if (next >= count)
079: throw new WrongArguments(proc, count);
080: return getArgAsObject(next++);
081: }
082:
083: /** Get the next incoming argument.
084: * Return defaultValue if there are no more arguments.
085: */
086: public Object getNextArg(Object defaultValue) {
087: if (next >= count)
088: return defaultValue;
089: return getArgAsObject(next++);
090: }
091:
092: /** Note that we are done with the input arguments.
093: * Throw WrongArguments if there are unprocessed arguments.
094: */
095: public void lastArg() {
096: if (next < count)
097: throw new WrongArguments(proc, count);
098: values = null;
099: }
100:
101: public void setArgs() {
102: count = 0;
103: where = 0;
104: next = 0;
105: }
106:
107: public void setArgs(Object arg1) {
108: value1 = arg1;
109: count = 1;
110: where = ARG_IN_VALUE1;
111: next = 0;
112: }
113:
114: public void setArgs(Object arg1, Object arg2) {
115: value1 = arg1;
116: value2 = arg2;
117: count = 2;
118: where = ARG_IN_VALUE1 | (ARG_IN_VALUE2 << 4);
119: next = 0;
120: }
121:
122: public void setArgs(Object arg1, Object arg2, Object arg3) {
123: value1 = arg1;
124: value2 = arg2;
125: value3 = arg3;
126: count = 3;
127: where = ARG_IN_VALUE1 | (ARG_IN_VALUE2 << 4)
128: | (ARG_IN_VALUE3 << 8);
129: next = 0;
130: }
131:
132: public void setArgs(Object arg1, Object arg2, Object arg3,
133: Object arg4) {
134: value1 = arg1;
135: value2 = arg2;
136: value3 = arg3;
137: value4 = arg4;
138: count = 4;
139: where = (ARG_IN_VALUE1 | (ARG_IN_VALUE2 << 4) | (ARG_IN_VALUE3 << 8 | ARG_IN_VALUE4 << 12));
140: next = 0;
141: }
142:
143: public void setArgsN(Object[] args) {
144: values = args;
145: count = args.length;
146: where = 0;
147: next = 0;
148: }
149:
150: public Object[] getArgs() {
151: if (where == 0)
152: return values;
153: else {
154: int i = count;
155: Object[] args = new Object[i];
156: while (--i >= 0)
157: args[i] = getArgAsObject(i);
158: return args;
159: }
160: }
161:
162: public void runUntilDone() throws Throwable {
163: for (;;) {
164: /** Cps
165: CallFrame frame = this.frame;
166: if (frame == null)
167: break;
168: frame.step(this);
169: */
170: Procedure proc = this .proc;
171: if (proc == null)
172: break;
173: this .proc = null;
174: proc.apply(this );
175: }
176: }
177:
178: /** Run until no more continuations, returning final result. */
179: public final Object runUntilValue() throws Throwable {
180: Consumer consumerSave = consumer;
181: ValueStack vst = vstack;
182: consumer = vst;
183: int dindexSave = vst.gapStart;
184: int oindexSave = vst.oindex;
185: try {
186: runUntilDone();
187: return Values.make(vst, dindexSave, vst.gapStart);
188: } finally {
189: consumer = consumerSave;
190: vst.gapStart = dindexSave;
191: vst.oindex = oindexSave;
192: }
193: }
194:
195: /** Run until no more continuations, sending result to a COnsumer. */
196: public final void runUntilValue(Consumer out) throws Throwable {
197: Consumer consumerSave = consumer;
198: consumer = out;
199: try {
200: runUntilDone();
201: } finally {
202: consumer = consumerSave;
203: }
204: }
205:
206: public void run() {
207: try {
208: runUntilDone();
209: } catch (RuntimeException ex) {
210: throw ex;
211: } catch (Error ex) {
212: throw ex;
213: } catch (Throwable ex) {
214: throw new WrappedException(ex);
215: }
216: }
217:
218: /** Write values (of function result) to current consumer. */
219: public void writeValue(Object value) {
220: Values.writeValues(value, consumer);
221: }
222: }
|