a21_txt01_8a
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 川合のプログラミング言語自作のためのテキスト第三版#8a
-(by [[K]], 2021.03.16)
** (1) HL-8a
-今回は、配列と文字列リテラルのサポートです。
-もう少し詳しく言うと、こんな感じです。
--[1]変数の値(var[])の型をintではなく、intptr_tにする。
---こうすることで、変数にポインタの値を入れることもできる...
---intのままでも32bitなら問題ないけど、x64などのようにint...
--[2]getTc()やlexer()を改造して、文字列リテラルを受け付け...
---そしてcompile()にprints命令を追加して、exec()にOpPrint...
--[3]配列については、OpArySet, OpAryGet, OpAryNew, OpAryI...
|icp[0]|icp[1]|icp[2]|icp[3]|icp[4]|動作|説明|
|OpPrints |p1| | | |printf("%s\n", p1);|文字列の表示|
|OpAryNew |p1|p2| | |p1=new intptr_t[p2]; (malloc)|配列...
|OpAryInit|p1|p2|p3| |memcpy(p1,p2,p3*sizeof(inttr_t));|...
|OpArySet |p1|p2|p3| |p1[p2]=p3;|変数の値を配列へ代入|
|OpAryGet |p1|p2|p3| |p3=p1[p2];|配列の値を変数へ代入|
--[4]ついでのおまけ。HL-8まででは加算と減算だけ「a=b+c;」...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h> // intptr_tを使うため.
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;
intptr_t var[MAX_TC + 1]; // 変数. (!)
int getTc(String s, int len) // トークン番号を得るための...
{
int i;
for (i = 0; i < tcs; i++) { // 登録済みの中から探す.
if (len == tl[i] && strncmp(s, ts[i], len) == 0)
break;
}
if (i == tcs) {
if (tcs >= MAX_TC) {
printf("too many tokens\n");
exit(1);
}
strncpy(&tcBuf[tcb], s, len); // 見つからなかっ...
tcBuf[tcb + len] = 0; // 終端文字コード.
ts[i] = &tcBuf[tcb];
tl[i] = len;
tcb += len + 1;
tcs++;
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
+ if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
+ char *p = malloc(len - 1);
+ var[i] = (intptr_t) p;
+ memcpy(p, ts[i] + 1, len - 2); // 手抜き実装...
+ p[len - 2] = 0;
+ }
}
return i;
}
////////////////////////////////////////////////////////...
int isAlphabetOrNumber(unsigned char c) → HL-2と同じなの...
int lexer(String s, int tc[]) // プログラムをトークンコ...
{
int i = 0, j = 0, len; // i:今s[]のどこを読んでいる...
for (;;) {
if (s[i] == ' ' || s[i] == '\t' || s[i] == '\n' ...
i++;
continue;
}
if (s[i] == 0) // ファイル終端.
return j;
len = 0;
if (strchr("(){}[];,", s[i]) != 0) { // 1文字記号.
len = 1;
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
while (strchr("=+-*/!%&~|<>?:.#", s[i + len]...
len++;
+ } else if (s[i] == 34 || s[i] == 39) { // "文字...
+ len = 1;
+ while (s[i + len] != s[i] && s[i + len] >= '...
+ len++;
+ if (s[i + len] == s[i])
+ len++;
} else {
printf("syntax error : %.10s\n", &s[i]);
exit(1);
}
tc[j] = getTc(&s[i], len);
i += len;
j++;
}
}
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 intptr_t *IntP; // こう書くと IntP は intptr_t *...
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
! OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
+ OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet };
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 exprSub1(int i, int priority, int op) → HL-7と同じな...
int exprSub(int priority)
{
! int i = -1, e0 = 0, e1 = 0;
ppc1 = 0;
(中略)
for (;;) {
tmpFree(e0);
+ tmpFree(e1);
! if (i < 0 || e0 < 0 || e1 < 0) return -1; // こ...
if (epc >= epc1) break;
! e0 = e1 = 0;
if (tc[epc] == TcPlPlus) { // 後置インクリメント.
epc++;
e0 = i;
i = tmpAlloc();
putIc(OpCpy, &var[i], &var[e0], 0, 0);
putIc(OpAdd1, &var[e0], 0, 0, 0);
+ } else if (phrCmp(70, "[!!**0]=", epc) && priori...
+ e1 = i;
+ e0 = expr(0);
+ epc = ppc1;
+ i = exprSub(15);
+ putIc(OpArySet, &var[e1], &var[e0], &var[i],...
+ } else if (phrCmp(71, "[!!**0]", epc)) {
+ e1 = i;
+ i = tmpAlloc();
+ e0 = expr(0);
+ putIc(OpAryGet, &var[e1], &var[e0], &var[i],...
+ epc = ppc1;
} else if (TcAster <= tc[epc] && tc[epc] <= TcPe...
i = exprSub1(i, 3, tc[epc] - TcAster + OpMul...
(中略)
}
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 compile(String s)
{
(中略)
} else if (phrCmp( 9, "!!*0 = !!*1 + 1;", pc) &&...
putIc(OpAdd1, &var[tc[wpc[0]]], 0, 0, 0);
! } else if (phrCmp( 2, "!!*0 = !!*1 !!*2 !!*3;", ...
! putIc(tc[wpc[2]] - TcEEq + OpCeq, &var[tc[w...
} else if (phrCmp( 4, "print !!**0;", pc)) { // ...
e0 = expr(0);
putIc(OpPrint, &var[e0], 0, 0, 0);
(中略)
} else if (phrCmp(19, "if ( !!**0 ) break;", pc)...
ifgoto(0, IfTrue, binf[lbd + ForBrk ]);
+ } else if (phrCmp(20, "prints !!**0;", pc)) { //...
+ e0 = expr(0);
+ putIc(OpPrints, &var[e0], 0, 0, 0);
+ } 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)...
+ e2 = expr(2);
+ putIc(OpAryNew, &var[tc[wpc[0]]], &var[e2], ...
+ j = 0;
+ for (i = ppc1; i < pc1; i++) { // コンマ以外...
+ if (tc[i] == TcCrBrCls) break;
+ if (tc[i] != TcComma) {
+ j++;
+ }
+ }
+ if (i >= pc1) goto err;
+ intptr_t *ip = malloc(j * sizeof (intptr_t));
+ j = 0;
+ for (i = ppc1; tc[i] != TcCrBrCls; i++) {
+ if (tc[i] == TcCrBrCls) break;
+ if (tc[i] != TcComma) {
+ ip[j] = var[tc[i]];
+ j++;
+ }
+ }
+ putIc(OpAryInit, &var[tc[wpc[0]]], (IntP) ip...
+ ppc1 = i + 2; // } と ; の分.
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
(中略)
}
void exec()
{
clock_t t0 = clock();
IntP *icp = ic;
! intptr_t i, *a;
for (;;) {
switch ((int) icp[0]) {
(中略)
+ case OpPrints:
+ printf("%s\n", (char *) *icp[1]);
+ icp += 5;
+ continue;
+ case OpAryNew:
+ *icp[1] = (intptr_t) malloc(*icp[2] * sizeof...
+ memset((char *) *icp[1], 0, *icp[2] * sizeof...
+ icp += 5;
+ continue;
+ case OpAryInit:
+ memcpy((char *) *icp[1], (char *) icp[2], ((...
+ icp += 5;
+ continue;
+ case OpArySet:
+ a = (intptr_t *) *icp[1];
+ i = *icp[2];
+ a[i] = *icp[3];
+ icp += 5;
+ continue;
+ case OpAryGet:
+ a = (intptr_t *) *icp[1];
+ i = *icp[2];
+ *icp[3] = a[i];
+ icp += 5;
+ continue;
}
}
}
int run(String s) → HL-6と同じなので省略
////////////////////////////////////////////////////////...
int main(int argc, const char **argv) → HL-5と同じなので...
-プログラムは635行になりました。49行から始まって、思えば...
-この先にHL-9やHL-9aもありますが、それらはお遊びみたいな...
----
-HL-8aにはprints命令があります。
>prints "hello"
hello
-まあ、それだけなのですが・・・。まあ一応、以下みたいなこ...
a = "abc";
if (x > y) {
a = "def";
}
prints a;
-HL-8aでは配列も使えます。
>int a[30] = { 1, 1 }
>for (i = 2; i < 30; i++) { a[i] = a[i - 2] + a[i - 1]; }
>for (i = 0; i < 10; i++) { print a[i]; }
1
1
2
3
5
8
13
21
34
55
** (2) HL-8aの簡単な説明
-基本的なことは、(1)の最初にある程度書いたので、この節で...
-細かいことを書きます。
--文字列リテラルでは、エスケープシーケンスを処理していま...
--配列では、宣言されるたびにmalloc()でメモリを確保してい...
--だからどんどんメモリリークします。これをどうするか考え...
** (3) HL-8aにおける配列アクセスの実現方法
-何も考えずに添え字演算子を実装するとこんな感じになると思...
} else if (phrCmp(71, "[!!**0]", epc)) {
e1 = i;
i = tmpAlloc();
e0 = expr(0);
putIc(OpAryGet, &var[e1], &var[e0], &var[i], 0);
epc = ppc1;
-配列から値を読むだけなら、これで何の問題もなく十分に機能...
-しかし実際には、 a[i] = 3; みたいに配列への代入をするこ...
-ということで、添え字演算子の直後に代入演算子が来た時に限...
-なお、これは上記のphrCmp()よりも先にやらないと、先に上記...
} else if (phrCmp(70, "[!!**0]=", epc) && priority >= 15...
e1 = i;
e0 = expr(0);
epc = ppc1;
i = exprSub(15);
putIc(OpArySet, &var[e1], &var[e0], &var[i], 0);
-こうすることで、a[i] = 3;で配列の値が更新されるようにな...
** 次回に続く
-次回: [[a21_txt01_9]]
*こめんと欄
#comment
終了行:
* 川合のプログラミング言語自作のためのテキスト第三版#8a
-(by [[K]], 2021.03.16)
** (1) HL-8a
-今回は、配列と文字列リテラルのサポートです。
-もう少し詳しく言うと、こんな感じです。
--[1]変数の値(var[])の型をintではなく、intptr_tにする。
---こうすることで、変数にポインタの値を入れることもできる...
---intのままでも32bitなら問題ないけど、x64などのようにint...
--[2]getTc()やlexer()を改造して、文字列リテラルを受け付け...
---そしてcompile()にprints命令を追加して、exec()にOpPrint...
--[3]配列については、OpArySet, OpAryGet, OpAryNew, OpAryI...
|icp[0]|icp[1]|icp[2]|icp[3]|icp[4]|動作|説明|
|OpPrints |p1| | | |printf("%s\n", p1);|文字列の表示|
|OpAryNew |p1|p2| | |p1=new intptr_t[p2]; (malloc)|配列...
|OpAryInit|p1|p2|p3| |memcpy(p1,p2,p3*sizeof(inttr_t));|...
|OpArySet |p1|p2|p3| |p1[p2]=p3;|変数の値を配列へ代入|
|OpAryGet |p1|p2|p3| |p3=p1[p2];|配列の値を変数へ代入|
--[4]ついでのおまけ。HL-8まででは加算と減算だけ「a=b+c;」...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h> // intptr_tを使うため.
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;
intptr_t var[MAX_TC + 1]; // 変数. (!)
int getTc(String s, int len) // トークン番号を得るための...
{
int i;
for (i = 0; i < tcs; i++) { // 登録済みの中から探す.
if (len == tl[i] && strncmp(s, ts[i], len) == 0)
break;
}
if (i == tcs) {
if (tcs >= MAX_TC) {
printf("too many tokens\n");
exit(1);
}
strncpy(&tcBuf[tcb], s, len); // 見つからなかっ...
tcBuf[tcb + len] = 0; // 終端文字コード.
ts[i] = &tcBuf[tcb];
tl[i] = len;
tcb += len + 1;
tcs++;
var[i] = strtol(ts[i], 0, 0); // 定数だった場合...
+ if (ts[i][0] == 34) { // 先頭がダブルクォーテー...
+ char *p = malloc(len - 1);
+ var[i] = (intptr_t) p;
+ memcpy(p, ts[i] + 1, len - 2); // 手抜き実装...
+ p[len - 2] = 0;
+ }
}
return i;
}
////////////////////////////////////////////////////////...
int isAlphabetOrNumber(unsigned char c) → HL-2と同じなの...
int lexer(String s, int tc[]) // プログラムをトークンコ...
{
int i = 0, j = 0, len; // i:今s[]のどこを読んでいる...
for (;;) {
if (s[i] == ' ' || s[i] == '\t' || s[i] == '\n' ...
i++;
continue;
}
if (s[i] == 0) // ファイル終端.
return j;
len = 0;
if (strchr("(){}[];,", s[i]) != 0) { // 1文字記号.
len = 1;
} else if (isAlphabetOrNumber(s[i])) { // 1文字...
while (isAlphabetOrNumber(s[i + len]))
len++;
} else if (strchr("=+-*/!%&~|<>?:.#", s[i]) != 0...
while (strchr("=+-*/!%&~|<>?:.#", s[i + len]...
len++;
+ } else if (s[i] == 34 || s[i] == 39) { // "文字...
+ len = 1;
+ while (s[i + len] != s[i] && s[i + len] >= '...
+ len++;
+ if (s[i + len] == s[i])
+ len++;
} else {
printf("syntax error : %.10s\n", &s[i]);
exit(1);
}
tc[j] = getTc(&s[i], len);
i += len;
j++;
}
}
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 intptr_t *IntP; // こう書くと IntP は intptr_t *...
enum { OpCpy = 0, OpCeq, OpCne, OpClt, OpCge, OpCle, OpC...
! OpAdd1, OpNeg, OpGoto, OpJeq, OpJne, OpJlt, OpJge, O...
+ OpPrints, OpAryNew, OpAryInit, OpArySet, OpAryGet };
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 exprSub1(int i, int priority, int op) → HL-7と同じな...
int exprSub(int priority)
{
! int i = -1, e0 = 0, e1 = 0;
ppc1 = 0;
(中略)
for (;;) {
tmpFree(e0);
+ tmpFree(e1);
! if (i < 0 || e0 < 0 || e1 < 0) return -1; // こ...
if (epc >= epc1) break;
! e0 = e1 = 0;
if (tc[epc] == TcPlPlus) { // 後置インクリメント.
epc++;
e0 = i;
i = tmpAlloc();
putIc(OpCpy, &var[i], &var[e0], 0, 0);
putIc(OpAdd1, &var[e0], 0, 0, 0);
+ } else if (phrCmp(70, "[!!**0]=", epc) && priori...
+ e1 = i;
+ e0 = expr(0);
+ epc = ppc1;
+ i = exprSub(15);
+ putIc(OpArySet, &var[e1], &var[e0], &var[i],...
+ } else if (phrCmp(71, "[!!**0]", epc)) {
+ e1 = i;
+ i = tmpAlloc();
+ e0 = expr(0);
+ putIc(OpAryGet, &var[e1], &var[e0], &var[i],...
+ epc = ppc1;
} else if (TcAster <= tc[epc] && tc[epc] <= TcPe...
i = exprSub1(i, 3, tc[epc] - TcAster + OpMul...
(中略)
}
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 compile(String s)
{
(中略)
} else if (phrCmp( 9, "!!*0 = !!*1 + 1;", pc) &&...
putIc(OpAdd1, &var[tc[wpc[0]]], 0, 0, 0);
! } else if (phrCmp( 2, "!!*0 = !!*1 !!*2 !!*3;", ...
! putIc(tc[wpc[2]] - TcEEq + OpCeq, &var[tc[w...
} else if (phrCmp( 4, "print !!**0;", pc)) { // ...
e0 = expr(0);
putIc(OpPrint, &var[e0], 0, 0, 0);
(中略)
} else if (phrCmp(19, "if ( !!**0 ) break;", pc)...
ifgoto(0, IfTrue, binf[lbd + ForBrk ]);
+ } else if (phrCmp(20, "prints !!**0;", pc)) { //...
+ e0 = expr(0);
+ putIc(OpPrints, &var[e0], 0, 0, 0);
+ } 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)...
+ e2 = expr(2);
+ putIc(OpAryNew, &var[tc[wpc[0]]], &var[e2], ...
+ j = 0;
+ for (i = ppc1; i < pc1; i++) { // コンマ以外...
+ if (tc[i] == TcCrBrCls) break;
+ if (tc[i] != TcComma) {
+ j++;
+ }
+ }
+ if (i >= pc1) goto err;
+ intptr_t *ip = malloc(j * sizeof (intptr_t));
+ j = 0;
+ for (i = ppc1; tc[i] != TcCrBrCls; i++) {
+ if (tc[i] == TcCrBrCls) break;
+ if (tc[i] != TcComma) {
+ ip[j] = var[tc[i]];
+ j++;
+ }
+ }
+ putIc(OpAryInit, &var[tc[wpc[0]]], (IntP) ip...
+ ppc1 = i + 2; // } と ; の分.
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
(中略)
}
void exec()
{
clock_t t0 = clock();
IntP *icp = ic;
! intptr_t i, *a;
for (;;) {
switch ((int) icp[0]) {
(中略)
+ case OpPrints:
+ printf("%s\n", (char *) *icp[1]);
+ icp += 5;
+ continue;
+ case OpAryNew:
+ *icp[1] = (intptr_t) malloc(*icp[2] * sizeof...
+ memset((char *) *icp[1], 0, *icp[2] * sizeof...
+ icp += 5;
+ continue;
+ case OpAryInit:
+ memcpy((char *) *icp[1], (char *) icp[2], ((...
+ icp += 5;
+ continue;
+ case OpArySet:
+ a = (intptr_t *) *icp[1];
+ i = *icp[2];
+ a[i] = *icp[3];
+ icp += 5;
+ continue;
+ case OpAryGet:
+ a = (intptr_t *) *icp[1];
+ i = *icp[2];
+ *icp[3] = a[i];
+ icp += 5;
+ continue;
}
}
}
int run(String s) → HL-6と同じなので省略
////////////////////////////////////////////////////////...
int main(int argc, const char **argv) → HL-5と同じなので...
-プログラムは635行になりました。49行から始まって、思えば...
-この先にHL-9やHL-9aもありますが、それらはお遊びみたいな...
----
-HL-8aにはprints命令があります。
>prints "hello"
hello
-まあ、それだけなのですが・・・。まあ一応、以下みたいなこ...
a = "abc";
if (x > y) {
a = "def";
}
prints a;
-HL-8aでは配列も使えます。
>int a[30] = { 1, 1 }
>for (i = 2; i < 30; i++) { a[i] = a[i - 2] + a[i - 1]; }
>for (i = 0; i < 10; i++) { print a[i]; }
1
1
2
3
5
8
13
21
34
55
** (2) HL-8aの簡単な説明
-基本的なことは、(1)の最初にある程度書いたので、この節で...
-細かいことを書きます。
--文字列リテラルでは、エスケープシーケンスを処理していま...
--配列では、宣言されるたびにmalloc()でメモリを確保してい...
--だからどんどんメモリリークします。これをどうするか考え...
** (3) HL-8aにおける配列アクセスの実現方法
-何も考えずに添え字演算子を実装するとこんな感じになると思...
} else if (phrCmp(71, "[!!**0]", epc)) {
e1 = i;
i = tmpAlloc();
e0 = expr(0);
putIc(OpAryGet, &var[e1], &var[e0], &var[i], 0);
epc = ppc1;
-配列から値を読むだけなら、これで何の問題もなく十分に機能...
-しかし実際には、 a[i] = 3; みたいに配列への代入をするこ...
-ということで、添え字演算子の直後に代入演算子が来た時に限...
-なお、これは上記のphrCmp()よりも先にやらないと、先に上記...
} else if (phrCmp(70, "[!!**0]=", epc) && priority >= 15...
e1 = i;
e0 = expr(0);
epc = ppc1;
i = exprSub(15);
putIc(OpArySet, &var[e1], &var[e0], &var[i], 0);
-こうすることで、a[i] = 3;で配列の値が更新されるようにな...
** 次回に続く
-次回: [[a21_txt01_9]]
*こめんと欄
#comment
ページ名: