2019-06-01から1ヶ月間の記事一覧

コンパイラ作成(86) double型の単項マイナス演算子

今回の目標 今回は単項マイナス演算子だよ。 // 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 = …

コンパイラ作成(85) double型の比較演算子

今回の目標 前回の残りの比較演算をサポートするよ。 // 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"); } コード生成部 …

コンパイラ作成(84) double型の等価演算子

今回の目標 等価演算子をサポートするよ。 // 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"); } コード生成部 まずはここ…

コンパイラ作成(83) double型を返す関数の呼出

今回の目標 sqrtをコールしてみるよ。 // double型 extern double sqrt(double x); int main() { printf("%f\n", 2.0 * sqrt(2.0)); } 前回、関数コールに不安があったんだけど、やってみたらやっぱり駄目だったよ。見直してみたら未修正のところがあった。 …

コンパイラ作成(82) double型の複雑な四則演算

今回の目標 前回に続き四則演算。 // double型 int main() { printf("%f\n", 2.0 + 5.0 / 2.0); } 前回対応できなかった複雑な式。 コード生成部 codegen_elsの括弧の処理部と関数呼出の処理部を修正。 def codegen_els(op, operand, type_l) ostr = mnemoni…

Haskellのお勉強(4) 素数

素数の表示 Haskellだけど細々と勉強続けてるよ。でもなかなか進まない。解説サイト見たりしてるんだけどさ、書かれてる内容は理解できても、それを実際のプログラミングの中でどう活かせば良いのかが分からないんだよね。ということでまた簡単なとこから。 …

vlangを試してみた

vlang 巷で話題になってるvlangを触ってみたよ。 vlang.io 奇麗なページでしっかりしたプログラミング言語なのかと思ったけど、一人だけで作ってるんだね。正直出来はまだまだって感じみたいだ。コンパイラの中身をちょこっと見てみたけど、C言語へのトラン…

コンパイラ作成(81) double型の単純な四則演算

今回の目標 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 / …

コンパイラ作成(80) double型引数の関数呼出

今回の目標 前回サボった関数呼出を頑張るよ。 // 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に渡してる。 関数コール # 関…

コンパイラ作成(79) double型の代入・参照

今回の目標 前回、Lexerの修正したんで、今回はdouble型の代入と参照まで実装するよ。 // double型 int main() { double d = 10.78; double e = 0.13e-3; printf("d = %f\n", d); printf("e = %f\n", e); } double型追加 まずはここ。 @typeword = [ "extern…

コンパイラ作成(78) double型

今回の目標 IEEE754内部形式への変換は中途半端になってるけど、とりあえず先に進むことにしたよ。当面サポートするのはRubyで変換できるdouble型だけにするよ。 // double型 int main() { double d = 10.78; double e = 0.13e-3; printf("d = %f\n", d); pr…

コンパイラ作成(77) 続浮動小数点数

IEEE754内部形式への変換 前回の続きで頑張ってみるよ。 #! /bin/sh exec ruby -S -x "$0" "$@" #! ruby # # ieee754 # def ieee754_binary(n,format=:double) a = n.split('.') integer = a[0] if a.size < 2 then decimal = "" else decimal = a[1] end b_…

コンパイラ作成(76) 浮動小数点数

今回はお勉強 char型のサポートが粗方終わったんで、次に何やるかって考えたよ。最初はshort型にしようかと思ったんだけど、やることはchar型と大体同じで詰まらないから、double型に手を出してみるよ。今まで浮動小数点数を使ったプログラミングはあんまり…

コンパイラ作成(75) char型の比較演算、単項マイナス演算

今回の目標 今回もchar型のサポートだよ。 // char型 int main() { char a = 11, b = 4; if( a == b ) printf("%hhu == %hhu\n", a, b); else printf("%hhu != %hhu\n", a, b); } // char型 int main() { char a = 11, b = -a; printf("a = %hhu b = %hhu\n"…

コンパイラ作成(74) char型の乗除余算

今回の目標 引き続きchar型のサポート。 // char型 int main() { char a = 11, b = 4, c; c = a * b; printf("%hhu * %hhu = %hhu\n", a, b, c); c = a / b; printf("%hhu / %hhu = %hhu\n", a, b, c); c = a % b; printf("%hhu %% %hhu = %hhu\n", a, b, c)…

コンパイラ作成(73) char型の加減算

今回の目標 char型のサポートを進めるよ。 // char型 int main() { char a = 10, b = 8, c; c = a + b; printf("%hhu + %hhu = %hhu\n", a, b, c); c = a - b; printf("%hhu - %hhu = %hhu\n", a, b, c); } 今回は加減算。 codegen_els # 式のコード生成(二…

コンパイラ作成(72) char型

今回の目標 char型のサポートを頑張るよ。 // char型 int main() { char ch = 'A'; // char ch = '\n'; printf("ch = %c\n",ch); } 今回は文字リテラルとchar型への代入と参照までだよ。一気にやるのはしんどいからちょっとずつ。 Lexerクラス まずは文字リ…

