a21_txt01_9
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 川合のプログラミング言語自作のためのテキスト第三版#9
-(by [[K]], 2021.03.19)
** (1) HL-9
-今回は、HL-8aをaclライブラリを利用できるように書き換えた...
-追加の命令は以下の通りです。
|タイプ|形式|説明|HL-9aのどのサンプルで使っているか?|
|関数|mul64shr(a, b, c)|a * b を64bitで計算して、結果を >...
|関数|aRgb8(r, g, b)|0~255のRGB値から、色番号を得る。|ma...
|関数|aOpenWin(sx, sy, t, dmy)|グラフィックウィンドウを開...
|関数|aXorShift32()|32bit符号付き整数の乱数を返す。|maze|
|関数|aGetPix(win, x, y)|グラフィックウィンドウ上のピクセ...
|関数|ff16sin(t)|角度は1周を65536度とする。そして結果は65...
|関数|ff16cos(t)|角度は1周を65536度とする。そして結果は65...
|関数|aInkey(dmy, mod)|グラフィックウィンドウに入力された...
|命令|aSetPix0(win, x, y, col)|グラフィックウィンドウの座...
|命令|aWait(msec)|指定した秒数(ミリ秒)だけ待つ。|mandel...
|命令|aFillRect0(win, xsiz, ysiz, x, y, c)|グラフィックウ...
|命令|aDrawStr0(win, x, y, col, bcol, str)|グラフィックウ...
|命令|gprintDec(win, x, y, len, col, bcol, i)|グラフィッ...
|命令|bitblt(win, xsiz, ysiz, x, y, ary)|配列ary[]に入っ...
-このうち、mul64shr()とff16sin()とff16cos()は、整数演算し...
-aclライブラリでは、intptr_tの代わりにAIntを使うのが標準...
-aclライブラリでは、main()関数をvoid aMain()に書き換える...
--argcやargvはaArgc, aArgvで参照できます。
-aclライブラリは標準ライブラリのincludeを含むので、プログ...
#include <acl.c>
typedef unsigned char *String; // こう書くと String は u...
int loadText(String path, String t, int siz) → HL-4と同...
////////////////////////////////////////////////////////...
#define MAX_TC 1000 // トークンコードの最大値.
String ts[MAX_TC + 1]; // トークンの内容(文字列)を記憶.
int tl[MAX_TC + 1]; // トークンの長さ.
unsigned char tcBuf[(MAX_TC + 1) * 10]; // トークン1つ当...
int tcs = 0, tcb = 0;
AInt var[MAX_TC + 1]; // 変数. (!)
int getTc(String s, int len) → HL-8aと同じなので省略
////////////////////////////////////////////////////////...
int isAlphabetOrNumber(unsigned char c) → HL-2と同じなの...
int lexer(String s, int tc[]) → HL-8aと同じなので省略
int tc[10000]; // トークンコード.
enum { TcSemi = 0, TcDot, TcWiCard, Tc0, Tc1, Tc2, Tc3, ...
TcEEq, TcNEq, TcLt, TcGe, TcLe, TcGt, TcPlus, TcMinu...
TcComma, TcExpr, TcExpr0, TcTmp0, TcTmp1, TcTmp2, Tc...
char tcInit[] = "; . !!* 0 1 2 3 4 5 6 7 8 ( ) [ ] { } =...
////////////////////////////////////////////////////////...
int phrCmp_tc[32 * 100], ppc1, wpc[9], wpc1[9]; // ppc1:...
int phrCmp(int pid, String phr, int pc) → HL-7と同じなの...
////////////////////////////////////////////////////////...
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...
IntP ic[10000], *icq; // ic[]:内部コード、icq:ic[]への書...
void putIc(int op, IntP p0, IntP p1, IntP p2, IntP p3) →...
////////////////////////////////////////////////////////...
char tmp_flag[10]; // 一時変数の利用状況を管理.
int tmpAlloc() → HL-7と同じなので省略
void tmpFree(int i) → HL-7と同じなので省略
////////////////////////////////////////////////////////...
int epc, epc1; // exprのためのpcとpc1.
int exprSub(int priority); // exprSub1()が参照するので、...
int expr(int j);
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
int exprSub1(int i, int priority, int op) → HL-7と同じな...
int exprSub(int priority)
{
int i = -1, e0 = 0, e1 = 0;
ppc1 = 0;
(中略)
} else if (tc[epc] == TcMinus) { // 単項マイナス.
epc++;
e0 = exprSub(2);
i = tmpAlloc();
putIc(OpNeg, &var[i], &var[e0], 0, 0);
+ } else if (phrCmpPutIc(72, "mul64shr(!!**1, !!**2, !...
+ } else if (phrCmpPutIc(73, "aRgb8(!!**1, !!**2, !!**...
+ } else if (phrCmpPutIc(74, "aOpenWin(!!**0, !!**1, !...
+ i = Tc0;
+ } else if (phrCmpPutIc(75, "aXorShift32()", ...
+ } else if (phrCmpPutIc(76, "aGetPix(!!**8, !!**1, !!...
+ } else if (phrCmpPutIc(77, "ff16sin(!!**1)", ...
+ } else if (phrCmpPutIc(78, "ff16cos(!!**1)", ...
+ } else if (phrCmpPutIc(79, "aInkey(!!***8 , !!**1)",...
} else { // 変数もしくは定数.
i = tc[epc];
epc++;
}
(中略)
}
int expr(int j) → HL-7と同じなので省略
////////////////////////////////////////////////////////...
enum { IfTrue = 0, IfFalse = 1 };
void ifgoto(int i, int not, int label) → HL-8と同じなの...
int tmpLabelNo;
int tmpLabelAlloc() → HL-8と同じなので省略
#define BInfSiz 10
int binf[BInfSiz * 100], bd, lbd; // binf:block-info, bd...
enum { BlkIf = 1, BlkFor };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
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;
}
////////////////////////////////////////////////////////...
int compile(String s)
{
(中略)
! } else if (phrCmpPutIc( 4, "print !!**0;", pc, 0...
(中略)
! } else if (phrCmpPutIc( 7, "time;", pc, 0, 0, Op...
(中略)
} else if (phrCmp(19, "if (!!**0) break;", pc) &...
ifgoto(0, IfTrue, binf[lbd + ForBrk ]);
! } else if (phrCmpPutIc(20, "prints !!**0;", pc, ...
} else if (phrCmp(21, "int !!*0[!!**2];", pc)) {
e2 = expr(2);
putIc(OpAryNew, &var[tc[wpc[0]]], &var[e2], ...
} else if (phrCmp(22, "int !!*0[!!**2] = {", pc)...
(中略)
+ } else if (phrCmpPutIc(23, "aSetPix0(!!***8, !!*...
+ } else if (phrCmpPutIc(24, "aWait(!!**0);", ...
+ } else if (phrCmpPutIc(25, "aFillRect0(!!***8, !...
+ } else if (phrCmpPutIc(26, "aDrawStr0(!!***8, !!...
+ } else if (phrCmpPutIc(27, "gprintDec(!!***8, !!...
+ } else if (phrCmpPutIc(28, "bitblt(!!***8, !!**0...
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
(中略)
}
AWindow *win; // この行を追加.
void exec()
{
clock_t t0 = clock();
IntP *icp = ic;
! AInt i, j, *a, sx, sy;
+ AInt32 *p32;
+ char s[100];
for (;;) {
switch ((int) icp[0]) {
(中略)
case OpEnd:
+ if (win != 0)
+ aFlushAll(win);
return;
(中略:ここの中のintptr_tもAIntに置換すること)
+ case OpOpnWin:
+ if (win != 0) {
+ if (win->xsiz < *icp[1] || win->ysiz < *...
+ printf("openWin error\n");
+ return;
+ }
+ } else
+ win = aOpenWin(*icp[1], *icp[2], (char *...
+ icp += 5;
+ continue;
+ case OpSetPix0:
+ aSetPix0(win, *icp[1], *icp[2], *icp[3]);
+ icp += 5;
+ continue;
+ case OpM64s:
+ *icp[1] = (((AInt64) *icp[2]) * ((AInt64) *i...
+ icp += 5;
+ continue;
+ case OpRgb8:
+ *icp[1] = aRgb8(*icp[2], *icp[3], *icp[4]);
+ icp += 5;
+ continue;
+ case OpWait:
+ if (*icp[1] == -1) {
+ if (win != 0)
+ aFlushAll(win);
+ return;
+ }
+ aWait(*icp[1]);
+ icp += 5;
+ continue;
+ case OpXorShift:
+ *icp[1] = aXorShift32();
+ icp += 5;
+ continue;
+ case OpGetPix:
+ *icp[1] = aGetPix(win, *icp[2], *icp[3]);
+ icp += 5;
+ continue;
+ case OpFilRct0:
+ aFillRect0(win, *icp[1], *icp[2], *icp[3], *...
+ icp += 10;
+ continue;
+ case OpF16Sin:
+ *icp[1] = (AInt) (sin(*icp[2] * (2 * 3.14159...
+ icp += 5;
+ continue;
+ case OpF16Cos:
+ *icp[1] = (AInt) (cos(*icp[2] * (2 * 3.14159...
+ icp += 5;
+ continue;
+ case OpInkey:
+ *icp[1] = aInkey(win, *icp[2]);
+ icp += 5;
+ continue;
+ case OpDrwStr0:
+ aDrawStr0(win, *icp[1], *icp[2], *icp[3], *i...
+ icp += 10;
+ continue;
+ case OpGprDec:
+ sprintf(s, "%*d", *icp[3], *icp[7]);
+ aDrawStr0(win, *icp[1], *icp[2], *icp[4], *i...
+ icp += 10;
+ continue;
+ case OpBitBlt:
+ a = (AInt *) *icp[6];
+ p32 = &win->buf[*icp[3] + *icp[4] * win->xsi...
+ sx = *icp[1];
+ sy = *icp[2];
+ for (j = 0; j < sy; j++) {
+ for (i = 0; i < sx; i++) {
+ p32[i] = a[i];
+ }
+ a += sx;
+ p32 += win->xsiz;
+ }
+ icp += 10;
+ continue;
}
}
}
int run(String s) → HL-6と同じなので省略
////////////////////////////////////////////////////////...
void aMain() // 関数名を変更.
{
unsigned char txt[10000];
int i;
lexer(tcInit, tc);
! if (aArgc >= 2) {
! if (loadText((String) aArgv[1], txt, 10000) == 0...
run(txt);
}
exit(0);
}
for (;;) { // Read-Eval-Print Loop.
(中略)
}
}
-プログラムは754行になりました。でもやっていることは、組...
-私としては、「組み込み関数を増やすのは簡単だ」ということ...
--組み込み関数を1つ増やすためには、enumに内部コード番号を...
----
-このHL-9は例えば以下のプログラムを実行できます。
win = aOpenWin(256, 256, "gradation", 1);
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
aSetPix0(win, x, y, aRgb8(y, x, 0));
}
}
-http://k.osask.jp/files/pic20200917a.png
-これが動くのは当たり前だし当然なのですが、しかしそれでも...
-他にも、mandelやmazeやkcubeやinvaderが動くのですが、今そ...
** (2) phrCmpPutIc()について
-HL-9を作り始めた時は、以下のような記述の繰り返しになって...
} else if (phrCmp(23, "aSetPix0(!!***8, !!**0, !!**1, !!...
e0 = expr(0);
e1 = expr(1);
e2 = expr(2);
putIc(OpSetPix0, &var[e0], &var[e1], &var[e2], 0);
} else if (phrCmp(24, "aWait(!!**0);", pc)) {
e0 = expr(0);
putIc(OpWait, &var[e0], 0, 0, 0);
} else if (phrCmp(25, "aFillRect0(!!***8, !!**0, !!**1, ...
e0 = expr(0);
e1 = expr(1);
e2 = expr(2);
e3 = expr(3);
e4 = expr(4);
putIc(OpFilRct0, &var[e0], &var[e1], &var[e2], &var[...
putIc(OpPrm, &var[e4], 0, 0, 0);
-こんな記述を繰り返すのは面倒で行数も食います。それでこれ...
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) { // もしphrCmp()の結果が1...
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc(); // もしpiが0でなけ...
i0 = 1;
}
for (i = i0; i < lenExpr; i++) { // e0 = expr(0)...
e[i] = expr(i);
}
putIc(op, &var[e[0]], &var[e[1]], &var[e[2]], &v...
if (lenExpr >= 5) { // e[4]以降も使われていたら...
putIc(OpPrm, &var[e[4]], &var[e[5]], &var[e[...
}
for (i = i0; i < lenExpr; i++) { // e1~が負では...
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]); // e1~をtmpFree()する.
}
return 1;
}
return 0;
}
-これがあれば、先の例は、
} else if (phrCmpPutIc(23, "aSetPix0(!!***8, !!**0, !!**...
} else if (phrCmpPutIc(24, "aWait(!!**0);", ...
} else if (phrCmpPutIc(25, "aFillRect0(!!***8, !!**0, !!...
-のように、if文の条件成立節の中に何も書かなくていいほどシ...
** (3) aclライブラリについて
-普通、グラフィックスを使ったプログラムはOS依存があり、だ...
-だからaclライブラリを使って作ったプログラムはそのまま他...
-このような性質を持つのは、なにもこのaclライブラリだけで...
-aclライブラリの関数は、たいていaで始まる名前が付けられて...
** (4) aclライブラリの入手方法
-Windowsの場合: (Windows専用版を使う方法と、SDL2.0対応...
--[[aclib21]](Windows専用版をMinGW-5.1.6で使う例)
--[[aclib07]](SDL2.0対応版をMinGW-5.1.6で使う例)
-MacOSの場合:
--準備中(とりあえず今は[[aclib06]]でしのいでください)
-Linuxの場合:
--[[aclib17]]
-Androidの場合: (Android 7.0以降が必要です。スマートフ...
--[[aclib08]] (SDL2.0対応版をTermux+clangで使う例)
-ラズベリーパイの場合:
--準備中(とりあえず今は[[aclib06]]でしのいでください)
-「はりぼてOS」の場合:
--準備中
-その他(SDL2.0とCの標準ライブラリを使った一般的なやり方...
--[[aclib06]]
** (5) なぜHL-9ではaOpenWin()がいつも0を返して、aSetPix0(...
-普通にwinのポインタを返す仕様にすることもできたのですが...
-それならば、いっそのことwinの値はHL-9が内部で管理してお...
-なんとなく思いつきでやってみただけです。あまり深い意味は...
** (6)[追記]aclライブラリの不備?
-ひょっとすると、上記で公開済みのaclライブラリは、いくつ...
--後日aclライブラリ自体をきちんと整理しないといけないなあ。
static AUInt32 aXorShift32_i = 2463534242U;
ASTATIC void aXorShift32_seed(AUInt32 s)
{
aXorShift32_i = 2463534242U ^ s;
}
ASTATIC AUInt32 aXorShift32()
{
AUInt32 i = aXorShift32_i;
i = i ^ (i << 13);
i = i ^ (i >> 17);
i = i ^ (i << 5);
aXorShift32_i = i;
return i;
}
ASTATIC AInt32 aGetPix(AWindow *w, AInt16 x, AInt16 y)
{
return w->buf[y * w->xsiz + x];
}
-さらにacl.cのmain()関数の中の、aMain();呼び出しの直前に...
aXorShift32_seed((unsigned int) time(0));
** 次回に続く
-次回: [[a21_txt01_9a]]
*こめんと欄
#comment
終了行:
* 川合のプログラミング言語自作のためのテキスト第三版#9
-(by [[K]], 2021.03.19)
** (1) HL-9
-今回は、HL-8aをaclライブラリを利用できるように書き換えた...
-追加の命令は以下の通りです。
|タイプ|形式|説明|HL-9aのどのサンプルで使っているか?|
|関数|mul64shr(a, b, c)|a * b を64bitで計算して、結果を >...
|関数|aRgb8(r, g, b)|0~255のRGB値から、色番号を得る。|ma...
|関数|aOpenWin(sx, sy, t, dmy)|グラフィックウィンドウを開...
|関数|aXorShift32()|32bit符号付き整数の乱数を返す。|maze|
|関数|aGetPix(win, x, y)|グラフィックウィンドウ上のピクセ...
|関数|ff16sin(t)|角度は1周を65536度とする。そして結果は65...
|関数|ff16cos(t)|角度は1周を65536度とする。そして結果は65...
|関数|aInkey(dmy, mod)|グラフィックウィンドウに入力された...
|命令|aSetPix0(win, x, y, col)|グラフィックウィンドウの座...
|命令|aWait(msec)|指定した秒数(ミリ秒)だけ待つ。|mandel...
|命令|aFillRect0(win, xsiz, ysiz, x, y, c)|グラフィックウ...
|命令|aDrawStr0(win, x, y, col, bcol, str)|グラフィックウ...
|命令|gprintDec(win, x, y, len, col, bcol, i)|グラフィッ...
|命令|bitblt(win, xsiz, ysiz, x, y, ary)|配列ary[]に入っ...
-このうち、mul64shr()とff16sin()とff16cos()は、整数演算し...
-aclライブラリでは、intptr_tの代わりにAIntを使うのが標準...
-aclライブラリでは、main()関数をvoid aMain()に書き換える...
--argcやargvはaArgc, aArgvで参照できます。
-aclライブラリは標準ライブラリのincludeを含むので、プログ...
#include <acl.c>
typedef unsigned char *String; // こう書くと String は u...
int loadText(String path, String t, int siz) → HL-4と同...
////////////////////////////////////////////////////////...
#define MAX_TC 1000 // トークンコードの最大値.
String ts[MAX_TC + 1]; // トークンの内容(文字列)を記憶.
int tl[MAX_TC + 1]; // トークンの長さ.
unsigned char tcBuf[(MAX_TC + 1) * 10]; // トークン1つ当...
int tcs = 0, tcb = 0;
AInt var[MAX_TC + 1]; // 変数. (!)
int getTc(String s, int len) → HL-8aと同じなので省略
////////////////////////////////////////////////////////...
int isAlphabetOrNumber(unsigned char c) → HL-2と同じなの...
int lexer(String s, int tc[]) → HL-8aと同じなので省略
int tc[10000]; // トークンコード.
enum { TcSemi = 0, TcDot, TcWiCard, Tc0, Tc1, Tc2, Tc3, ...
TcEEq, TcNEq, TcLt, TcGe, TcLe, TcGt, TcPlus, TcMinu...
TcComma, TcExpr, TcExpr0, TcTmp0, TcTmp1, TcTmp2, Tc...
char tcInit[] = "; . !!* 0 1 2 3 4 5 6 7 8 ( ) [ ] { } =...
////////////////////////////////////////////////////////...
int phrCmp_tc[32 * 100], ppc1, wpc[9], wpc1[9]; // ppc1:...
int phrCmp(int pid, String phr, int pc) → HL-7と同じなの...
////////////////////////////////////////////////////////...
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...
IntP ic[10000], *icq; // ic[]:内部コード、icq:ic[]への書...
void putIc(int op, IntP p0, IntP p1, IntP p2, IntP p3) →...
////////////////////////////////////////////////////////...
char tmp_flag[10]; // 一時変数の利用状況を管理.
int tmpAlloc() → HL-7と同じなので省略
void tmpFree(int i) → HL-7と同じなので省略
////////////////////////////////////////////////////////...
int epc, epc1; // exprのためのpcとpc1.
int exprSub(int priority); // exprSub1()が参照するので、...
int expr(int j);
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
int exprSub1(int i, int priority, int op) → HL-7と同じな...
int exprSub(int priority)
{
int i = -1, e0 = 0, e1 = 0;
ppc1 = 0;
(中略)
} else if (tc[epc] == TcMinus) { // 単項マイナス.
epc++;
e0 = exprSub(2);
i = tmpAlloc();
putIc(OpNeg, &var[i], &var[e0], 0, 0);
+ } else if (phrCmpPutIc(72, "mul64shr(!!**1, !!**2, !...
+ } else if (phrCmpPutIc(73, "aRgb8(!!**1, !!**2, !!**...
+ } else if (phrCmpPutIc(74, "aOpenWin(!!**0, !!**1, !...
+ i = Tc0;
+ } else if (phrCmpPutIc(75, "aXorShift32()", ...
+ } else if (phrCmpPutIc(76, "aGetPix(!!**8, !!**1, !!...
+ } else if (phrCmpPutIc(77, "ff16sin(!!**1)", ...
+ } else if (phrCmpPutIc(78, "ff16cos(!!**1)", ...
+ } else if (phrCmpPutIc(79, "aInkey(!!***8 , !!**1)",...
} else { // 変数もしくは定数.
i = tc[epc];
epc++;
}
(中略)
}
int expr(int j) → HL-7と同じなので省略
////////////////////////////////////////////////////////...
enum { IfTrue = 0, IfFalse = 1 };
void ifgoto(int i, int not, int label) → HL-8と同じなの...
int tmpLabelNo;
int tmpLabelAlloc() → HL-8と同じなので省略
#define BInfSiz 10
int binf[BInfSiz * 100], bd, lbd; // binf:block-info, bd...
enum { BlkIf = 1, BlkFor };
enum { IfLabel0 = 1, IfLabel1 };
enum { ForLopBgn = 1, ForCont, ForBrk, ForLbd0, ForWpc01...
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;
}
////////////////////////////////////////////////////////...
int compile(String s)
{
(中略)
! } else if (phrCmpPutIc( 4, "print !!**0;", pc, 0...
(中略)
! } else if (phrCmpPutIc( 7, "time;", pc, 0, 0, Op...
(中略)
} else if (phrCmp(19, "if (!!**0) break;", pc) &...
ifgoto(0, IfTrue, binf[lbd + ForBrk ]);
! } else if (phrCmpPutIc(20, "prints !!**0;", pc, ...
} else if (phrCmp(21, "int !!*0[!!**2];", pc)) {
e2 = expr(2);
putIc(OpAryNew, &var[tc[wpc[0]]], &var[e2], ...
} else if (phrCmp(22, "int !!*0[!!**2] = {", pc)...
(中略)
+ } else if (phrCmpPutIc(23, "aSetPix0(!!***8, !!*...
+ } else if (phrCmpPutIc(24, "aWait(!!**0);", ...
+ } else if (phrCmpPutIc(25, "aFillRect0(!!***8, !...
+ } else if (phrCmpPutIc(26, "aDrawStr0(!!***8, !!...
+ } else if (phrCmpPutIc(27, "gprintDec(!!***8, !!...
+ } else if (phrCmpPutIc(28, "bitblt(!!***8, !!**0...
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
(中略)
}
AWindow *win; // この行を追加.
void exec()
{
clock_t t0 = clock();
IntP *icp = ic;
! AInt i, j, *a, sx, sy;
+ AInt32 *p32;
+ char s[100];
for (;;) {
switch ((int) icp[0]) {
(中略)
case OpEnd:
+ if (win != 0)
+ aFlushAll(win);
return;
(中略:ここの中のintptr_tもAIntに置換すること)
+ case OpOpnWin:
+ if (win != 0) {
+ if (win->xsiz < *icp[1] || win->ysiz < *...
+ printf("openWin error\n");
+ return;
+ }
+ } else
+ win = aOpenWin(*icp[1], *icp[2], (char *...
+ icp += 5;
+ continue;
+ case OpSetPix0:
+ aSetPix0(win, *icp[1], *icp[2], *icp[3]);
+ icp += 5;
+ continue;
+ case OpM64s:
+ *icp[1] = (((AInt64) *icp[2]) * ((AInt64) *i...
+ icp += 5;
+ continue;
+ case OpRgb8:
+ *icp[1] = aRgb8(*icp[2], *icp[3], *icp[4]);
+ icp += 5;
+ continue;
+ case OpWait:
+ if (*icp[1] == -1) {
+ if (win != 0)
+ aFlushAll(win);
+ return;
+ }
+ aWait(*icp[1]);
+ icp += 5;
+ continue;
+ case OpXorShift:
+ *icp[1] = aXorShift32();
+ icp += 5;
+ continue;
+ case OpGetPix:
+ *icp[1] = aGetPix(win, *icp[2], *icp[3]);
+ icp += 5;
+ continue;
+ case OpFilRct0:
+ aFillRect0(win, *icp[1], *icp[2], *icp[3], *...
+ icp += 10;
+ continue;
+ case OpF16Sin:
+ *icp[1] = (AInt) (sin(*icp[2] * (2 * 3.14159...
+ icp += 5;
+ continue;
+ case OpF16Cos:
+ *icp[1] = (AInt) (cos(*icp[2] * (2 * 3.14159...
+ icp += 5;
+ continue;
+ case OpInkey:
+ *icp[1] = aInkey(win, *icp[2]);
+ icp += 5;
+ continue;
+ case OpDrwStr0:
+ aDrawStr0(win, *icp[1], *icp[2], *icp[3], *i...
+ icp += 10;
+ continue;
+ case OpGprDec:
+ sprintf(s, "%*d", *icp[3], *icp[7]);
+ aDrawStr0(win, *icp[1], *icp[2], *icp[4], *i...
+ icp += 10;
+ continue;
+ case OpBitBlt:
+ a = (AInt *) *icp[6];
+ p32 = &win->buf[*icp[3] + *icp[4] * win->xsi...
+ sx = *icp[1];
+ sy = *icp[2];
+ for (j = 0; j < sy; j++) {
+ for (i = 0; i < sx; i++) {
+ p32[i] = a[i];
+ }
+ a += sx;
+ p32 += win->xsiz;
+ }
+ icp += 10;
+ continue;
}
}
}
int run(String s) → HL-6と同じなので省略
////////////////////////////////////////////////////////...
void aMain() // 関数名を変更.
{
unsigned char txt[10000];
int i;
lexer(tcInit, tc);
! if (aArgc >= 2) {
! if (loadText((String) aArgv[1], txt, 10000) == 0...
run(txt);
}
exit(0);
}
for (;;) { // Read-Eval-Print Loop.
(中略)
}
}
-プログラムは754行になりました。でもやっていることは、組...
-私としては、「組み込み関数を増やすのは簡単だ」ということ...
--組み込み関数を1つ増やすためには、enumに内部コード番号を...
----
-このHL-9は例えば以下のプログラムを実行できます。
win = aOpenWin(256, 256, "gradation", 1);
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
aSetPix0(win, x, y, aRgb8(y, x, 0));
}
}
-http://k.osask.jp/files/pic20200917a.png
-これが動くのは当たり前だし当然なのですが、しかしそれでも...
-他にも、mandelやmazeやkcubeやinvaderが動くのですが、今そ...
** (2) phrCmpPutIc()について
-HL-9を作り始めた時は、以下のような記述の繰り返しになって...
} else if (phrCmp(23, "aSetPix0(!!***8, !!**0, !!**1, !!...
e0 = expr(0);
e1 = expr(1);
e2 = expr(2);
putIc(OpSetPix0, &var[e0], &var[e1], &var[e2], 0);
} else if (phrCmp(24, "aWait(!!**0);", pc)) {
e0 = expr(0);
putIc(OpWait, &var[e0], 0, 0, 0);
} else if (phrCmp(25, "aFillRect0(!!***8, !!**0, !!**1, ...
e0 = expr(0);
e1 = expr(1);
e2 = expr(2);
e3 = expr(3);
e4 = expr(4);
putIc(OpFilRct0, &var[e0], &var[e1], &var[e2], &var[...
putIc(OpPrm, &var[e4], 0, 0, 0);
-こんな記述を繰り返すのは面倒で行数も食います。それでこれ...
int phrCmpPutIc(int pid, String phr, int pc, int *pi, in...
{
int e[9], i, i0 = 0;
if (phrCmp(pid, phr, pc)) { // もしphrCmp()の結果が1...
e[0] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] =...
if (pi != 0) {
e[0] = *pi = tmpAlloc(); // もしpiが0でなけ...
i0 = 1;
}
for (i = i0; i < lenExpr; i++) { // e0 = expr(0)...
e[i] = expr(i);
}
putIc(op, &var[e[0]], &var[e[1]], &var[e[2]], &v...
if (lenExpr >= 5) { // e[4]以降も使われていたら...
putIc(OpPrm, &var[e[4]], &var[e[5]], &var[e[...
}
for (i = i0; i < lenExpr; i++) { // e1~が負では...
if (e[i] < 0) {
*err = -1;
}
tmpFree(e[i]); // e1~をtmpFree()する.
}
return 1;
}
return 0;
}
-これがあれば、先の例は、
} else if (phrCmpPutIc(23, "aSetPix0(!!***8, !!**0, !!**...
} else if (phrCmpPutIc(24, "aWait(!!**0);", ...
} else if (phrCmpPutIc(25, "aFillRect0(!!***8, !!**0, !!...
-のように、if文の条件成立節の中に何も書かなくていいほどシ...
** (3) aclライブラリについて
-普通、グラフィックスを使ったプログラムはOS依存があり、だ...
-だからaclライブラリを使って作ったプログラムはそのまま他...
-このような性質を持つのは、なにもこのaclライブラリだけで...
-aclライブラリの関数は、たいていaで始まる名前が付けられて...
** (4) aclライブラリの入手方法
-Windowsの場合: (Windows専用版を使う方法と、SDL2.0対応...
--[[aclib21]](Windows専用版をMinGW-5.1.6で使う例)
--[[aclib07]](SDL2.0対応版をMinGW-5.1.6で使う例)
-MacOSの場合:
--準備中(とりあえず今は[[aclib06]]でしのいでください)
-Linuxの場合:
--[[aclib17]]
-Androidの場合: (Android 7.0以降が必要です。スマートフ...
--[[aclib08]] (SDL2.0対応版をTermux+clangで使う例)
-ラズベリーパイの場合:
--準備中(とりあえず今は[[aclib06]]でしのいでください)
-「はりぼてOS」の場合:
--準備中
-その他(SDL2.0とCの標準ライブラリを使った一般的なやり方...
--[[aclib06]]
** (5) なぜHL-9ではaOpenWin()がいつも0を返して、aSetPix0(...
-普通にwinのポインタを返す仕様にすることもできたのですが...
-それならば、いっそのことwinの値はHL-9が内部で管理してお...
-なんとなく思いつきでやってみただけです。あまり深い意味は...
** (6)[追記]aclライブラリの不備?
-ひょっとすると、上記で公開済みのaclライブラリは、いくつ...
--後日aclライブラリ自体をきちんと整理しないといけないなあ。
static AUInt32 aXorShift32_i = 2463534242U;
ASTATIC void aXorShift32_seed(AUInt32 s)
{
aXorShift32_i = 2463534242U ^ s;
}
ASTATIC AUInt32 aXorShift32()
{
AUInt32 i = aXorShift32_i;
i = i ^ (i << 13);
i = i ^ (i >> 17);
i = i ^ (i << 5);
aXorShift32_i = i;
return i;
}
ASTATIC AInt32 aGetPix(AWindow *w, AInt16 x, AInt16 y)
{
return w->buf[y * w->xsiz + x];
}
-さらにacl.cのmain()関数の中の、aMain();呼び出しの直前に...
aXorShift32_seed((unsigned int) time(0));
** 次回に続く
-次回: [[a21_txt01_9a]]
*こめんと欄
#comment
ページ名: