a22_txt03
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2022.06.17)
** (1) はじめに
-このテキストは、「10日くらいでできる!プログラミング言語...
-このシリーズでは、言語の実行速度の改善はほとんどしないで...
-[[a21_txt02]]のほうの続編で、「はりぼて言語」はJITコンパ...
-そして、これはごめんなさい案件なのですが、最近ちょっと忙...
** (2) 今回の改造テーマ
-HL-9aでは 10 / 3 の答えは 3 でした。
>print 10/3
3
-まあC言語でも整数の割り算では答えは整数になるのが正しい...
-ということで、今回は小数を扱うための準備をして、次の回で...
** (3-1) lexerの改造(小数の定数を途中で切らないようにす...
-before:
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
-after:
} else if ('0' <= s[i] && s[i] <= '9') { // 1文...
while (isAlphabetOrNumber(s[i + len]) || s[i...
len++;
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
** (3-2) 変数の型を増やす
-before:
AInt var[MAX_TC + 1]; // 変数.
-after:
enum { TypInt, TypDbl };
AInt varTyp[MAX_TC + 1]; // そのトークンは、int型か、dou...
AInt var[MAX_TC + 1]; // int変数.
double varDbl[MAX_TC + 1]; // double変数.
** (3-3) 定数値のセット処理の拡張
-before:
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
char *p = malloc(len - 1);
var[i] = (AInt) p;
memcpy(p, ts[i] + 1, len - 2); // 手抜き実装.
p[len - 2] = 0;
}
-after:
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
varTyp[i] = TypInt;
if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
char *p = malloc(len - 1);
var[i] = (AInt) p;
memcpy(p, ts[i] + 1, len - 2); // 手抜き実装.
p[len - 2] = 0;
} else if (strchr(ts[i], '.') != 0 && '0' <= ts[...
varTyp[i] = TypDbl;
varDbl[i] = strtod(ts[i], 0);
}
** (3-4) OpPrintd と DblP の宣言の追加
-before:
typedef AInt *IntP; // こう書くと IntP は AInt * の代わ...
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...
-after:
typedef AInt *IntP; // こう書くと IntP は AInt * の代わ...
typedef double *DblP; // DblP は double * の代わりになる.
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 };
** (3-5) icpd の宣言と初期化
-before:
for (;;) {
switch ((int) icp[0]) {
-after:
for (;;) {
DblP *icpd = (DblP *) icp;
switch ((int) icp[0]) {
** (3-6) OpPrintd 命令の追加
-OpBitBltの処理の後に以下を追加:
case OpPrintd:
printf("%f\n", *icpd[1]);
icp += 5;
continue;
** (3-7) printfd 命令を追加
- } else if (phrCmp( 8, "!!***0;", pc)) { の前に以下の1行...
} else if (phrCmpPutIc(35, "printd !!**0;", pc, ...
** (3-8) varP() 関数の追加
- int exprSub1(int i, int priority, int op) の直前に以下...
IntP varP(int i) // トークンコード番号から対応する変数の...
{
if (i < 0) return 0; // NULL
if (varTyp[i] == TypInt) return &var[i];
if (varTyp[i] == TypDbl) return (IntP) &varDbl[i];
return 0;
}
** (3-9) phrCmpPutIc() 関数を書き換え
- &var[ ... ] という記述を varP( ... ) に置換します.
-before:
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) {
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc();
i0 = 1;
}
for (i = i0; i < lenExpr; i++) {
e[i] = expr(i);
}
putIc(op, &var[e[0]], &var[e[1]], &var[e[2]], &v...
if (lenExpr >= 5) {
putIc(OpPrm, &var[e[4]], &var[e[5]], &var[e[...
}
for (i = i0; i < lenExpr; i++) {
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]);
}
return 1;
}
return 0;
}
-after:
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) {
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc();
i0 = 1;
}
for (i = i0; i < lenExpr; i++) {
e[i] = expr(i);
}
putIc(op, varP(e[0]), varP(e[1]), varP(e[2]), va...
if (lenExpr >= 5) {
putIc(OpPrm, varP(e[4]), varP(e[5]), varP(e[...
}
for (i = i0; i < lenExpr; i++) {
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]);
}
return 1;
}
return 0;
}
** (4) printd 命令のテスト
>printd 12.34
12.340000
** 次回に続く
次回: [[a22_txt03_1a]]
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2022.06.17)
** (1) はじめに
-このテキストは、「10日くらいでできる!プログラミング言語...
-このシリーズでは、言語の実行速度の改善はほとんどしないで...
-[[a21_txt02]]のほうの続編で、「はりぼて言語」はJITコンパ...
-そして、これはごめんなさい案件なのですが、最近ちょっと忙...
** (2) 今回の改造テーマ
-HL-9aでは 10 / 3 の答えは 3 でした。
>print 10/3
3
-まあC言語でも整数の割り算では答えは整数になるのが正しい...
-ということで、今回は小数を扱うための準備をして、次の回で...
** (3-1) lexerの改造(小数の定数を途中で切らないようにす...
-before:
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
-after:
} else if ('0' <= s[i] && s[i] <= '9') { // 1文...
while (isAlphabetOrNumber(s[i + len]) || s[i...
len++;
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
** (3-2) 変数の型を増やす
-before:
AInt var[MAX_TC + 1]; // 変数.
-after:
enum { TypInt, TypDbl };
AInt varTyp[MAX_TC + 1]; // そのトークンは、int型か、dou...
AInt var[MAX_TC + 1]; // int変数.
double varDbl[MAX_TC + 1]; // double変数.
** (3-3) 定数値のセット処理の拡張
-before:
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
char *p = malloc(len - 1);
var[i] = (AInt) p;
memcpy(p, ts[i] + 1, len - 2); // 手抜き実装.
p[len - 2] = 0;
}
-after:
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
varTyp[i] = TypInt;
if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
char *p = malloc(len - 1);
var[i] = (AInt) p;
memcpy(p, ts[i] + 1, len - 2); // 手抜き実装.
p[len - 2] = 0;
} else if (strchr(ts[i], '.') != 0 && '0' <= ts[...
varTyp[i] = TypDbl;
varDbl[i] = strtod(ts[i], 0);
}
** (3-4) OpPrintd と DblP の宣言の追加
-before:
typedef AInt *IntP; // こう書くと IntP は AInt * の代わ...
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...
-after:
typedef AInt *IntP; // こう書くと IntP は AInt * の代わ...
typedef double *DblP; // DblP は double * の代わりになる.
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 };
** (3-5) icpd の宣言と初期化
-before:
for (;;) {
switch ((int) icp[0]) {
-after:
for (;;) {
DblP *icpd = (DblP *) icp;
switch ((int) icp[0]) {
** (3-6) OpPrintd 命令の追加
-OpBitBltの処理の後に以下を追加:
case OpPrintd:
printf("%f\n", *icpd[1]);
icp += 5;
continue;
** (3-7) printfd 命令を追加
- } else if (phrCmp( 8, "!!***0;", pc)) { の前に以下の1行...
} else if (phrCmpPutIc(35, "printd !!**0;", pc, ...
** (3-8) varP() 関数の追加
- int exprSub1(int i, int priority, int op) の直前に以下...
IntP varP(int i) // トークンコード番号から対応する変数の...
{
if (i < 0) return 0; // NULL
if (varTyp[i] == TypInt) return &var[i];
if (varTyp[i] == TypDbl) return (IntP) &varDbl[i];
return 0;
}
** (3-9) phrCmpPutIc() 関数を書き換え
- &var[ ... ] という記述を varP( ... ) に置換します.
-before:
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) {
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc();
i0 = 1;
}
for (i = i0; i < lenExpr; i++) {
e[i] = expr(i);
}
putIc(op, &var[e[0]], &var[e[1]], &var[e[2]], &v...
if (lenExpr >= 5) {
putIc(OpPrm, &var[e[4]], &var[e[5]], &var[e[...
}
for (i = i0; i < lenExpr; i++) {
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]);
}
return 1;
}
return 0;
}
-after:
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) {
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc();
i0 = 1;
}
for (i = i0; i < lenExpr; i++) {
e[i] = expr(i);
}
putIc(op, varP(e[0]), varP(e[1]), varP(e[2]), va...
if (lenExpr >= 5) {
putIc(OpPrm, varP(e[4]), varP(e[5]), varP(e[...
}
for (i = i0; i < lenExpr; i++) {
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]);
}
return 1;
}
return 0;
}
** (4) printd 命令のテスト
>printd 12.34
12.340000
** 次回に続く
次回: [[a22_txt03_1a]]
*こめんと欄
#comment
ページ名: