「10日くらいでできる!プログラミング言語自作入門」の続編#1-1a
(1) HL-11a
- HL-11では、JITコンパイラ化のための下準備がメインで、命令としては単純代入とprint命令だけ対応しました。
- さすがにそれだけでさみしすぎるので、普通の演算子を全部JITコンパイラ化しようと思います。
#include <acl.c>
typedef unsigned char *String; // こう書くと String は unsigned char * の代用になる.
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つ当たり平均10バイトを想定.
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-9aと同じなので省略
int tc[10000]; // トークンコード.
enum { TcSemi = 0, TcDot, TcWiCard, Tc0, Tc1, Tc2, Tc3, Tc4, Tc5, Tc6, Tc7, Tc8, TcBrOpn, TcBrCls, TcSqBrOpn, TcSqBrCls, TcCrBrOpn, TcCrBrCls,
TcEEq, TcNEq, TcLt, TcGe, TcLe, TcGt, TcPlus, TcMinus, TcAster, TcSlash, TcPerce, TcAnd, TcShr, TcPlPlus, TcEqu,
TcComma, TcExpr, TcExpr0, TcTmp0, TcTmp1, TcTmp2, TcTmp3, TcTmp4, TcTmp5, TcTmp6, TcTmp7, TcTmp8, TcTmp9 };
char tcInit[] = "; . !!* 0 1 2 3 4 5 6 7 8 ( ) [ ] { } == != < >= <= > + - * / % & >> ++ = , !!** !!*** _t0 _t1 _t2 _t3 _t4 _t5 _t6 _t7 _t8 _t9";
///////////////////////////////////////////////////////////////////////////////
int phrCmp_tc[32 * 100], ppc1, wpc[9], wpc1[9]; // ppc1:一致したフレーズの次のトークンをさす, wpc[]:ワイルドカードのトークンの場所をさす.
int phrCmp(int pid, String phr, int pc) → HL-7と同じなので省略
/////////////////////////////////////////////////////////////////////////////// → ここまではHL-11と全く同じ、ここから改造が始まる.
typedef AInt *IntP; // こう書くと IntP は AInt * の代わりに使えるようになる.
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 };
String opBin[] = { // 二項演算子のための機械語.
"8b_%1m0; 3b_%2m0; 0f_94_c0; 83_e0_01; 89_%0m0;", // TcEEq ==
"8b_%1m0; 3b_%2m0; 0f_95_c0; 83_e0_01; 89_%0m0;", // TcNEq !=
"8b_%1m0; 3b_%2m0; 0f_9c_c0; 83_e0_01; 89_%0m0;", // TcLt <
"8b_%1m0; 3b_%2m0; 0f_9d_c0; 83_e0_01; 89_%0m0;", // TcGe >=
"8b_%1m0; 3b_%2m0; 0f_9e_c0; 83_e0_01; 89_%0m0;", // TcLe <=
"8b_%1m0; 3b_%2m0; 0f_9f_c0; 83_e0_01; 89_%0m0;", // TcGt >
"8b_%1m0; 03_%2m0; 89_%0m0;", // TcPlus +
"8b_%1m0; 2b_%2m0; 89_%0m0;", // TcMinus -
"8b_%1m0; f7_%2m5; 89_%0m0;", // TcAster *
"8b_%1m0; 99; f7_%2m7; 89_%0m0;", // TcSlash /
"8b_%1m0; 99; f7_%2m7; 89_%0m2;", // TcPerce %
"8b_%1m0; 23_%2m0; 89_%0m0;", // TcAnd &
"8b_%1m0; 8b_%2m1; d3_f8; 89_%0m0;" // TcShr >>
};
unsigned char *ic, *icq; // ic[]:内部コード、icq:ic[]への書き込み用ポインタ.
void putIc(int op, IntP p0, IntP p1, IntP p2, IntP p3) → HL-11と同じなので省略
int getHex(int c) → HL-11と同じなので省略
int get32(unsigned char *p) → HL-11と同じなので省略
void put32(unsigned char *p, int i) → HL-11と同じなので省略
void putIcX86_sub(String s, IntP a[]) → HL-11と同じなので省略
void putIcX86(String s, IntP p0, IntP p1, IntP p2, IntP p3) → HL-11と同じなので省略
次回に続く
こめんと欄