a22_txt03_2
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2022.06.25)
** (1) 今回の改造テーマ
-今回は、関数を定義して呼び出せるようになりたいです。
-いきなりあれこれとやると大変なので、まずは引数なし、返値...
** (2-1) 関数型を追加
-before:
enum { TypInt, TypDbl };
-after:
enum { TypInt, TypDbl, TypFnc };
** (2-2) 内部命令を追加(1)
-before:
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet, O...
OpXorShift, OpGetPix, OpFilRct0, OpPrm, OpF16Sin, Op...
OpPrintd, OpAddDbl, OpSubDbl, OpMulDbl, OpDivDbl, Op...
-after:
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet, O...
OpXorShift, OpGetPix, OpFilRct0, OpPrm, OpF16Sin, Op...
OpPrintd, OpAddDbl, OpSubDbl, OpMulDbl, OpDivDbl, Op...
** (2-3) 内部命令を追加(2)
-関数exec()の直前あたりに以下を追加。
IntP *icpRet;
-case OpDblToInt: の下に以下を追加。
case OpCall: icpRet = icp + 5; icp = (IntP *)...
case OpRet: icp = icpRet; continue;
-とりあえず今は手抜き実装にしていて、リターンアドレスをス...
** (2-4) ブロック構文に関数定義を追加
-before:
enum { BlkIf = 1, BlkFor, BlkMain };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
-after:
enum { BlkIf = 1, BlkFor, BlkMain, BlkFunc };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
enum { FncSkp = 1 };
** (2-5) 構文を追加
-compile()関数に以下を追加。phrCmp(36, "double", pc) のあ...
} else if (phrCmp(37, "void !!*0() {", pc)) {
bd += BInfSiz;
binf[bd] = BlkFunc;
binf[bd + FncSkp] = tmpLabelAlloc();
putIc(OpGoto, &var[binf[bd + FncSkp]], &var[...
var[tc[wpc[0]]] = icq - ic; // ラベルに対応...
varTyp[tc[wpc[0]]] = TypFnc;
} else if (phrCmp(38, "}", pc) && binf[bd] == Bl...
var[binf[bd + FncSkp]] = icq - ic; // ラベル...
bd -= BInfSiz;
} else if (phrCmp(39, "return;", pc)) {
putIc(OpRet, 0, 0, 0, 0);
** (2-6) 関数呼び出し演算子の実装
-追加する場所は phrCmp(99, "( !!**0 )", epc) の前あたり
} else if (phrCmp(82, "!!*0()", epc) && varTyp[tc[wp...
putIc(OpCall, &var[tc[wpc[0]]], &var[tc[wpc[0]]]...
i = Tc0; // 本当はvoidだから0ではないのだけれど...
** (2-7) 分岐処理に対する前処理の改造
-before:
for (icq = ic; icq < icq1; icq += 5) { // goto先の...
i = (int) icq[0];
if ((OpGoto <= i && i <= OpLop) {
icp = *icq[1] + ic;
while ((int) icp[0] == OpGoto) { // 飛び先...
icp = *icp[2] + ic;
}
icq[1] = (IntP) icp;
}
}
-after:
for (icq = ic; icq < icq1; icq += 5) { // goto先の...
i = (int) icq[0];
if (OpGoto <= i && i <= OpLop) || i == OpCall) {
icp = *icq[1] + ic;
while ((int) icp[0] == OpGoto) { // 飛び先...
icp = *icp[2] + ic;
}
icq[1] = (IntP) icp;
}
}
** (3) テスト
-テストプログラム
print 123;
void fnc()
{
print 789;
}
print 456;
fnc();
fnc();
-実行結果
123
456
789
789
** 次回に続く
次回: ''a22_txt03_2a''
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2022.06.25)
** (1) 今回の改造テーマ
-今回は、関数を定義して呼び出せるようになりたいです。
-いきなりあれこれとやると大変なので、まずは引数なし、返値...
** (2-1) 関数型を追加
-before:
enum { TypInt, TypDbl };
-after:
enum { TypInt, TypDbl, TypFnc };
** (2-2) 内部命令を追加(1)
-before:
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet, O...
OpXorShift, OpGetPix, OpFilRct0, OpPrm, OpF16Sin, Op...
OpPrintd, OpAddDbl, OpSubDbl, OpMulDbl, OpDivDbl, Op...
-after:
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet, O...
OpXorShift, OpGetPix, OpFilRct0, OpPrm, OpF16Sin, Op...
OpPrintd, OpAddDbl, OpSubDbl, OpMulDbl, OpDivDbl, Op...
** (2-3) 内部命令を追加(2)
-関数exec()の直前あたりに以下を追加。
IntP *icpRet;
-case OpDblToInt: の下に以下を追加。
case OpCall: icpRet = icp + 5; icp = (IntP *)...
case OpRet: icp = icpRet; continue;
-とりあえず今は手抜き実装にしていて、リターンアドレスをス...
** (2-4) ブロック構文に関数定義を追加
-before:
enum { BlkIf = 1, BlkFor, BlkMain };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
-after:
enum { BlkIf = 1, BlkFor, BlkMain, BlkFunc };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
enum { FncSkp = 1 };
** (2-5) 構文を追加
-compile()関数に以下を追加。phrCmp(36, "double", pc) のあ...
} else if (phrCmp(37, "void !!*0() {", pc)) {
bd += BInfSiz;
binf[bd] = BlkFunc;
binf[bd + FncSkp] = tmpLabelAlloc();
putIc(OpGoto, &var[binf[bd + FncSkp]], &var[...
var[tc[wpc[0]]] = icq - ic; // ラベルに対応...
varTyp[tc[wpc[0]]] = TypFnc;
} else if (phrCmp(38, "}", pc) && binf[bd] == Bl...
var[binf[bd + FncSkp]] = icq - ic; // ラベル...
bd -= BInfSiz;
} else if (phrCmp(39, "return;", pc)) {
putIc(OpRet, 0, 0, 0, 0);
** (2-6) 関数呼び出し演算子の実装
-追加する場所は phrCmp(99, "( !!**0 )", epc) の前あたり
} else if (phrCmp(82, "!!*0()", epc) && varTyp[tc[wp...
putIc(OpCall, &var[tc[wpc[0]]], &var[tc[wpc[0]]]...
i = Tc0; // 本当はvoidだから0ではないのだけれど...
** (2-7) 分岐処理に対する前処理の改造
-before:
for (icq = ic; icq < icq1; icq += 5) { // goto先の...
i = (int) icq[0];
if ((OpGoto <= i && i <= OpLop) {
icp = *icq[1] + ic;
while ((int) icp[0] == OpGoto) { // 飛び先...
icp = *icp[2] + ic;
}
icq[1] = (IntP) icp;
}
}
-after:
for (icq = ic; icq < icq1; icq += 5) { // goto先の...
i = (int) icq[0];
if (OpGoto <= i && i <= OpLop) || i == OpCall) {
icp = *icq[1] + ic;
while ((int) icp[0] == OpGoto) { // 飛び先...
icp = *icp[2] + ic;
}
icq[1] = (IntP) icp;
}
}
** (3) テスト
-テストプログラム
print 123;
void fnc()
{
print 789;
}
print 456;
fnc();
fnc();
-実行結果
123
456
789
789
** 次回に続く
次回: ''a22_txt03_2a''
*こめんと欄
#comment
ページ名: