今回の目標 配列を実装したときに先送りしちゃった件をなんとかするよ。 // 配列 int main() { int a[10]; a[0] = 42; printf("-a[0] = %d\n", -a[0]); } 本来は-(a[0])と評価しなくちゃいけないんだけど、(-a)[0]って解釈しちゃっててコンパイルに失敗して…
バグ エラー処理周りのチェックをしていてバグを見つけたよ。 // 配列 int main() { double a[10], *p = a; a[0) = 42; a[1] = 55; printf("*p = %f\n", *p); } 配列の閉じ括弧が間違ってる場合。エラーにならずにコンパイル通っちゃってたよ。 read_el # 式…
今回の目標 コマンドライン引数を表示できるように対応するよ。 // コマンドライン int main(int argc, char *argv[]) { for(int i = 0; i < argc; i = i + 1) printf("argv[%d]=%s\n", i, argv[i]); } 関数定義の解析さえ頑張れば大丈夫かな。 function 引…
今回の目標 ポインタに[]演算子を適用できるようにするよ。 // ポインタと配列演算子 int main() { char *p = "myc"; for(int i = 0; i < 3; i = i + 1) putchar(p[i]); putchar('\n'); } 配列演算子っていう呼び方で合ってるんだろうか。 codegen_els 型チ…
今回の目標 前回に続きバグ修正。 // 配列 int main() { double a[10], *p = a; a[0] = 42; a[1] = 55; printf("*p = %f\n", *p); } 間接参照演算子もdouble型とかに対応できてなかったよ。 codegen_unaryop 間接参照演算子の処理のところを修正。 elsif op.…
今回の目標 色々試してたらバグが見つかったよ。 // 配列 int main() { double a[10]; a[0] = 42; a[1] = 55; printf("a[0] = %f\n", a[0]); } 配列の参照だけどint型以外の場合上手く行ってなかった。バグっていうか未サポートってところかな。 codegen_lva…
今回の目標 今回は代入だよ。 // 配列 int main() { int a[10]; a[0] = 42; printf("a[0] = %d\n", a[0]); } まずは単純な場合から。 codegen_assign 今回、大きく書き換えたよ。 # 代入のコード生成 def codegen_assign(el) if el.size != 3 then perror en…
今回の目標 今回は配列の参照だよ。 // 配列 int main() { int a[10], *p; p = a; *p = 42; printf("a[0] = %d\n", a[0]); printf("0[a] = %d\n", 0[a]); printf("10 + a[0] = %d\n", 10 + a[0]); printf("10 + 0[a] = %d\n", 10 + 0[a]); } 配列への代入は…
今回の目標 配列の実装を進めるよ。 // 配列 int main() { int a[10], *p; p = a; printf("p = %016lx\n", p); } 簡単そうなところから。 ヘルパーメソッド # 配列型? def is_array_type?(type) return type.match(/\[.*\]$/) end # 配列型→pointer型 def a…
今回の目標 いきなりだけど配列に手を出してみるよ。 // 配列 int main() { int a[10], b; } まずは配列変数の宣言から。 Lexer gettokenの修正。 # symbolの切り出し elsif m = @line[@idx,@line.length] .match(/^(==|!=|<=|>=|=|<|>|\+|\-|\*|\/|\%|&|:|,…
今回の目標 int型→double型の型変換。 // int型→double型 double func(void) { return 5; } int main() { double x; x = func(); printf("x = %f\n", x); } 最近、return文のとこばかりだな。 statement return文の処理を修正。 if kind == TK::RESERVE && s…
バグ修正 プログラム眺めてたらバグを見っけたよ。 // double型 double dadd(double a, double b) { printf("dadd: %f %f\n", a, b); return a + b; } int main() { double x = 12.3, y = -2.8; printf("%f %f %f\n", x, y, dadd(5.4, 3.2)); printf("%d %d …
今回の目標 前回の続きでreturn文。 // 関数の呼び出し int *sub(void) { return 2.5; } int main() { printf("%d\n",sub()); } 型をチェックするよ。 expr # 式の構文解析 def expr2(fkind,fstr,skind,sstr) el, kind, str = read_modify_el fkind, fstr, s…
今回の目標 単純なreturn文。 // 関数の呼び出し void sub(void) { return; } int main() { sub(); printf("%d\n",42); } これサポートしてなかったよ。 statement return文の処理。 def statement(kind, str) if kind == TK::RESERVE && str == "return" th…
今回の目標 型変換を頑張るよ。 // int型→double型 int func(void) { return 5; } int func2(double a) { return 10; } int main() { int a = 12; double x, *p = &x; x = a; printf("x = %f\n", x); x = x * 2; printf("x = %f\n", x); x = x - a; printf("…
今回の目標 いくつかテストしてる時に気が付いたんだけど、voidを使って関数に引数が無いことを明示する記述の仕方、まだ対応してなかったよ。 // 関数の呼び出し int answer(void) { // Answer to the Ultimate Question of Life, the Universe, and Everyt…
今回の目標 重複したリテラルを一個に纏めるよ。 // double型 double dadd(double a, double b) { printf("dadd: %f %f\n", a, b); return a + b; } int main() { double x = 12.3, y = -2.8; printf("%f %f %f\n", x, y, dadd(5.4, 3.2)); printf("%d %d %f…
今回の目標 double型引数の関数呼出が入子になってる場合に対応するよ。 // double型 double dadd(double a, double b) { printf("dadd: %f %f\n", a, b); return a + b; } int main() { double x = 12.3, y = -2.8; printf("%f %f %f\n", x, y, dadd(5.4, 3…
今回の目標 前回に続きエラーチェック。 // 壊れてる式 int main() { int i; i = ; } 壊れた代入。 codegen_assign # 代入のコード生成 def codegen_assign(el) if el.size != 3 then perror end if el[2] == nil then perror "broken expression" end type_…
今回の目標 double型関連にちょっと疲れたんで別の事やるよ。壊れてる式をチェックしてエラーに。 // 壊れてる式 int main() { 1 + ; } // 壊れてる式 int main() { + ; } // 壊れてる式 int main() { / ; } // 壊れてる式 int main() { int i; i++; } ちょ…
今回の目標 double型の関数だよ。 // double型 double dadd(double a, double b) { return a + b; } int main() { double x = 12.3, y = -2.8, z = dadd(x, y); printf("%f + %f = %f\n", x, y, z); } 引数も返値もdouble型の場合。 function # レジスタで渡…
今回の目標 今回は単項マイナス演算子だよ。 // double型 int main() { double x = 4.5, y = -x; printf("x = %f\ny = %f\n", x, y); } コード生成部 codegen_unaryopの該当部分を修正。 # 単行演算子のコード生成 def codegen_unaryop(op, operand) type = …
今回の目標 前回の残りの比較演算をサポートするよ。 // double型の比較 int main() { double x; x = 1.5; if( x != 1.5 ) printf("true\n"); else printf("false\n"); x = 1.0; if( x != 1.5 ) printf("true\n"); else printf("false\n"); } コード生成部 …
今回の目標 等価演算子をサポートするよ。 // double型の乱数 int main() { double x; x = 1.5; if( x == 1.5 ) printf("true\n"); else printf("false\n"); x = 1.0; if( x == 1.5 ) printf("true\n"); else printf("false\n"); } コード生成部 まずはここ…
今回の目標 sqrtをコールしてみるよ。 // double型 extern double sqrt(double x); int main() { printf("%f\n", 2.0 * sqrt(2.0)); } 前回、関数コールに不安があったんだけど、やってみたらやっぱり駄目だったよ。見直してみたら未修正のところがあった。 …
今回の目標 前回に続き四則演算。 // double型 int main() { printf("%f\n", 2.0 + 5.0 / 2.0); } 前回対応できなかった複雑な式。 コード生成部 codegen_elsの括弧の処理部と関数呼出の処理部を修正。 def codegen_els(op, operand, type_l) ostr = mnemoni…
素数の表示 Haskellだけど細々と勉強続けてるよ。でもなかなか進まない。解説サイト見たりしてるんだけどさ、書かれてる内容は理解できても、それを実際のプログラミングの中でどう活かせば良いのかが分からないんだよね。ということでまた簡単なとこから。 …
vlang 巷で話題になってるvlangを触ってみたよ。 vlang.io 奇麗なページでしっかりしたプログラミング言語なのかと思ったけど、一人だけで作ってるんだね。正直出来はまだまだって感じみたいだ。コンパイラの中身をちょこっと見てみたけど、C言語へのトラン…
今回の目標 double型の計算を実装するよ。 // double型 int main() { double a = 2.7, b = 5.1, c; c = a + b; printf("%f + %f = %f\n", a, b, c); c = a - b; printf("%f - %f = %f\n", a, b, c); c = a * b; printf("%f * %f = %f\n", a, b, c); c = a / …
今回の目標 前回サボった関数呼出を頑張るよ。 // double型 int main() { int a = 15, b = 25; double d = 10.78; double e = 0.13e-3; printf("a = %d d = %f e = %e b = %d\n", a, d, e, b); } int型、double型を混ぜてprintfに渡してる。 関数コール # 関…