はじめに
諸般の流れから日本語プログラミング言語Mindで固定小数点計算機能を書いてみようかなと思い立ち、Mind開発者の@killyさんからMind8に倍精度整数があると伺ったのを契機に、諸般の都合でMind8のkernelの修正実行に挑戦。
前回で倍精度整数同士の加算のめぼしがつきましたので今回は倍精度整数(64bit整数)の変数同士の四則演算と論理演算の一部(等しいと大きい)を実装してみます。もしも本記事の内容をお試ししたい場合は諸般の事情でMind7のライセンスが必要となりますのでご注意ください。
前提条件
Windows11 Pro 22H2
VSCode(Visual Studo Code) 1.86.1
Microsoft Visual C++ 2008 Express Edition
Mind Version 7.5 for Windows
Mind Version 8.07 for Windows
MindはMind8のバージョンのパスが構成されていることを前提とします。
VSCodeの拡張機能
C/C++ for Visual Studio Code 1.18.5 Microsoft
C/C++ Extension Pack 1.3.0 Microsoft
C/C++のデバッガはMind8のCカーネルアプリケーションをデバッグ実行するために使用しています。
お題のソースコード C関数
Mind8標準のスタック操作内部関数push_quad()が64bitイメージのうち下位32bitの上位16bitを0でマスクする仕様のようでしたので、下位32bitをそのままMind8スタックにプッシュするpush_quad2()をcompword.c内のpush_quad()定義部の下に追記します。その下にはMind開発者の@killyさんからご紹介いたいだいたMind単語のスタック検査関数c_test_push_quadが定義されています。
PRIVATE void
push_quad( word64 qval )
{
/* ([引数] → quad) */
ULONG hi;
ULONG lo;
hi = qval >> 32;
lo = qval & 0xffff;
PUSH_Q( lo, hi );
}
PRIVATE void
push_quad2( word64 qval )
{
/* ([引数] → quad) */
ULONG hi32;
ULONG lo32;
hi32 = qval >> 32;
lo32 = qval & 0xffffffff;
PUSH_Q( lo32, hi32 );
}
このスタックプッシュ関数push_quad2()を使えば正常動作するだろうという想定で、予約されているダミー関数8つが定義されているother.c内の空いているダミー関数7つを下記のようにすべて使い切って四則演算と等しい、大きいを定義します。
また、push_quad2()用のテスト単語c_test_push_quad2を用意しておきます。
PRIVATE void
c_test_push_quad2( void ) /* ;WORD c_test_push_quad2 */
{
word64 qval;
/* (quad → quad) */
qval = pop_quad();
printf("pop qvalした\n");
printf("qval(16進表記)=%016llx\n", qval);
printf("push qvalして再度戻す\n");
push_quad2( qval );
}
PRIVATE void
qkuwae( void ) /* ;WORD q加え */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1+long2) */
long2 = pop_quad();
long1 = pop_quad();
long1 += long2;
push_quad2(long1);
}
PRIVATE void
qhiku( void ) /* ;WORD q引く */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1-long2) */
long2 = pop_quad();
long1 = pop_quad();
long1 -= long2;
push_quad2(long1);
}
PRIVATE void
qkake( void ) /* ;WORD q掛け */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1*long2) */
long2 = pop_quad();
long1 = pop_quad();
long1 = long1 * long2;
push_quad2(long1);
}
PRIVATE void
qwaru( void ) /* ;WORD q割る */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1/long2) */
long2 = pop_quad();
long1 = pop_quad();
long1 = long1 / long2;
push_quad2(long1);
}
/* --------- 以下は32bit整数値返しなので注意のこと --------- */
/* */
PRIVATE void
qhitosii( void ) /* ;WORD q等しい */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1==long2) */
long2 = pop_quad();
long1 = pop_quad();
PUSH_Q( (long1 == long2), 0 );
}
PRIVATE void
qookii( void ) /* ;WORD q大きい */
{
word64 long1;
word64 long2;
/* (long1, long2 → long1>long2) */
long2 = pop_quad();
long1 = pop_quad();
PUSH_Q( (long1 > long2), 0 );
}
/* end of 'other.c' */
Mind7ツールでc_words修正ビルド
Mind8には単語定義修正ツールが入っていないので、Mind7のライセンスがあることを前提にMind7のbinフォルダからMind8のbinフォルダへツールをコピーしておきます。(前回記事参照)
今回はtasks.jsonに設定しておき、VSCodeターミナルのタスクで実行しました。
* 実行するタスク: c2words 'kernel.c c_words'
c2words 処理中・・kernel.c kerbody.c osdefine.def serialno.def common.def osfunc.h kernel.def ptrdef.c jumpbufmax.h ptrmacro.def wincons0.h dispatch.c kerhot.c compword.c 0ker.c dispword.c kermain.c array.c bunki.c 1ker.c 1kerF.c 1kerFunc.c 2ker0.c 2ker1.c 2ker2.c 2ker22.c 2ker3.c 2ker4.c 2kerU.c 3ker.c 4ker.c mktime.c ms_c.c chmod.c dosdep.c proccomm.c regquery_lib.h regquery.c other.c runtno.c 終り
* ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。
Mind8ツールでfile修正ビルド
ここからはMind8のツール、コンパイラを使用します。
前回記事でMind開発者の@killyさんからMind8ランタイムのシリアル番号チェッカーツールをご提供いただいたので、それをインストールしておきます。
c:\pmind\bin のディレクトリ
2024/03/09 19:42 57,344 incrserial.exe
2024/03/09 19:42 32,742 incrserial.mco
2 個のファイル 90,086 バイト
2024/03/09 19:42 131,072 mrunt057.exe
1 個のファイル 131,072 バイト
ランタイムのシリアル番号チェッカツールを下記のオプションで実行し、シリアル番号をカウントアップしておきます。
C:\developments\vscode\mind8\kernel>incrserial u
42 -> 43 | Generated: serialno.def
fileライブラリをリビルドして開発環境のlibフォルダにコピーします。
C:\developments\vscode\mind8\kernel>cd ../file
C:\developments\vscode\mind8\file>mmake obj\file mind
..\kernel\c_words.wrdが新しい。
[再コンパイル] mind asmword ..\libY\yoyakugoG obj\asmword
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. serialno=43 終了
[再コンパイル] mind console obj\asmword obj\console -local
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
[再コンパイル] mind file obj\console obj\file -local
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
C:\developments\vscode\mind8\file>mcpC -puv obj\file.mco obj\file.sym ..\lib
obj\file.mco -> ..\lib
obj\file.sym -> ..\lib
続いて以前の記事でtasks.jsonに設定してあるnmake allをターミナルのタスクから実行します。
* 実行するタスク: nmake all
Microsoft(R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cl -c -W2 /nologo /Zi /Od kernel.c /Fokernel.obj
kernel.c
c:\developments\vscode\mind8\kernel\compword.c(2359) : warning C4047: '=' : 間接参照のレベルが 'char *' と 'ULONG' で異なっています。
c:\developments\vscode\mind8\kernel\compword.c(2362) : warning C4047: '関数' : 間接参照の
レベルが 'char **' と 'char *' で異なっています。
c:\developments\vscode\mind8\kernel\compword.c(2362) : warning C4024: 'strtod' : の型が 2 の仮引数および実引数と異なります。
c:\developments\vscode\mind8\kernel\dispword.c(273) : warning C4090: '関数' : 異なる 'const' 修飾子です。
c:\developments\vscode\mind8\kernel\dispword.c(357) : warning C4090: '関数' : 異なる 'const' 修飾子です。
c:\developments\vscode\mind8\kernel\dispword.c(365) : warning C4090: '関数' : 異なる 'const' 修飾子です。
c:\developments\vscode\mind8\kernel\dispword.c(376) : warning C4090: '関数' : 異なる 'const' 修飾子です。
c:\developments\vscode\mind8\kernel\dispword.c(384) : warning C4090: '関数' : 異なる 'const' 修飾子です。
c:\developments\vscode\mind8\kernel\3ker.c(303) : warning C4028: パラメータの型 1 が関数宣言と一致しません。
c:\developments\vscode\mind8\kernel\3ker.c(309) : warning C4028: パラメータの型 1 が関数宣言と一致しません。
c:\developments\vscode\mind8\kernel\3ker.c(316) : warning C4028: パラメータの型 1 が関数宣言と一致しません。
c:\developments\vscode\mind8\kernel\dosdep.c(888) : warning C4133: '関数' : 'int *' と 'char *' の間で型に互換性がありません。
cl /SUBSYSTEM:console /MACHINE:IX86 /nologo /Zi /Od /OUT:kernel.exe kernel.obj startup.obj osfunc.obj wincons0.obj regquery_lib.obj WSOCK32.LIB advapi32.lib
cl : コマンド ライン warning D9025 : '/Od' より '/Ox' が優先されます。
cl : コマンド ライン warning D9002 : 不明なオプション '/SUBSYSTEM:console' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/MACHINE:IX86' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/OU' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/OT' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/O:' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Ok' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Oe' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Or' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/On' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Oe' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Ol' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/O.' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Oe' を無視します
cl : コマンド ライン warning D9002 : 不明なオプション '/Oe' を無視します
* ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。
警告が出ていますが実行には問題なさそうなので無視しています。
nmake installも実行しておきます。
* 実行するタスク: nmake install
Microsoft(R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
copy c_words.wrd ..\bin
1 個のファイルをコピーしました。
copy kernel.exe ..\bin
1 個のファイルをコピーしました。
copy mindexec.exe ..\bin
1 個のファイルをコピーしました。
copy c_words2.wrd ..\bin
1 個のファイルをコピーしました。
copy compker.exe ..\bin
1 個のファイルをコピーしました。
copy mindexec.exe ..\bin
1 個のファイルをコピーしました。
* ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。
開発環境のbinフォルダはパスを設定しておらず、正規のMind8にパスが通っていますので、kernel.exeをリネームしたmrunt010.exeに手動でコピーします。
C:\developments\vscode\mind8>copy bin\kernel.exe c:\pmind\bin\mrunt010.exe
c:\pmind\bin\mrunt010.exe を上書きしますか? (Yes/No/All): Y
1 個のファイルをコピーしました。
お題のソースコード Mind
今回追加した単語をすべて使うソースを下記のように記述してビルドします。
int64は 倍精度変数。
int64_2は 倍精度変数。
メインとは
0fffffffeHと 000009FFFHを 無処理し 文字列情報合成し int64に 入れ
000000002Hと 000000000Hを 無処理し 文字列情報合成し int64_2に 入れ
int64を $$クアド表示し " "を 表示し int64を $$倍精度表示し 改行し
int64_2を $$クアド表示し " "を 表示し int64_2を $$倍精度表示し 改行し
改行し
int64に int64_2を q加え $$クアド表示し " "を 表示し
int64に int64_2を q加え $$倍精度表示 改行し
int64から int64_2を q引き $$クアド表示し " "を 表示し
int64から int64_2を q引き $$倍精度表示 改行し
int64に int64_2を q掛け $$クアド表示し " "を 表示し
int64に int64_2を q掛け $$倍精度表示 改行し
int64と int64_2を q割り $$クアド表示し " "を 表示し
int64と int64_2を q割り $$倍精度表示 改行し
int64と int64_2を q等しい $$クアド表示し 改行し
int64が int64_2より q大きい $$クアド表示し 改行し
改行し
int64を $$クアド表示し " "を 表示し int64を $$倍精度表示し 改行し
int64に c_test_push_quad2 c_test_push_quad2 $$クアド表示し 改行し 改行し
int64_2を $$クアド表示し " "を 表示し int64_2を $$倍精度表示し 改行し
int64_2を c_test_push_quad2 c_test_push_quad2 $$クアド表示し 改行し
。
前回の記事ではあまりはっきり書いておりませんでしたが、kernelをビルド・デバッグ実行する環境はVisual Studio 2008 command promptを開いて、vscode\mind8\kernelをカレントディレクトリとしてcode .でVSCodeを起動しています。
それに対して、Mindのソースを編集してMindコンパイラでコンパイルする環境は通常のコマンドプロンプトを開いて、vscode\mind8をカレントディレクトリとしてcode .で別のVSCodeインスタンスを起動しています。
正規のMind8のfileライブラリではなく、今回リビルドしたfileライブラリを指定してコンパイルします。
C:\developments\vscode\mind8>mind sample\quad lib\file
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> sample\quad.exe
ここでC環境でデバッグ実行できるようにコンパイルされたmcodeファイルをmindexec.mcoにリネームしてkernelフォルダにコピーしておきます。
C:\developments\vscode\mind8>copy sample\quad.mco kernel\mindexec.mco
kernel\mindexec.mco を上書きしますか? (Yes/No/All): Y
1 個のファイルをコピーしました。
実行結果
kernelをビルド・デバッグ実行する環境でデバッグ実行開始します。
下記はVSCodeのターミナルに出力された実行結果です。
FFFFFFFE|00009FFF 175921860444158
00000002|00000000 2
00000000|0000A000 175921860444160
FFFFFFFC|00009FFF 175921860444156
FFFFFFFC|00013FFF 351843720888316
FFFFFFFF|00004FFF 87960930222079
00000000|00000000
00000001|00000000
FFFFFFFE|00009FFF 175921860444158
pop qvalした
qval(16進表記)=00009ffffffffffe
push qvalして再度戻す
pop qvalした
qval(16進表記)=00009ffffffffffe
push qvalして再度戻す
FFFFFFFE|00009FFF
00000002|00000000 2
pop qvalした
qval(16進表記)=0000000000000002
push qvalして再度戻す
pop qvalした
qval(16進表記)=0000000000000002
push qvalして再度戻す
00000002|00000000
PS C:\developments\vscode\mind8\kernel>
正常動作したようです。演算結果もあっている模様。
スタック検査単語での結果もOKのようです。
ここでC環境で実行したランタイムのシリアル番号チェッカツールでアップデートしたシリアル番号と異なるライブラリでビルドされたmindexec.mcoを実行しようとすると、デバッグ実行時にエラーがでました。
おわりに
今回はいい感じで終われました。本来ならばテストツールでがらがら諸条件を検証しなければならないところですが、本件は学習目的なのでそこは割愛させていただきます。次回は少し調子にのって、いよいよ本丸の固定小数点に迫っていきます。変数の宣言や初期化どうするか(わたしにとっての)難題が山積していますが、(少し納税期限が迫ってきておりますので)少しお休みします。
2024/03/11追記
Mind7ツールc2wordsが更新したファイルを確認しました。追加した単語のmcodeが対応していることが確認できます。
~略~
グローバル。
f余りは アセンブラ定義の処理単語 実数入力 実数出力。
c_test_push_quad2は アセンブラ定義の処理単語。
q加えは アセンブラ定義の処理単語。
q引くは アセンブラ定義の処理単語。
q掛けは アセンブラ定義の処理単語。
q割るは アセンブラ定義の処理単語。
q等しいは アセンブラ定義の処理単語。
q大きいは アセンブラ定義の処理単語。
$$mrunt010は アセンブラ定義の処理単語。
~略~
PRIVATE void famari( void );
PRIVATE void c_test_push_quad2( void );
PRIVATE void qkuwae( void );
PRIVATE void qhiku( void );
PRIVATE void qkake( void );
PRIVATE void qwaru( void );
PRIVATE void qhitosii( void );
PRIVATE void qookii( void );
PRIVATE int mrunt_no( void );
~略~
/*02EF*/ famari,
/*02F0*/ c_test_push_quad2,
/*02F1*/ qkuwae,
/*02F2*/ qhiku,
/*02F3*/ qkake,
/*02F4*/ qwaru,
/*02F5*/ qhitosii,
/*02F6*/ qookii,