00001
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016
00017 #include "NewtCore.h"
00018 #include "NewtBC.h"
00019 #include "NewtVM.h"
00020 #include "NewtIO.h"
00021 #include "NewtMem.h"
00022
00023
00024
00025
00027 typedef struct nbc_env_t nbc_env_t;
00028
00030 struct nbc_env_t {
00031 nbc_env_t * parent;
00032
00033 newtStack bytecode;
00034 newtStack breakstack;
00035 newtStack onexcpstack;
00036
00037 newtRefVar func;
00038 newtRefVar literals;
00039 newtRefVar argFrame;
00040 newtRefVar constant;
00041 };
00042
00043
00045 typedef struct {
00046 char * name;
00047 int32_t numArgs;
00048 int16_t b;
00049 newtRefVar sym;
00050 } freq_func_t;
00051
00052
00053
00054 #define ENV_BC(env) ((uint8_t*)env->bytecode.stackp)
00055 #define ENV_CX(env) (env->bytecode.sp)
00056 #define BC ENV_BC(newt_bc_env)
00057 #define CX ENV_CX(newt_bc_env)
00058 #define BREAKSTACK ((uint32_t*)newt_bc_env->breakstack.stackp)
00059 #define BREAKSP (newt_bc_env->breakstack.sp)
00060 #define ONEXCPSTACK ((uint32_t*)newt_bc_env->onexcpstack.stackp)
00061 #define ONEXCPSP (newt_bc_env->onexcpstack.sp)
00062 #define LITERALS (newt_bc_env->literals)
00063 #define ARGFRAME (newt_bc_env->argFrame)
00064 #define CONSTANT (newt_bc_env->constant)
00065
00066 #define NBCAddLiteral(r) NBCAddLiteralEnv(newt_bc_env, r)
00067 #define NBCGenCode(a, b) NBCGenCodeEnv(newt_bc_env, a, b)
00068 #define NBCGenCodeL(a, r) NBCGenCodeEnvL(newt_bc_env, a, r)
00069 #define NBCGenPushLiteral(r) NBCGenPushLiteralEnv(newt_bc_env, r)
00070
00071 #define NBCGenBC_op(stree, r) NBCGenBC_stmt(stree, r, true)
00072 #define NBCGenFreq(b) NBCGenCode(kNBCFreqFunc, b)
00073
00074
00075 #pragma mark -
00076 #pragma mark ローカル変数
00077
00078
00080 static nbc_env_t * newt_bc_env;
00081
00083 static freq_func_t freq_func_tb[] =
00084 {
00085
00086
00087 {"BAnd", 2, kNBCBitAnd, 0},
00088 {"BOr", 2, kNBCBitOr, 0},
00089 {"BNot", 1, kNBCBitNot, 0},
00090 {"Length", 1, kNBCLength, 0},
00091 {"Clone", 1, kNBCClone, 0},
00092 {"SetClass", 2, kNBCSetClass, 0},
00093 {"AddArraySlot", 2, kNBCAddArraySlot, 0},
00094 {"Stringer", 1, kNBCStringer, 0},
00095 {"ClassOf", 1, kNBCClassOf, 0},
00096
00097
00098 {NULL, 0, 0, 0}
00099 };
00100
00101
00102 #pragma mark -
00103
00104 static int16_t NBCAddLiteralEnv(nbc_env_t * env, newtRefArg r);
00105 static void NBCGenCodeEnv(nbc_env_t * env, uint8_t a, int16_t b);
00106 static void NBCGenCodeEnvL(nbc_env_t * env, uint8_t a, newtRefArg r);
00107 static int16_t NBCGenPushLiteralEnv(nbc_env_t * env, newtRefArg r);
00108
00109 static void NBCGenPUSH(newtRefArg r);
00110 static void NBCGenGetVar(nps_syntax_node_t * stree, newtRefArg r);
00111 static void NBCGenCallFn(newtRefArg fn, int16_t numArgs);
00112 static int16_t NBCMakeFnArgFrame(newtRefArg argFrame, nps_syntax_node_t * stree, nps_node_t r, bool * indefiniteP);
00113 static int16_t NBCMakeFnArgs(newtRefArg fn, nps_syntax_node_t * stree, nps_node_t r);
00114 static nbc_env_t * NBCMakeFnEnv(nps_syntax_node_t * stree, nps_node_t args);
00115 static uint32_t NBCGenBranch(uint8_t a);
00116 static void NBCDefLocal(newtRefArg type, newtRefArg r, bool init);
00117 static void NBCBackPatch(uint32_t cx, int16_t b);
00118 static void NBCPushBreakStack(uint32_t cx);
00119 static void NBCBreakBackPatchs(uint32_t loop_head, uint32_t cx);
00120 static void NBCPushOnexcpStack(uint32_t cx);
00121 static void NBCOnexcpBackPatchs(uint32_t try_head, uint32_t cx);
00122 static void NBCGenOnexcpPC(int32_t pc);
00123 static void NBCGenOnexcpBranch(void);
00124 static void NBCOnexcpBackPatchL(uint32_t sp, int32_t pc);
00125
00126 static newtRef NBCMakeFn(nbc_env_t * env);
00127 static void NBCInitFreqFuncTable(void);
00128 static nbc_env_t * NBCEnvNew(nbc_env_t * parent);
00129 static void NBCEnvFree(nbc_env_t * env);
00130 static newtRef NBCFnDone(nbc_env_t ** envP);
00131
00132 static void NBCInit(void);
00133 static void NBCCleanup(void);
00134
00135 static void NBCGenBC_stmt(nps_syntax_node_t * stree, nps_node_t r, bool ret);
00136 static void NBCGenConstant(nps_syntax_node_t * stree, nps_node_t r);
00137 static void NBCGenGlobalVar(nps_syntax_node_t * stree, nps_node_t r);
00138 static void NBCGenLocalVar(nps_syntax_node_t * stree, nps_node_t type, nps_node_t r);
00139 static bool NBCTypeValid(nps_node_t type);
00140 static int16_t NBCGenTryPre(nps_syntax_node_t * stree, nps_node_t r);
00141 static int16_t NBCGenTryPost(nps_syntax_node_t * stree, nps_node_t r, uint32_t * onexcpspP);
00142 static void NBCGenTry(nps_syntax_node_t * stree, nps_node_t expr, nps_node_t onexception_list);
00143 static void NBCGenIfThenElse(nps_syntax_node_t * stree, nps_node_t cond, nps_node_t thenelse, bool ret);
00144 static void NBCGenAnd(nps_syntax_node_t * stree, nps_node_t op1, nps_node_t op2);
00145 static void NBCGenOr(nps_syntax_node_t * stree, nps_node_t op1, nps_node_t op2);
00146 static void NBCGenLoop(nps_syntax_node_t * stree, nps_node_t expr);
00147 static newtRef NBCMakeTempSymbol(newtRefArg index, newtRefArg val, char * s);
00148 static void NBCGenFor(nps_syntax_node_t * stree, nps_node_t r, nps_node_t expr);
00149 static void NBCGenForeach(nps_syntax_node_t * stree, nps_node_t r, nps_node_t expr);
00150 static void NBCGenWhile(nps_syntax_node_t * stree, nps_node_t cond, nps_node_t expr);
00151 static void NBCGenRepeat(nps_syntax_node_t * stree, nps_node_t expr, nps_node_t cond);
00152 static void NBCGenBreak(nps_syntax_node_t * stree, nps_node_t expr);
00153 static void NBCGenStringer(nps_syntax_node_t * stree, nps_node_t op1, nps_node_t op2, char * dlmt);
00154 static void NBCGenAsign(nps_syntax_node_t * stree, nps_node_t lvalue, nps_node_t expr, bool ret);
00155 static void NBCGenExists(nps_syntax_node_t * stree, nps_node_t r);
00156 static void NBCGenReceiver(nps_syntax_node_t * stree, nps_node_t r);
00157 static void NBCGenMethodExists(nps_syntax_node_t * stree, nps_node_t receiver, nps_node_t name);
00158 static void NBCGenFn(nps_syntax_node_t * stree, nps_node_t args, nps_node_t expr);
00159 static void NBCGenGlobalFn(nps_syntax_node_t * stree, nps_node_t name, nps_node_t fn);
00160 static void NBCGenCall(nps_syntax_node_t * stree, nps_node_t name, nps_node_t args);
00161 static void NBCGenInvoke(nps_syntax_node_t * stree, nps_node_t fn, nps_node_t args);
00162 static void NBCGenFunc2(nps_syntax_node_t * stree, newtRefArg name, nps_node_t op1, nps_node_t op2);
00163 static void NBCGenSend(nps_syntax_node_t * stree, uint32_t code, nps_node_t receiver, nps_node_t r);
00164 static void NBCGenResend(nps_syntax_node_t * stree, uint32_t code, nps_node_t name, nps_node_t args);
00165 static void NBCGenMakeArray(nps_syntax_node_t * stree, nps_node_t klass, nps_node_t r);
00166 static void NBCGenMakeFrame(nps_syntax_node_t * stree, nps_node_t r);
00167 static void NVCGenNoResult(bool ret);
00168 static void NBCGenSyntaxCode(nps_syntax_node_t * stree, nps_syntax_node_t * node, bool ret);
00169 static int16_t NBCCountNumArgs(nps_syntax_node_t * stree, nps_node_t r);
00170 static newtRef NBCGenMakeFrameSlots_sub(nps_syntax_node_t * stree, nps_node_t r);
00171 static newtRef NBCGenMakeFrameSlots(nps_syntax_node_t * stree, nps_node_t r);
00172 static void NBCGenBC_sub(nps_syntax_node_t * stree, uint32_t n, bool ret);
00173
00174
00175 #pragma mark -
00176
00185 int16_t NBCAddLiteralEnv(nbc_env_t * env, newtRefArg r)
00186 {
00187 int16_t b;
00188
00189 b = NewtArrayLength(env->literals);
00190 NcAddArraySlot(env->literals, r);
00191
00192 return b;
00193 }
00194
00195
00196
00206 void NBCGenCodeEnv(nbc_env_t * env, uint8_t a, int16_t b)
00207 {
00208 uint8_t * bc;
00209 uint32_t cx;
00210
00211 cx = ENV_CX(env);
00212
00213 if (! NewtStackExpand(&env->bytecode, cx + 3))
00214 return;
00215
00216 bc = ENV_BC(env);
00217
00218 if (a == kNBCFieldMask)
00219 b = 1;
00220
00221 if (a != kNBCFieldMask &&
00222 ((a & kNBCFieldMask) == a ||
00223 (b != kNBCFieldMask && (b & kNBCFieldMask) == b)))
00224 {
00225 bc[cx++] = a | b;
00226 }
00227 else
00228 {
00229 bc[cx++] = a | kNBCFieldMask;
00230 bc[cx++] = b >> 8;
00231 bc[cx++] = b & 0xff;
00232 }
00233
00234 ENV_CX(env) = cx;
00235 }
00236
00237
00238
00248 void NBCGenCodeEnvL(nbc_env_t * env, uint8_t a, newtRefArg r)
00249 {
00250 newtRefVar obj;
00251 int16_t b = 0;
00252
00253 obj = NewtPackLiteral(r);
00254
00255
00256 b = NewtFindArrayIndex(env->literals, obj, 0);
00257
00258 if (b == -1)
00259 b = NBCAddLiteralEnv(env, obj);
00260
00261 NBCGenCodeEnv(env, a, b);
00262 }
00263
00264
00265
00274 int16_t NBCGenPushLiteralEnv(nbc_env_t * env, newtRefArg r)
00275 {
00276 newtRefVar obj;
00277 int16_t b;
00278
00279 obj = NewtPackLiteral(r);
00280 b = NBCAddLiteralEnv(env, obj);
00281
00282 NBCGenCodeEnv(env, kNBCPush, b);
00283
00284 return b;
00285 }
00286
00287
00288 #pragma mark -
00289
00297 void NBCGenPUSH(newtRefArg r)
00298 {
00299 switch (NewtGetRefType(r, false))
00300 {
00301 case kNewtInt30:
00302 {
00303 int32_t n;
00304
00305 n = NewtRefToInteger(r);
00306
00307 if (-8192 <= n && n <= 8191)
00308 NBCGenCode(kNBCPushConstant, r);
00309 else
00310 NBCGenCodeL(kNBCPush, r);
00311 }
00312 break;
00313
00314 case kNewtNil:
00315 case kNewtTrue:
00316 case kNewtUnbind:
00317 NBCGenCode(kNBCPushConstant, r);
00318 break;
00319
00320 case kNewtCharacter:
00321 case kNewtSpecial:
00322 case kNewtMagicPointer:
00323 if ((r & 0xffff0000) == 0)
00324 NBCGenCode(kNBCPushConstant, r);
00325 else
00326 NBCGenCodeL(kNBCPush, r);
00327 break;
00328
00329 case kNewtPointer:
00330 default:
00331 NBCGenCodeL(kNBCPush, r);
00332 break;
00333 }
00334 }
00335
00336
00337
00346 void NBCGenGetVar(nps_syntax_node_t * stree, newtRefArg r)
00347 {
00348 if (NewtHasSlot(CONSTANT, r))
00349 {
00350
00351 newtRefVar c;
00352
00353 c = NcGetSlot(CONSTANT, r);
00354
00355 if (! NPSRefIsSyntaxNode(c) && NewtRefIsLiteral(c))
00356 NBCGenPUSH(c);
00357 else
00358 NBCGenBC_op(stree, c);
00359 }
00360 else
00361 {
00362 int16_t b;
00363
00364
00365 b = NewtFindSlotIndex(ARGFRAME, r);
00366
00367 if (b != -1)
00368 NBCGenCode(kNBCGetVar, b);
00369 else
00370 NBCGenCodeL(kNBCFindVar, r);
00371 }
00372 }
00373
00374
00375
00384 void NBCGenCallFn(newtRefArg fn, int16_t numArgs)
00385 {
00386 int i;
00387
00388
00389 for (i = 0; freq_func_tb[i].name != NULL; i++)
00390 {
00391 if (NewtRefEqual(fn, freq_func_tb[i].sym))
00392 {
00393 if (numArgs != freq_func_tb[i].numArgs)
00394 {
00395 NBError(kNErrWrongNumberOfArgs);
00396 return;
00397 }
00398
00399 NBCGenFreq(freq_func_tb[i].b);
00400 return;
00401 }
00402 }
00403
00404
00405 NBCGenPUSH(fn);
00406 NBCGenCode(kNBCCall, numArgs);
00407 }
00408
00409
00410
00421 int16_t NBCMakeFnArgFrame(newtRefArg argFrame, nps_syntax_node_t * stree, nps_node_t r, bool * indefiniteP)
00422 {
00423 int16_t numArgs = 1;
00424
00425 if (r == kNewtRefUnbind)
00426 return 0;
00427
00428 if (*indefiniteP == true)
00429 {
00430 NBError(kNErrSyntaxError);
00431 return 0;
00432 }
00433
00434 if (NPSRefIsSyntaxNode(r))
00435 {
00436 nps_syntax_node_t * node;
00437
00438 node = &stree[NPSRefToSyntaxNode(r)];
00439
00440 switch (node->code)
00441 {
00442 case kNPSCommaList:
00443 numArgs = NBCMakeFnArgFrame(argFrame, stree, node->op1, indefiniteP)
00444 + NBCMakeFnArgFrame(argFrame, stree, node->op2, indefiniteP);
00445 break;
00446
00447 case kNPSArg:
00448
00449 NcSetSlot(argFrame, node->op2, kNewtRefUnbind);
00450 break;
00451
00452 case kNPSIndefinite:
00453
00454 NcSetSlot(argFrame, node->op1, kNewtRefUnbind);
00455 *indefiniteP = true;
00456 numArgs = 0;
00457 break;
00458
00459 default:
00460 NBError(kNErrSyntaxError);
00461 break;
00462 }
00463 }
00464 else
00465 {
00466 NcSetSlot(argFrame, r, kNewtRefUnbind);
00467 }
00468
00469 return numArgs;
00470 }
00471
00472
00473
00483 int16_t NBCMakeFnArgs(newtRefArg fn, nps_syntax_node_t * stree, nps_node_t r)
00484 {
00485 int16_t numArgs = 0;
00486
00487 if (r != kNewtRefUnbind)
00488 {
00489 newtRefVar argFrame;
00490 bool indefinite = false;
00491
00492 argFrame = NcGetSlot(fn, NSSYM0(argFrame));
00493 numArgs = NBCMakeFnArgFrame(argFrame, stree, r, &indefinite);
00494
00495 if (0 < numArgs)
00496 NcSetSlot(fn, NSSYM0(numArgs), NewtMakeInteger(numArgs));
00497
00498 if (indefinite)
00499 NcSetSlot(fn, NSSYM0(indefinite), kNewtRefTRUE);
00500 }
00501
00502 return numArgs;
00503 }
00504
00505
00506
00515 nbc_env_t * NBCMakeFnEnv(nps_syntax_node_t * stree, nps_node_t args)
00516 {
00517 newt_bc_env = NBCEnvNew(newt_bc_env);
00518
00519 if (newt_bc_env != NULL)
00520 NBCMakeFnArgs(newt_bc_env->func, stree, args);
00521
00522 return newt_bc_env;
00523 }
00524
00525
00526
00534 uint32_t NBCGenBranch(uint8_t a)
00535 {
00536 uint32_t cx;
00537
00538 cx = CX;
00539 NBCGenCode(a, 0xffff);
00540
00541 return cx;
00542 }
00543
00544
00545 #pragma mark -
00546
00559 void NBCDefLocal(newtRefArg type, newtRefArg r, bool init)
00560 {
00561 NcSetSlot(ARGFRAME, r, kNewtRefUnbind);
00562
00563 if (init)
00564 {
00565 int16_t b;
00566
00567
00568 b = NewtFindSlotIndex(ARGFRAME, r);
00569
00570 if (b != -1)
00571 NBCGenCode(kNBCSetVar, b);
00572 else
00573 NewtFprintf(stderr, "Not inpriment");
00574 }
00575 }
00576
00577
00578 #pragma mark -
00579
00590 void NBCBackPatch(uint32_t cx, int16_t b)
00591 {
00592 BC[cx + 1] = b >> 8;
00593 BC[cx + 2] = b & 0xff;
00594 }
00595
00596
00597
00607 void NBCPushBreakStack(uint32_t cx)
00608 {
00609 if (BREAKSTACK == NULL)
00610 NewtStackSetup(&newt_bc_env->breakstack, NEWT_POOL, sizeof(uint32_t), NEWT_NUM_BREAKSTACK);
00611
00612 if (! NewtStackExpand(&newt_bc_env->breakstack, BREAKSP + 1))
00613 return;
00614
00615 BREAKSTACK[BREAKSP] = cx;
00616 BREAKSP++;
00617 }
00618
00619
00620
00629 void NBCBreakBackPatchs(uint32_t loop_head, uint32_t cx)
00630 {
00631 uint32_t branch;
00632
00633 for (; 0 < BREAKSP; BREAKSP--)
00634 {
00635 branch = BREAKSTACK[BREAKSP - 1];
00636
00637 if (branch < loop_head)
00638 break;
00639
00640 NBCBackPatch(branch, cx);
00641 }
00642 }
00643
00644
00645 #pragma mark -
00646
00656 void NBCPushOnexcpStack(uint32_t cx)
00657 {
00658 if (ONEXCPSTACK == NULL)
00659 NewtStackSetup(&newt_bc_env->onexcpstack, NEWT_POOL, sizeof(uint32_t), NEWT_NUM_ONEXCPSTACK);
00660
00661 if (! NewtStackExpand(&newt_bc_env->onexcpstack, ONEXCPSP + 1))
00662 return;
00663
00664 ONEXCPSTACK[ONEXCPSP] = cx;
00665 ONEXCPSP++;
00666 }
00667
00668
00669
00678 void NBCOnexcpBackPatchs(uint32_t try_head, uint32_t cx)
00679 {
00680 uint32_t branch;
00681
00682 for (; 0 < ONEXCPSP; ONEXCPSP--)
00683 {
00684 branch = ONEXCPSTACK[ONEXCPSP - 1];
00685
00686 if (branch < try_head)
00687 break;
00688
00689 NBCBackPatch(branch, cx);
00690 }
00691 }
00692
00693
00694
00702 void NBCGenOnexcpPC(int32_t pc)
00703 {
00704 newtRefVar r;
00705 int16_t b;
00706
00707 r = NewtMakeInteger(pc);
00708 b = NBCGenPushLiteral(r);
00709
00710 NBCPushOnexcpStack(b);
00711 }
00712
00713
00714
00720 void NBCGenOnexcpBranch(void)
00721 {
00722 uint32_t cx;
00723
00724 cx = NBCGenBranch(kNBCBranch);
00725 NBCPushOnexcpStack(cx);
00726 }
00727
00728
00729
00738 void NBCOnexcpBackPatchL(uint32_t sp, int32_t pc)
00739 {
00740 newtRefVar r;
00741
00742 if (ONEXCPSTACK == NULL || ONEXCPSP <= sp)
00743 return;
00744
00745 r = NewtMakeInteger(pc);
00746 NewtSetArraySlot(LITERALS, ONEXCPSTACK[sp], r);
00747 }
00748
00749
00750 #pragma mark -
00751
00759 newtRef NBCMakeFn(nbc_env_t * env)
00760 {
00761 newtRefVar fnv[] = {
00762 NS_CLASS, NSSYM0(CodeBlock),
00763 NSSYM0(instructions), kNewtRefNIL,
00764 NSSYM0(literals), kNewtRefNIL,
00765 NSSYM0(argFrame), kNewtRefNIL,
00766 NSSYM0(numArgs), kNewtRefNIL
00767 };
00768
00769 newtRefVar afv[] = {
00770 NSSYM0(_nextArgFrame), kNewtRefNIL,
00771 NSSYM0(_parent), kNewtRefNIL,
00772 NSSYM0(_implementor), kNewtRefNIL
00773 };
00774
00775 newtRefVar fn;
00776 int32_t numArgs = 0;
00777
00778
00779 env->literals = NewtMakeArray(NSSYM0(literals), 0);
00780
00781
00782 env->argFrame = NewtMakeFrame2(sizeof(afv) / (sizeof(newtRefVar) * 2), afv);
00783
00784
00785 fn = NewtMakeFrame2(sizeof(fnv) / (sizeof(newtRefVar) * 2), fnv);
00786
00787
00788 NcSetSlot(fn, NSSYM0(instructions), kNewtRefNIL);
00789 NcSetSlot(fn, NSSYM0(literals), env->literals);
00790 NcSetSlot(fn, NSSYM0(argFrame), env->argFrame);
00791 NcSetSlot(fn, NSSYM0(numArgs), NewtMakeInteger(numArgs));
00792
00793 env->func = fn;
00794
00795
00796 if (env->parent)
00797 {
00798 env->constant = env->parent->constant;
00799 }
00800 else
00801 {
00802 env->constant = NcMakeFrame();
00803 }
00804
00805 return fn;
00806 }
00807
00808
00809
00815 void NBCInitFreqFuncTable(void)
00816 {
00817 int i;
00818
00819 for (i = 0; freq_func_tb[i].name != NULL; i++)
00820 {
00821 freq_func_tb[i].sym = NewtMakeSymbol(freq_func_tb[i].name);
00822 }
00823 }
00824
00825
00826
00834 nbc_env_t * NBCEnvNew(nbc_env_t * parent)
00835 {
00836 nbc_env_t * env;
00837
00838 env = (nbc_env_t *)NewtMemCalloc(NEWT_POOL, 1, sizeof(nbc_env_t));
00839
00840 if (env != NULL)
00841 {
00842 env->parent = parent;
00843 NewtStackSetup(&env->bytecode, NEWT_POOL, sizeof(uint8_t), NEWT_NUM_BYTECODE);
00844
00845 NBCMakeFn(env);
00846 }
00847
00848 return env;
00849 }
00850
00851
00852
00860 void NBCEnvFree(nbc_env_t * env)
00861 {
00862 if (env != NULL)
00863 {
00864 NewtStackFree(&env->bytecode);
00865 NewtStackFree(&env->breakstack);
00866 NewtStackFree(&env->onexcpstack);
00867
00868 NewtMemFree(env);
00869 }
00870 }
00871
00872
00873
00881 newtRef NBCFnDone(nbc_env_t ** envP)
00882 {
00883 nbc_env_t * env = *envP;
00884 newtRefVar fn = kNewtRefNIL;
00885
00886 if (env != NULL)
00887 {
00888 newtRefVar instr;
00889 newtRefVar literals;
00890
00891 NBCGenCodeEnv(env, kNBCReturn, 0);
00892
00893 fn = env->func;
00894 instr = NewtMakeBinary(kNewtRefNIL, ENV_BC(env), ENV_CX(env), true);
00895 NcSetSlot(fn, NSSYM0(instructions), instr);
00896
00897 literals = NcGetSlot(fn, NSSYM0(literals));
00898
00899 if (NewtRefIsNotNIL(literals) && NcLength(literals) == 0)
00900 NcSetSlot(fn, NSSYM0(literals), kNewtRefNIL);
00901
00902 *envP = env->parent;
00903 NBCEnvFree(env);
00904 }
00905
00906 return fn;
00907 }
00908
00909
00910
00916 void NBCInit(void)
00917 {
00918 NBCInitFreqFuncTable();
00919 }
00920
00921
00922
00928 void NBCCleanup(void)
00929 {
00930 nbc_env_t * env;
00931
00932 while (newt_bc_env != NULL)
00933 {
00934 env = newt_bc_env;
00935 newt_bc_env = env->parent;
00936 NBCEnvFree(env);
00937 }
00938 }
00939
00940
00941 #pragma mark -
00942
00952 void NBCGenBC_stmt(nps_syntax_node_t * stree, nps_node_t r, bool ret)
00953 {
00954 if (NPSRefIsSyntaxNode(r))
00955 {
00956 NBCGenBC_sub(stree, NPSRefToSyntaxNode(r), ret);
00957 return;
00958 }
00959
00960 if (r != kNewtRefUnbind)
00961 NBCGenPUSH(r);
00962 }
00963
00964
00965
00974 void NBCGenConstant(nps_syntax_node_t * stree, nps_node_t r)
00975 {
00976 if (NPSRefIsSyntaxNode(r))
00977 {
00978 nps_syntax_node_t * node;
00979
00980 node = &stree[NPSRefToSyntaxNode(r)];
00981
00982 switch (node->code)
00983 {
00984 case kNPSCommaList:
00985 NBCGenConstant(stree, node->op1);
00986 NBCGenConstant(stree, node->op2);
00987 break;
00988
00989 case kNPSAsign:
00990
00991 NcSetSlot(CONSTANT, node->op1, node->op2);
00992 break;
00993 }
00994 }
00995 else
00996 {
00997 NBError(kNErrSyntaxError);
00998 }
00999 }
01000
01001
01002
01011 void NBCGenGlobalVar(nps_syntax_node_t * stree, nps_node_t r)
01012 {
01013 if (NPSRefIsSyntaxNode(r))
01014 {
01015 nps_syntax_node_t * node;
01016
01017 node = &stree[NPSRefToSyntaxNode(r)];
01018
01019 switch (node->code)
01020 {
01021 case kNPSCommaList:
01022 NBCGenGlobalVar(stree, node->op1);
01023 NBCGenGlobalVar(stree, node->op2);
01024 break;
01025
01026 case kNPSAsign:
01027 NBCGenPUSH(node->op1);
01028 NBCGenBC_op(stree, node->op2);
01029
01030
01031 NBCGenCallFn(NSSYM0(defGlobalVar), 2);
01032 break;
01033 }
01034 }
01035 else if (NewtRefIsSymbol(r))
01036 {
01037 NBCGenPUSH(r);
01038 NBCGenPUSH(kNewtRefUnbind);
01039
01040
01041 NBCGenCallFn(NSSYM0(defGlobalVar), 2);
01042 }
01043 else
01044 {
01045 NBError(kNErrSyntaxError);
01046 }
01047 }
01048
01049
01050
01062 void NBCGenLocalVar(nps_syntax_node_t * stree, nps_node_t type, nps_node_t r)
01063 {
01064 if (NPSRefIsSyntaxNode(r))
01065 {
01066 nps_syntax_node_t * node;
01067
01068 node = &stree[NPSRefToSyntaxNode(r)];
01069
01070 switch (node->code)
01071 {
01072 case kNPSCommaList:
01073 NBCGenLocalVar(stree, type, node->op1);
01074 NBCGenLocalVar(stree, type, node->op2);
01075 break;
01076
01077 case kNPSAsign:
01078 NBCGenBC_op(stree, node->op2);
01079 NBCDefLocal(type, node->op1, true);
01080 break;
01081 }
01082 }
01083 else if (NewtRefIsSymbol(r))
01084 {
01085 NBCDefLocal(type, r, false);
01086 }
01087 else
01088 {
01089 NBError(kNErrSyntaxError);
01090 }
01091 }
01092
01093
01094
01103 bool NBCTypeValid(nps_node_t type)
01104 {
01105 if (type == kNewtRefUnbind)
01106 return true;
01107
01108 if (type == NS_INT)
01109 return true;
01110
01111 if (type == NSSYM0(array))
01112 return true;
01113
01114 NBError(kNErrSyntaxError);
01115
01116 return false;
01117 }
01118
01119
01120
01129 int16_t NBCGenTryPre(nps_syntax_node_t * stree, nps_node_t r)
01130 {
01131 int16_t numExcps = 0;
01132
01133 if (NPSRefIsSyntaxNode(r))
01134 {
01135 nps_syntax_node_t * node;
01136
01137 node = &stree[NPSRefToSyntaxNode(r)];
01138
01139 switch (node->code)
01140 {
01141 case kNPSOnexception:
01142 NBCGenPUSH(node->op1);
01143 NBCGenOnexcpPC(-1);
01144
01145 numExcps = 1;
01146 break;
01147
01148 case kNPSOnexceptionList:
01149 numExcps = NBCGenTryPre(stree, node->op1)
01150 + NBCGenTryPre(stree, node->op2);
01151 break;
01152 }
01153 }
01154
01155 return numExcps;
01156 }
01157
01158
01159
01169 int16_t NBCGenTryPost(nps_syntax_node_t * stree, nps_node_t r,
01170 uint32_t * onexcpspP)
01171 {
01172 int16_t numExcps = 0;
01173
01174 if (NPSRefIsSyntaxNode(r))
01175 {
01176 nps_syntax_node_t * node;
01177
01178 node = &stree[NPSRefToSyntaxNode(r)];
01179
01180 switch (node->code)
01181 {
01182 case kNPSOnexception:
01183
01184 NBCOnexcpBackPatchL(*onexcpspP, CX);
01185 (*onexcpspP)++;
01186
01187
01188 NBCGenBC_stmt(stree, node->op2, true);
01189 NBCGenOnexcpBranch();
01190
01191 numExcps = 1;
01192 break;
01193
01194 case kNPSOnexceptionList:
01195 numExcps = NBCGenTryPost(stree, node->op1, onexcpspP)
01196 + NBCGenTryPost(stree, node->op2, onexcpspP);
01197 break;
01198 }
01199 }
01200
01201 return numExcps;
01202 }
01203
01204
01205
01215 void NBCGenTry(nps_syntax_node_t * stree, nps_node_t expr,
01216 nps_node_t onexception_list)
01217 {
01218 uint32_t onexcp_cx;
01219 uint32_t branch_cx;
01220 uint32_t onexcpsp;
01221 int16_t numExcps = 0;
01222
01223 onexcpsp = ONEXCPSP;
01224 numExcps = NBCGenTryPre(stree, onexception_list);
01225 NBCGenCode(kNBCNewHandlers, numExcps);
01226
01227
01228 NBCGenBC_op(stree, expr);
01229 NBCGenCode(kNBCPopHandlers, 0);
01230
01231 branch_cx = CX;
01232 branch_cx = NBCGenBranch(kNBCBranch);
01233
01234
01235 onexcp_cx = CX;
01236 NBCGenTryPost(stree, onexception_list, &onexcpsp);
01237
01238
01239 NBCOnexcpBackPatchs(onexcp_cx, CX);
01240 NBCGenCode(kNBCPopHandlers, 0);
01241
01242
01243 ONEXCPSP = onexcpsp;
01244
01245
01246 NBCBackPatch(branch_cx, CX);
01247 }
01248
01249
01250
01261 void NBCGenIfThenElse(nps_syntax_node_t * stree, nps_node_t cond,
01262 nps_node_t thenelse, bool ret)
01263 {
01264 nps_node_t ifthen;
01265 nps_node_t ifelse = kNewtRefUnbind;
01266 uint32_t cond_cx;
01267
01268 NBCGenBC_op(stree, cond);
01269 cond_cx = NBCGenBranch(kNBCBranchIfFalse);
01270
01271 if (NewtRefIsArray(thenelse))
01272 {
01273 ifthen = NewtGetArraySlot(thenelse, 0);
01274 ifelse = NewtGetArraySlot(thenelse, 1);
01275 }
01276 else
01277 {
01278 ifthen = thenelse;
01279 }
01280
01281
01282 NBCGenBC_stmt(stree, ifthen, ret);
01283
01284 if (ifelse == kNewtRefUnbind)
01285 {
01286 NBCBackPatch(cond_cx, CX);
01287 }
01288 else
01289 {
01290 uint32_t then_done;
01291
01292 then_done = NBCGenBranch(kNBCBranch);
01293 NBCBackPatch(cond_cx, CX);
01294
01295
01296 NBCGenBC_stmt(stree, ifelse, ret);
01297
01298 NBCBackPatch(then_done, CX);
01299 }
01300 }
01301
01302
01303
01313 void NBCGenAnd(nps_syntax_node_t * stree, nps_node_t op1, nps_node_t op2)
01314 {
01315 uint32_t cx1;
01316 uint32_t cx2;
01317
01318
01319 NBCGenBC_op(stree, op1);
01320
01321
01322 cx1 = NBCGenBranch(kNBCBranchIfFalse);
01323
01324
01325 NBCGenBC_op(stree, op2);
01326
01327 cx2 = NBCGenBranch(kNBCBranch);
01328
01329
01330 NBCBackPatch(cx1, CX);
01331 NBCGenPUSH(kNewtRefNIL);
01332
01333
01334 NBCBackPatch(cx2, CX);
01335 }
01336
01337
01338