コンパイラ作成(71) ポインタのポインタ型

今回の目標 ポインタのポインタ型に対応するよ。 // 間接参照演算子 int main() { int a = 55; int *p = &a; int **pp = &p; printf("a = %d **pp = %d\n",a,**pp); **pp = 123; printf("a = %d **pp = %d\n",a,**pp); } 変数宣言と連続した単項演算子の扱い…

コンパイラ作成(70) ポインタ型とint型の演算

今回の目標 引き続きポインタ型のサポートを頑張るよ。 // int*型+int型 extern void *malloc(size_t size); extern void free(void *ptr); extern int puts(char *s); int main() { int *p = malloc(10*4); for(int i = 0; i < 10; i = i + 1) printf("p + …

コンパイラ作成(69) 間接参照演算子

今回の目標 前回の続きで間接参照演算子を追加するよ。 // 間接参照演算子 int main() { int a = 55; int *p = &a; printf("a = %d *p = %d\n",a,*p); *p = 123; printf("a = %d *p = %d\n",a,*p); } 右辺値の場合と左辺値の場合があるよ。 read_modify_el …

コンパイラ作成(68) int*型、アドレス演算子

今回の目標 アドレス演算子を追加するよ。 // アドレス演算子 int main() { int a = 55; int *p = &a; printf("p = %016lx\n",p); } それとint*型の対応も頑張るよ。char*型の時よりもうちょっと汎用的になるようにしたいなあ。 Lexerクラス まずは演算子の…

コンパイラ作成(67) for文での変数宣言

今回の目標 前回の続きでfor文の頭での変数宣言だよ。 // for文での変数宣言 extern int puts(char *str); int main() { int a = 10, b = 20; printf("1: a = %d b = %d\n",a,b); for(int i = 0; i < 3; i = i +1) { int a = 55; printf("2: a = %d b = %d\n…

コンパイラ作成(66) ブロック内での変数宣言

今回の目標 ブロック{...}を追加して、その中での変数宣言にも対応するよ。 // block中の変数宣言 extern int puts(char *str); int main() { int a = 10, b = 20; printf("1: a = %d b = %d\n",a,b); { int a = 55; printf("2: a = %d b = %d\n",a,b); } in…

コンパイラ作成(65) 剰余演算子

今回の目標 久々に演算子を追加するよ。 // 剰余 int main() { printf("17 * 4 = %d\n",17*4); printf("17 / 4 = %d\n",17/4); printf("17 % 4 = %d\n",17%4); } 剰余演算子だよ。 gettoken 修正いくよ。 # symbolの切り出し elsif m = @line[@idx,@line.len…

コンパイラ作成(64) printf

今回の目標 前回の続き。 // void*, size_t extern void *malloc(size_t size); int main() { char *buffer = malloc(256); printf("buffer = %016lx\n",buffer); } 何回も出てきたprintfだけど、このテストプログラムは上手くコンパイルできないよ。printf…

コンパイラ作成(63) void*型・size_t型

今回の目標 いきなりmalloc。いきなりvoid*。いきなりsize_t。 // void*, size_t extern void *malloc(size_t size); int main() { char *buffer = malloc(256); } mallocなら簡単に呼べるかと思ったんだけど、現実は厳しいよ。void*型はchar*型に置き換えち…

コンパイラ作成(62) 引数のチェック

今回の目標 関数コール時の引数の型・個数をチェックするよ。 // 誤った関数コール extern int add(int a, int b); int main() { int a = 5, b = 12, c; c = add(a,"must be int"); printf("%d + %d = %d\n",a,b,c); } // 誤った関数コール extern int add(i…

コンパイラ作成(61) 引数のある関数の修正

バグ テストをしてたらバグを見つけたよ。 main() { print(2 * 3 + 5); print(2 + 3 * 5); } これなんだけど、計算結果が合わない。 ~/myc$ myc -d i7.myc print.o [[print, (), [2, *, 3, +, 5]]] [[print, (), [2, *, 3, +, 5]]] [[print, (), [2, +, 3, *…

コンパイラ作成(60) 関数のextern宣言

今回の目標 いきなりだけどextern行ってみるよ。 // 関数のextern宣言 extern int add(int a, int b); int main() { int a = 5, b = 12, c; c = add(a,b); printf("%d + %d = %d\n",a,b,c); } 本来はextern宣言の場合、仮引数の名前は省略できるんだけど、面…

コンパイラ作成(59) char*型変数の代入・参照を修正

今回の目標 引き続きchar*型。 // char*型の変数 int main() { char *p = "Hello, World!"; puts(p); } これ前々回のテストプログラム。コンパイルできてちゃんと動いたんだけどさ、アセンブリコード見てて変なことに気が付いたよ。 .intel_syntax noprefix …