* 「10日くらいでできる!プログラミング言語自作入門」の続編#2-1b (HL-30b)
-(by [[K]], 2022.06.24)

** (1) 今回の改造テーマ
-[[a22_txt03_1a]]の続きで、今回はdouble型の変数を利用できるようにします。

** (2-1) dblToInt()関数の追加、ついでにOpCpyDblも追加
-intToDbl()関数の直後あたりに以下を追記。
 int dblToInt(int i)
 {
     if (isInt(i) || i < 0) return i; // 最初からintなら何もしない、エラーなら何もしない。
     int k = tmpAlloc();
     putIc(OpDblToInt, varP(k), varP(i), 0, 0);
     tmpFree(i);
     return k;
 }
-OpIntToDblの宣言の後にOpDblToIntとOpCpyDblを追加。
 enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpCgt, OpAdd, OpSub, OpMul, OpDiv, OpMod, OpAnd, OpShr, 
     OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, OpJle, OpJgt, OpLop, OpPrint, OpTime, OpEnd,
     OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet, OpOpnWin, OpSetPix0, OpM64s, OpRgb8, OpWait,
     OpXorShift, OpGetPix, OpFilRct0, OpPrm, OpF16Sin, OpF16Cos, OpInkey, OpDrwStr0, OpGprDec, OpBitBlt,
     OpPrintd, OpAddDbl, OpSubDbl, OpMulDbl, OpDivDbl, OpIntToDbl, OpDblToInt, OpCpyDbl };
-case OpIntToDbl:の後に以下を追加。
         case OpDblToInt: *icp[1]  = *icpd[2];            icp += 5; continue;
         case OpCpyDbl:   *icpd[1] = *icpd[2];            icp += 5; continue;
** (2-2) 代入処理を改造する
-before:
        } else if (tc[epc] == TcEqu && priority >= 15) {
            epc++;
            e0 = exprSub(15);	// 右結合なので15のまま.
            putIc(OpCpy, &var[i], &var[e0], 0, 0);
-after:
        } else if (tc[epc] == TcEqu && priority >= 15) {
            epc++;
            e0 = exprSub(15);	// 右結合なので15のまま.
            if (isInt(i)) {
                e0 = dblToInt(e0);
                putIc(OpCpy, varP(i), varP(e0), 0, 0);
            } else {
                e0 = intToDbl(e0);
                putIc(OpCpyDbl, varP(i), varP(e0), 0, 0);
            }

** (2-3) int用の構文にdoubleが適合しないようにする
-before:
         if (phrCmp( 1, "!!*0 = !!*1;", pc)) { // 単純代入.
             putIc(OpCpy,  &var[tc[wpc[0]]], &var[tc[wpc[1]]], 0, 0);
         } else if (phrCmp(10, "!!*0 = !!*1 + 1; if (!!*2 < !!*3) goto !!*4;", pc) && tc[wpc[0]] == tc[wpc[1]] && tc[wpc[0]] == tc[wpc[2]]) {
             putIc(OpLop, &var[tc[wpc[4]]], &var[tc[wpc[0]]], &var[tc[wpc[3]]], 0);
         } else if (phrCmp( 9, "!!*0 = !!*1 + 1;", pc) && tc[wpc[0]] == tc[wpc[1]] && isInt(tc[wpc[0]])) {  // 高速化のために+1専用の命令を用意(せこくてすみません).
             putIc(OpAdd1, &var[tc[wpc[0]]], 0, 0, 0);
         } else if (phrCmp( 2, "!!*0 = !!*1 !!*2 !!*3;", pc) && TcEEq <= tc[wpc[2]] && tc[wpc[2]] <= TcShr) {  // 加算, 減算など.
             putIc(tc[wpc[2]] - TcEEq + OpCeq,  &var[tc[wpc[0]]], &var[tc[wpc[1]]], &var[tc[wpc[3]]], 0);
-after:
         if (phrCmp( 1, "!!*0 = !!*1;", pc) && isInt(tc[wpc[0]]) && isInt(tc[wpc[1]])) { // 単純代入.
             putIc(OpCpy,  &var[tc[wpc[0]]], &var[tc[wpc[1]]], 0, 0);
         } else if (phrCmp(10, "!!*0 = !!*1 + 1; if (!!*2 < !!*3) goto !!*4;", pc) && tc[wpc[0]] == tc[wpc[1]] && tc[wpc[0]] == tc[wpc[2]] && isInt(tc[wpc[0]])) {
             putIc(OpLop, &var[tc[wpc[4]]], &var[tc[wpc[0]]], &var[tc[wpc[3]]], 0);
         } else if (phrCmp( 9, "!!*0 = !!*1 + 1;", pc) && tc[wpc[0]] == tc[wpc[1]] && isInt(tc[wpc[0]])) {  // 高速化のために+1専用の命令を用意(せこくてすみません).
             putIc(OpAdd1, &var[tc[wpc[0]]], 0, 0, 0);
         } else if (phrCmp( 2, "!!*0 = !!*1 !!*2 !!*3;", pc) && TcEEq <= tc[wpc[2]] && tc[wpc[2]] <= TcShr && isInt(tc[wpc[0]]) && isInt(tc[wpc[1]]) && isInt(tc[wpc[3]])) {  // 加算, 減算など.
             putIc(tc[wpc[2]] - TcEEq + OpCeq,  &var[tc[wpc[0]]], &var[tc[wpc[1]]], &var[tc[wpc[3]]], 0);

** (2-4) 変数の型宣言命令に対応
-before:
         } else if (phrCmp(33, "int", pc) || phrCmp(34, "AWindow", pc)) {
             while (tc[pc] != TcSemi)
                 pc++;
             ppc1 = pc;
-after:
         } else if (phrCmp(33, "int", pc) || phrCmp(34, "AWindow", pc)) {
             pc++;
             while (tc[pc] != TcSemi) {
                 if (tc[pc] != TcComma)
                     varTyp[tc[pc]] = TypInt;
                 pc++;
             }
             ppc1 = pc;
         } else if (phrCmp(36, "double", pc)) {
             pc++;
             while (tc[pc] != TcSemi) {
                 if (tc[pc] != TcComma)
                     varTyp[tc[pc]] = TypDbl;
                 pc++;
             }
             ppc1 = pc;

** (2-5) (おまけ)型変換(キャスト)に対応
-before:
     if (phrCmp(99, "( !!**0 )", epc)) {	// かっこ.
         i = expr(0);
     } else if (tc[epc] == TcPlPlus) {	// 前置インクリメント.
-after:
     if (phrCmp(80, "(int)", epc)) {
         epc = ppc1;
         ppc1 = 0;
         i = exprSub(3);
         i = dblToInt(i);
     } else if (phrCmp(81, "(double)", epc)) {
         epc = ppc1;
         ppc1 = 0;
         i = exprSub(3);
         i = intToDbl(i);
     } else if (phrCmp(99, "( !!**0 )", epc)) {	// かっこ.
         i = expr(0);
     } else if (tc[epc] == TcPlPlus) {	// 前置インクリメント.

** (3) テスト
 >double a = 1; printd a;
 >double a; a = 1; printd a;
 1.000000
 
 >printd 10 / (double) 3
 3.333333

** 次回に続く
次回: ''a22_txt03_2''

*こめんと欄
#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS