NewtBC.c

説明を見る。
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 //      {"aref",            2,  kNBCAref,           0},
00086 //      {"setAref",         3,  kNBCSetAref,        0},
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         // end
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     // freq-func の場合
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     // call function
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                 // type (node->op1) はとりあえず無視
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);  // 0xffff is dummy
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     // literals
00779     env->literals = NewtMakeArray(NSSYM0(literals), 0);
00780 
00781     // argFrame
00782     env->argFrame = NewtMakeFrame2(sizeof(afv) / (sizeof(newtRefVar) * 2), afv);
00783 
00784     // function
00785     fn = NewtMakeFrame2(sizeof(fnv) / (sizeof(newtRefVar) * 2), fnv);
00786 
00787 //    NcSetClass(fn, NSSYM0(CodeBlock));
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     // constant
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                 // node->op2 がオブジェクトでない場合の処理を行うこと
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                 // defGlobalVar を呼出す
01031                 NBCGenCallFn(NSSYM0(defGlobalVar), 2);
01032                 break;
01033         }
01034     }
01035     else if (NewtRefIsSymbol(r))
01036     {
01037         NBCGenPUSH(r);
01038         NBCGenPUSH(kNewtRefUnbind);
01039 
01040         // defGlobalVar を呼出す
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); // PC(ダミー)
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                 // new-handler の引数をバックパッチ
01184                 NBCOnexcpBackPatchL(*onexcpspP, CX);
01185                 (*onexcpspP)++;
01186 
01187                 // onexception のコード生成
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     // onexception
01235     onexcp_cx = CX;
01236     NBCGenTryPost(stree, onexception_list, &onexcpsp);
01237 
01238     // onexception の終了
01239     NBCOnexcpBackPatchs(onexcp_cx, CX); // onexception の終了をバックパッチ
01240     NBCGenCode(kNBCPopHandlers, 0);
01241 
01242     // ONEXCPSP を戻す
01243     ONEXCPSP = onexcpsp;
01244 
01245     // バックパッチ
01246     NBCBackPatch(branch_cx, CX);    // branch をバックパッチ
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     // THEN 文
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);   // THEN 文の終了
01293         NBCBackPatch(cond_cx, CX);              // 条件文をバックパッチ
01294 
01295         // ELSE 文
01296         NBCGenBC_stmt(stree, ifelse, ret);
01297 
01298         NBCBackPatch(then_done, CX);            // THEN 文終了のブランチをバックパッチ
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     // オペランド1
01319     NBCGenBC_op(stree, op1);
01320 
01321     // NIL なら分岐
01322     cx1 = NBCGenBranch(kNBCBranchIfFalse);
01323 
01324     // オペランド2
01325     NBCGenBC_op(stree, op2);
01326     // 式の最後へ分岐
01327     cx2 = NBCGenBranch(kNBCBranch);
01328 
01329     // 戻り値をプッシュ
01330     NBCBackPatch(cx1, CX);      // 分岐をバックパッチ
01331     NBCGenPUSH(kNewtRefNIL);    // 戻り値は NIL
01332 
01333     // 式の最後
01334     NBCBackPatch(cx2, CX);      // 分岐をバックパッチ
01335 }
01336 
01337 
01338 /*------------------------------------------------------------------------*/