# ShellToAssembly v1.1 - 实现说明

## 架构概览

ShellToAssembly 是一个将 Shell 脚本子集编译为 AArch64 (ARM64) 静态 ELF 二进制的交叉编译器。编译器本身运行在 x86_64 Linux 上，生成的二进制可在 ARM64 硬件或 qemu-aarch64 上运行。

### 编译流水线

```
Shell 源码 → AST 解析 → 优化器(O1/O2) → ARM64 代码生成 → ELF 写入
```

## 模块设计

### 1. AST (ast.c / ast.h)
- **Tokenizer**: 词法分析，处理引号、转义、变量 `$var`、算术 `$((...))`
- **递归下降解析器**: 语句链表结构，支持 ASSIGN/ECHO/IF/FOR/WHILE/EXEC/EXIT
- **表达式树**: INT/VAR/BINOP，支持运算符优先级和括号
- **条件测试**: FILE(-f/-d/-e) / NUM(-eq/-ne 等) / STR(= / !=)
- **转义修复**: `\"` 正确将 `"` 放入字符串

### 2. 优化器 (optimizer.c / optimizer.h)
- **O1 优化**:
  - 常量折叠: 编译期计算 `1+2*3` → 7
  - 常量传播: 已知变量值替换使用处
  - 死代码消除: 不可达分支移除
  - 变量名消除: 编译期变量名不进入输出二进制
- **O2 优化**:
  - O1 全部优化
  - 循环展开: body 全为 echo 的 for 循环（≤8 次迭代）完全展开，消除循环跳转

### 3. ARM64 代码生成 (codegen_arm64.c / codegen.h)
- **指令发射**: 直接编码 ARM64 机器码（movz/movk/str/ldr/add/sub/cmp/b/bl/svc 等）
- **标签系统**: 前向引用支持，两遍扫描解决 ADR 偏移和分支回填
- **变量管理**: 256 槽变量表，运行时存放在 .data 段（x19 作基址）
- **子程序库**:
  - `itoa`: 整数转字符串
  - `strlen`: 字符串长度
  - `strcmp`: 字符串比较
  - `filetest`: newfstatat 文件测试
  - `exec`: execve + PATH 查找
- **系统调用**: write(64), exit(93), faccessat(48), newfstatat(79), execve(221)

### 4. ELF 生成 (elf.c / elf.h)
- 双 PT_LOAD 段布局:
  - 段 1: text + rodata，vaddr 0x401000，权限 R+X
  - 段 2: data，vaddr 0x410000，权限 R+W，大小 2048 字节
- 静态链接，无外部依赖

### 5. 主流程 (core.c / main.c)
- CLI: `-i input -o output -O1/-O2`
- TUI: 交互式界面，含优化等级选择 [1/2]

## 关键设计决策

1. **变量运行时存储**: 变量值存放在 .data 段而非栈上，确保跨语句持久化，x19 寄存器固定为 data 段基址。
2. **两遍代码生成**: 第一遍计算 text 总大小，第二遍用精确偏移生成 ADR 和分支指令。
3. **寄存器约定**: x19=data基址, x20=for循环计数器, x21=表达式临时保存, x29/x30=帧指针/返回地址。
4. **零 libc 依赖**: 生成的二进制不链接任何 C 库，全部通过 syscall 直接与内核交互。

## 扩展点

- **管道 (|)**: 在 AST 中添加 PIPE 节点，codegen 中用 pipe(22)+fork(107)+dup2(24) 实现
- **重定向 (>, >>, <)**: EXEC 节点添加重定向字段，codegen 中用 openat(56)+dup2 实现
- **函数**: AST 添加 FUNCTION 节点，支持定义和调用，codegen 中用 bl+ret 实现
- **多架构**: codegen 抽象为接口，新增 x86_64/RISC-V 后端
- **更多优化**: O2 可扩展指令重排、跳转表、公共子表达式消除
- **数组/关联数组**: 扩展变量系统，data 段动态分配

## 构建与测试

```bash
make                  # 编译编译器 (gcc -Wall -Wextra -O2, 零警告)
./run_all_tests.sh    # 运行全部 21 个测试 (O1+O2) + 反汇编验证
```

## 测试覆盖

21 个测试用例覆盖：变量赋值/引用、算术运算(+ - * / %、优先级、括号、负数)、条件测试(文件/数值/字符串)、if/elif/else、for/while 循环、外部命令 execve、转义字符、综合场景。O1 和 O2 均全部通过。
