From 4dc291b27e857d1f02f55aa064c6c920151332c4 Mon Sep 17 00:00:00 2001 From: Yaossg Date: Sat, 30 Nov 2024 17:47:52 +0800 Subject: [PATCH] new readme --- README.md | 78 ++++++++++++++++++++++++++-------------------- bootstrapping.png | Bin 0 -> 31532 bytes 2 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 bootstrapping.png diff --git a/README.md b/README.md index 86a2024..91db7ee 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RVBTCC -- 约 1800 行的轻量级自举编译器。 +- 约 1900 行的轻量级自举编译器。 - 编译器和自举编译器行为一致。 - 语法类似 C,输出 RISC-V 汇编。 - 依赖几个 libc 函数用于输入输出。 @@ -12,7 +12,6 @@ ### 真机运行 - 编译运行程序,src 为本语言源代码。可以编译 demo 文件夹下的实例。 ```sh @@ -25,19 +24,6 @@ $ sh run-native.sh $ sh boot-native.sh ``` -输出六个文件: - -| 源代码 | 编译器 | 汇编 | 可执行 | 命名 | -| ----------------- | --------- | ------- | --------- | ---------------------- | -| boot.c boot-lib.c | gcc | | gcc.out | 自制编译器 | -| boot.c boot-lib.h | gcc.out | boot1.s | boot1.out | 自举自制编译器 | -| boot.c boot-lib.h | boot1.out | boot2.s | boot2.out | 自举自举自制编译器 | -| boot.c boot-lib.h | boot2.out | boot3.s | | 验证自举自举自制编译器 | - -后三次编译时,boot-lib.h 的内容被手动导入 boot.c 开头进行编译,boot-lib.c 提供的库通过链接引入。 - -自举的目标为 boot1.s == boot2.s == boot3.s - ### 模拟运行 安装以下依赖 @@ -58,27 +44,31 @@ $ sh run.sh $ sh boot.sh ``` +### 自举过程 + + +自举会输出六个文件,三个汇编文件和三个可执行文件: + +| 源代码 | 编译器 | 汇编 | 可执行 | 代号 | 命名 | +| ----------------- | --------- | ------- | --------- | ---- | ---------------------- | +| boot.c boot-lib.c | gcc | | gcc.out | G | 自制编译器 | +| boot.c boot-lib.h | gcc.out | boot1.s | boot1.out | B1 | 自举自制编译器 | +| boot.c boot-lib.h | boot1.out | boot2.s | boot2.out | B2 | 自举自举自制编译器 | +| boot.c boot-lib.h | boot2.out | boot3.s | | B3 | 验证自举自举自制编译器 | + +后三次编译时,boot-lib.h 的内容被手动导入 boot.c 开头进行编译,boot-lib.c 提供的库通过链接引入。 + +整个自举及其验证的过程如下图所示: + +![](bootstrapping.png) + +自举的目标为 G、B1、B2 的可执行文件行为一致,也就是说 B1、B2、B3 的汇编代码一致。 + ## 语言文档 -### 关键字 +### 注释 -本语言包含的关键字即为支持的标量类型的关键字和流程控制的关键字,还有 `const`。 - -### `const` 关键字 - -`const` 关键字可以在类型中使用,在大部分情况下会被直接忽略。支持它是为了更好兼容 C 程序。 - -但是当在出现 - -- 全局,标量(即不是数组) -- 类型为 `const int` 或 `const int const` -- 带有初始化 - -的声明时,将会被解析为整数常量。 - -整数常量在使用的时候会被直接替换为对应的右值,失去作为全局变量左值的性质。 - -使用 `int const` 或 `int` 可以避免这样的特殊处理。 +支持多行 `/* ... */` 和单行 `//` 两种注释 ### 支持六个基本类型 @@ -103,6 +93,25 @@ $ sh boot.sh - `break` `continue` - `return` +### 关键字 + +本语言包含的关键字即为支持的标量类型的关键字和流程控制的关键字,还有 `const`。 + +#### `const` 关键字 + +`const` 关键字可以在类型中使用,在大部分情况下会被直接忽略。支持它是为了更好兼容 C 程序。 + +但是当在出现 + +- 全局,标量(即不是数组) +- 类型为 `const int` 或 `const int const` +- 带有初始化 + +的声明时,将会被解析为整数常量。 + +整数常量在使用的时候会被直接替换为对应的右值,失去作为全局变量左值的性质。 + +使用 `int const` 或 `int` 可以避免这样的特殊处理。 ### 支持以下运算符 @@ -121,7 +130,8 @@ $ sh boot.sh | | | 按位或 | 从左到右 | | `&&` | 逻辑与 | 从左到右 | | || | 逻辑或 | 从左到右 | -| `=` | 赋值 | 从右到左 | +| `?:` | 条件 | 从右到左 | +| `=` `+=` `-=` `*=` `/=` `%=` `<<=` `>>=` `&=` `^=` |= | 赋值 | 从右到左 | | `,` | 逗号 | 从左到右 | - 同级表达式的求值顺序与结合性一致。 diff --git a/bootstrapping.png b/bootstrapping.png new file mode 100644 index 0000000000000000000000000000000000000000..221b03affe2ec7555f155b06d52e5e207d2c68f2 GIT binary patch literal 31532 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 literal 0 HcmV?d00001