1 package gnu.expr; 2 import gnu.mapping.*; 3 import gnu.lists.*; 4 import gnu.kawa.reflect.ClassMemberLocation; 5 6 9 10 public abstract class ModuleBody extends Procedure0 11 { 12 public void apply (CallContext ctx) throws Throwable 13 { 14 if (ctx.pc == 0) 15 run(ctx); 16 } 17 18 protected boolean runDone; 19 20 public void run (CallContext ctx) throws Throwable 21 { 22 } 23 24 public void run () 25 { 26 synchronized (this) 27 { 28 if (runDone) 29 return; 30 runDone = true; 31 } 32 run (VoidConsumer.instance); 33 } 34 35 public void run (Consumer out) 36 { 37 CallContext ctx = CallContext.getInstance(); 39 Consumer save = ctx.consumer; 40 ctx.consumer = out; 41 Throwable th; 42 try 43 { 44 run(ctx); 45 th = null; 46 } 47 catch (Throwable ex) 48 { 49 th = ex; 50 } 51 runCleanup(ctx, th, save); 52 } 53 54 public static void runCleanup (CallContext ctx, Throwable th, Consumer save) 55 { 56 if (th == null) 57 { 58 try 59 { 60 ctx.runUntilDone(); 61 } 62 catch (Throwable ex) 63 { 64 th = ex; 65 } 66 } 67 ctx.consumer = save; 68 if (th != null) 69 { 70 if (th instanceof RuntimeException ) 71 throw (RuntimeException ) th; 72 if (th instanceof Error ) 73 throw (Error ) th; 74 throw new WrappedException(th); 75 } 76 } 77 78 public Object apply0 () throws Throwable 79 { 80 CallContext ctx = CallContext.getInstance(); 81 match0(ctx); 82 return ctx.runUntilValue(); 83 } 84 85 private static boolean mainPrintValues; 86 87 88 public static boolean getMainPrintValues() 89 { 90 return mainPrintValues; 91 } 92 93 public static void setMainPrintValues(boolean value) 94 { 95 mainPrintValues = value; 96 } 97 98 101 public final void runAsMain (String [] args) 102 { 103 processArgs(args); 104 runAsMain(); 105 } 106 107 108 public static void processArgs (String [] args) 109 { 110 int iArg = kawa.repl.processArgs(args, 0, args.length); 111 kawa.repl.setArgs(args, iArg); 112 } 113 114 115 public final void runAsMain () 116 { 117 gnu.text.WriterManager.instance.registerShutdownHook(); 118 try 119 { 120 CallContext ctx = CallContext.getInstance(); 121 ClassMemberLocation.defineAll(this, ctx.getEnvironment()); 122 if (getMainPrintValues()) 123 { 124 OutPort out = OutPort.outDefault(); 125 ctx.consumer = kawa.Shell.getOutputConsumer(out); 126 run(ctx); 127 ctx.runUntilDone(); 128 out.freshLine(); 129 } 130 else 131 { 132 run(); 133 ctx.runUntilDone(); 134 } 135 gnu.mapping.OutPort.runCleanups(); 137 kawa.repl.exitDecrement(); 138 } 139 catch (Throwable ex) 140 { 141 ex.printStackTrace(); 142 gnu.mapping.OutPort.runCleanups(); 143 System.exit(-1); 144 } 145 } 146 147 155 156 public Object apply0(ModuleMethod method) 157 throws Throwable 158 { 159 return applyN(method, Values.noArgs); 160 } 161 162 public Object apply1(ModuleMethod method, Object arg1) 163 throws Throwable 164 { 165 Object [] args = new Object [1]; 166 args[0] = arg1; 167 return applyN(method, args); 168 } 169 170 public Object apply2(ModuleMethod method, Object arg1, Object arg2) 171 throws Throwable 172 { 173 Object [] args = new Object [2]; 174 args[0] = arg1; 175 args[1] = arg2; 176 return applyN(method, args); 177 } 178 179 public Object apply3(ModuleMethod method, 180 Object arg1, Object arg2, Object arg3) 181 throws Throwable 182 { 183 Object [] args = new Object [3]; 184 args[0] = arg1; 185 args[1] = arg2; 186 args[2] = arg3; 187 return applyN(method, args); 188 } 189 190 public Object apply4(ModuleMethod method, 191 Object arg1, Object arg2, Object arg3, Object arg4) 192 throws Throwable 193 { 194 Object [] args = new Object [4]; 195 args[0] = arg1; 196 args[1] = arg2; 197 args[2] = arg3; 198 args[3] = arg4; 199 return applyN(method, args); 200 } 201 202 public Object applyN(ModuleMethod method, Object [] args) 203 throws Throwable 204 { 205 int count = args.length; 206 int num = method.numArgs(); 207 if (count >= (num & 0xFFF) 208 && (num < 0 || count <= (num >> 12))) 209 { 210 switch (count) 211 { 212 case 0: 213 return apply0(method); 214 case 1: 215 return apply1(method, args[0]); 216 case 2: 217 return apply2(method, args[0], args[1]); 218 case 3: 219 return apply3(method, args[0], args[1], args[2]); 220 case 4: 221 return apply4(method, args[0], args[1], args[2], args[3]); 222 } 223 } 224 throw new WrongArguments(method, count); 225 } 226 227 public int match0 (ModuleMethod proc, CallContext ctx) 228 { 229 int num = proc.numArgs(); 230 int min = num & 0xFFF; 231 if (min > 0) 232 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 233 if (num < 0) 234 return matchN(proc, ProcedureN.noArgs, ctx); 235 ctx.count = 0; 236 ctx.where = 0; 237 ctx.next = 0; 238 ctx.proc = proc; 239 return 0; 240 } 241 242 public int match1 (ModuleMethod proc, Object arg1, CallContext ctx) 243 { 244 int num = proc.numArgs(); 245 int min = num & 0xFFF; 246 if (min > 1) 247 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 248 if (num >= 0) 249 { 250 int max = num >> 12; 251 if (max < 1) 252 return MethodProc.NO_MATCH_TOO_MANY_ARGS|max; 253 ctx.value1 = arg1; 254 ctx.count = 1; 255 ctx.where = CallContext.ARG_IN_VALUE1; 256 ctx.next = 0; 257 ctx.proc = proc; 258 return 0; 260 } 261 Object [] args = { arg1 }; 262 return matchN(proc, args, ctx); 263 } 264 265 public int match2 (ModuleMethod proc, Object arg1, Object arg2, 266 CallContext ctx) 267 { 268 int num = proc.numArgs(); 269 int min = num & 0xFFF; 270 if (min > 2) 271 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 272 if (num >= 0) 273 { 274 int max = num >> 12; 275 if (max < 2) 276 return MethodProc.NO_MATCH_TOO_MANY_ARGS|max; 277 ctx.value1 = arg1; 278 ctx.value2 = arg2; 279 ctx.count = 2; 280 ctx.where = CallContext.ARG_IN_VALUE1 281 |(CallContext.ARG_IN_VALUE2<<4); 282 ctx.next = 0; 283 ctx.proc = proc; 284 return 0; 285 } 286 Object [] args = { arg1, arg2 }; 287 return matchN(proc, args, ctx); 288 } 289 290 public int match3 (ModuleMethod proc, Object arg1, Object arg2, Object arg3, 291 CallContext ctx) 292 { 293 int num = proc.numArgs(); 294 int min = num & 0xFFF; 295 if (min > 3) 296 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 297 if (num >= 0) 298 { 299 int max = num >> 12; 300 if (max < 3) 301 return MethodProc.NO_MATCH_TOO_MANY_ARGS|max; 302 ctx.value1 = arg1; 303 ctx.value2 = arg2; 304 ctx.value3 = arg3; 305 ctx.count = 3; 306 ctx.where = CallContext.ARG_IN_VALUE1 307 |(CallContext.ARG_IN_VALUE2<<4) 308 |(CallContext.ARG_IN_VALUE3<<8); 309 ctx.next = 0; 310 ctx.proc = proc; 311 return 0; 313 } 314 Object [] args = { arg1, arg2, arg3 }; 315 return matchN(proc, args, ctx); 316 } 317 318 public int match4 (ModuleMethod proc, Object arg1, Object arg2, 319 Object arg3, Object arg4, CallContext ctx) 320 { 321 int num = proc.numArgs(); 322 int min = num & 0xFFF; 323 if (min > 4) 324 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 325 if (num >= 0) 326 { 327 int max = num >> 12; 328 if (max < 4) 329 return MethodProc.NO_MATCH_TOO_MANY_ARGS|max; 330 ctx.value1 = arg1; 331 ctx.value2 = arg2; 332 ctx.value3 = arg3; 333 ctx.value4 = arg4; 334 ctx.count = 4; 335 ctx.where = (CallContext.ARG_IN_VALUE1 336 |(CallContext.ARG_IN_VALUE2<<4) 337 |(CallContext.ARG_IN_VALUE3<<8) 338 |(CallContext.ARG_IN_VALUE4<<12)); 339 ctx.next = 0; 340 ctx.proc = proc; 341 return 0; 343 } 344 Object [] args = { arg1, arg2, arg3, arg4 }; 345 return matchN(proc, args, ctx); 346 } 347 348 public int matchN (ModuleMethod proc, Object [] args, CallContext ctx) 349 { 350 int num = proc.numArgs(); 351 int min = num & 0xFFF; 352 if (args.length < min) 353 return MethodProc.NO_MATCH_TOO_FEW_ARGS|min; 354 if (num >= 0) 355 { 356 switch (args.length) 357 { 358 case 0: 359 return match0(proc, ctx); 360 case 1: 361 return match1(proc, args[0], ctx); 362 case 2: 363 return match2(proc, args[0], args[1], ctx); 364 case 3: 365 return match3(proc, args[0], args[1], args[2], ctx); 366 case 4: 367 return match4(proc, args[0], args[1], args[2], args[3], ctx); 368 default: 369 int max = num >> 12; 370 if (args.length > max) 371 return MethodProc.NO_MATCH_TOO_MANY_ARGS|max; 372 } 373 } 374 ctx.values = args; 375 ctx.count = args.length; 376 ctx.where = 0; 377 ctx.next = 0; 378 ctx.proc = proc; 379 return 0; 382 } 383 } 384 | Popular Tags |