# 抽象语法树文件编码文档

为了节约篇幅，我将用``AST文件``来作为抽象语法树文件的简称。

### 前言

AST文件里存储着一系列AST节点，一些应用程序可以将自己的语言解析成Stamon的AST文件格式，保存在文件，剩下编译流程交给Stamon的编译器即可。

### 格式

一个AST文件的编码由以下规则组成：

* 每个AST文件的开头必须要有两字节的二进制码：0xABDD，此魔数用于区分于其他文件
* AST文件中的数值存储采用大端存储（以Python的大端存储为标准）
* AST标识是用于区分词法单元的数字标记，以``src/ast/Ast.hpp``当中的``_AstType``枚举为准。特别的，当AST标识为-1时，代表结尾单元
* 每个AST单元由一字节的**AST标识**和若干字节的**AST数据**组成
* **一些AST单元只有AST标识，不含有AST数据**（即一些AST单元只占一字节）
* 一个AST节点及其子节点所组成的的标准结构是**父节点单元，第一个子节点单元，第二个子节点单元，......，最后一个子节点单元，结尾单元**。其中每个子节点还能再拥有子节点，因此这种结构是递归嵌套性的。
* 任何AST单元都要拥有其对应的结尾单元，哪怕这个单元没有任何子节点单元。
* 如果指定需要写入调试信息，则还需要遵循以下规则
* * 在写入第一个单元之前，先写入该单元所在的文件和行号
* * 若一个单元所在的文件与上一个单元不一样，则需要写入当前单元所在文件
* * 若一个单元所在的行号与上一个单元不一样，则需要写入当前单元所在行号
* * 写入当前单元所在行号，需要先写入一字节的数值-2，然后输出四字节的行号
* * 写入当前单元所在文件，需要先写入一字节的数值-3，接着写入四字节的长度（文件名字节长度），最后逐字节地写入文件名

我们来特别看看拥有AST数据的AST单元（以及AST数据的构成）：

* AstIdentifierName：标识符节点，AST数据由**四字节的标识符长度**和**字节长度为标识符长度的标识符内容**组成。
* AstNumber：数值节点，AST数据由**一字节的数值类型**和**若干字节的数值**组成。AstNumber根据数值类型（以``src/ast/LeafAst.cpp``的_NumberType为准）又分为以下几种节点：
* * AstIntNumber：整数节点，数值由**四字节的数值**组成。
* * AstFloatNumber：整数节点，数值由**四字节的float浮点数值**组成。
* * AstDoubleNumber：整数节点，数值由**八字节的float浮点数值**组成。
* AstString：字符串节点，其AST数据由**四字节的字符长度**和**字节长度为字符串长度的字符串内容**组成。
* AstAnonClass：匿名类节点，AST数据由**一字节的布尔值（即father_flag）组成**
* AstExpression：表达式节点，AST数据由**四字节的数值（即ass_type）组成**
* AstBinary：双目运算节点，AST数据由**四字节的数值（即operator_type）组成**
* AstUnary：单目运算节点，AST数据由**四字节的数值（即operator_type）组成**
* AstPostfix：右值后缀节点，AST数据由**四字节的数值（即postfix_type）组成**