From 9d5ec5e3bc01c6174dea048e118edee579c36565 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 7 Feb 2026 23:06:23 +0900 Subject: fix(style): fix codeblock style for rouge --- .../make-tiny-self-hosted-c-compiler/index.html | 80 ++++++++++------------ 1 file changed, 38 insertions(+), 42 deletions(-) (limited to 'services/nuldoc/public/blog/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html') diff --git a/services/nuldoc/public/blog/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html b/services/nuldoc/public/blog/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html index 4d828f45..79e31d17 100644 --- a/services/nuldoc/public/blog/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html +++ b/services/nuldoc/public/blog/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html @@ -15,7 +15,7 @@ セルフホスト可能な C コンパイラを作った|REPL: Rest-Eat-Program Loop - +
@@ -359,10 +359,9 @@ compilerbook では整数一つのパース・コード生成から始めるが、今回は以下のようなソースをパースしてコード生成するところからスタートすることにした。

-
int main() {
-    return 42;
-}
-
+
int main() { +
return 42; +
}

この時点で、struct Tokenstruct Parserstruct AstNodestruct CodeGen といった主要なデータ構造が定義され、この後もほぼ同じソース設計のまま進めている。 @@ -409,24 +408,23 @@ 一日の終わりには、次のようなプログラムのテストが通るようになった。

-
int printf();
-
-int main() {
-    int i;
-    for (i = 1; i <= 100; i = i + 1) {
-        if (i % 15 == 0) {
-            printf("FizzBuzz\n");
-        } else if (i % 3 == 0) {
-            printf("Fizz\n");
-        } else if (i % 5 == 0) {
-            printf("Buzz\n");
-        } else {
-            printf("%d\n", i);
-        }
-    }
-    return 0;
-}
-
+
int printf(); +
+
int main() { +
int i; +
for (i = 1; i <= 100; i = i + 1) { +
if (i % 15 == 0) { +
printf("FizzBuzz\n"); +
} else if (i % 3 == 0) { +
printf("Fizz\n"); +
} else if (i % 5 == 0) { +
printf("Buzz\n"); +
} else { +
printf("%d\n", i); +
} +
} +
return 0; +
}
@@ -515,14 +513,13 @@ 記念すべき (?) 最後のバグはこちら。

-
         gen_expr(g, ast->expr1, GEN_RVAL);
-     } else {
-         gen_expr(g, ast->expr1, GEN_RVAL);
--        gen_lval2rval(ast->expr1->ty);
-+        gen_lval2rval(ast->expr1->ty->to);
-     }
- }
-
+
gen_expr(g, ast->expr1, GEN_RVAL); +
} else { +
gen_expr(g, ast->expr1, GEN_RVAL); +
- gen_lval2rval(ast->expr1->ty); +
+ gen_lval2rval(ast->expr1->ty->to); +
} +
}

メモリアドレスから参照先の値を得る際、その型によってロードする命令の種類を変える必要があるのだが、その切替をポインタ型でおこなっていた。正しくは、そのポインタ型が指す型を元にして切り替えなければならない。 @@ -537,17 +534,16 @@ 一体どこが異なるのか。hexdump の差分がこちら。

-
$ diff -u <(hexdump -C p4dcc2) <(hexdump -C p4dcc3)
-@@ -5090,7 +5090,7 @@
- 00015db0  72 72 61 79 5f 65 6e 74  72 79 00 66 72 61 6d 65  |rray_entry.frame|
- 00015dc0  5f 64 75 6d 6d 79 00 5f  5f 66 72 61 6d 65 5f 64  |_dummy.__frame_d|
- 00015dd0  75 6d 6d 79 5f 69 6e 69  74 5f 61 72 72 61 79 5f  |ummy_init_array_|
--00015de0  65 6e 74 72 79 00 63 63  6d 69 42 49 59 6b 2e 6f  |entry.ccmiBIYk.o|
-+00015de0  65 6e 74 72 79 00 63 63  53 71 64 47 76 57 2e 6f  |entry.ccSqdGvW.o|
- 00015df0  00 66 61 74 61 6c 5f 65  72 72 6f 72 00 72 65 61  |.fatal_error.rea|
- 00015e00  64 5f 61 6c 6c 00 74 6f  6b 65 6e 69 7a 65 00 74  |d_all.tokenize.t|
- 00015e10  79 70 65 5f 6e 65 77 00  74 79 70 65 5f 6e 65 77  |ype_new.type_new|
-
+
$ diff -u <(hexdump -C p4dcc2) <(hexdump -C p4dcc3) +
@@ -5090,7 +5090,7 @@ +
00015db0 72 72 61 79 5f 65 6e 74 72 79 00 66 72 61 6d 65 |rray_entry.frame| +
00015dc0 5f 64 75 6d 6d 79 00 5f 5f 66 72 61 6d 65 5f 64 |_dummy.__frame_d| +
00015dd0 75 6d 6d 79 5f 69 6e 69 74 5f 61 72 72 61 79 5f |ummy_init_array_| +
-00015de0 65 6e 74 72 79 00 63 63 6d 69 42 49 59 6b 2e 6f |entry.ccmiBIYk.o| +
+00015de0 65 6e 74 72 79 00 63 63 53 71 64 47 76 57 2e 6f |entry.ccSqdGvW.o| +
00015df0 00 66 61 74 61 6c 5f 65 72 72 6f 72 00 72 65 61 |.fatal_error.rea| +
00015e00 64 5f 61 6c 6c 00 74 6f 6b 65 6e 69 7a 65 00 74 |d_all.tokenize.t| +
00015e10 79 70 65 5f 6e 65 77 00 74 79 70 65 5f 6e 65 77 |ype_new.type_new|

fatal_errorread_alltokenize type_new はいずれも main.c で定義された関数の名前である。このことから考えると、これは GCC が埋め込んだシンボルテーブルである可能性が高い。わずかに異なっている 6バイトは、ランダム生成された何かのように見える。 -- cgit v1.3-1-g0d28