rvcc/parse.c

3986 lines
107 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "rvcc.h"
// 局部变量全局变量typedefenum常量的域
typedef struct {
Obj *Var; // 对应的变量
Type *Typedef; // 别名
Type *EnumTy; // 枚举的类型
int EnumVal; // 枚举的值
} VarScope;
// 表示一个块域
typedef struct Scope Scope;
struct Scope {
Scope *Next; // 指向上一级的域
// C有两个域变量或类型别名结构体或联合体枚举标签域
HashMap Vars; // 指向当前域内的变量
HashMap Tags; // 指向当前域内的结构体标签
};
// 变量属性
typedef struct {
bool IsTypedef; // 是否为类型别名
bool IsStatic; // 是否为文件域内
bool IsExtern; // 是否为外部变量
bool IsInline; // 是否为内联
bool IsTLS; // 是否为线程局部存储Thread Local Storage
int Align; // 对齐量
} VarAttr;
// 可变的初始化器。此处为树状结构。
// 因为初始化器可以是嵌套的,
// 类似于 int x[2][2] = {{1, 2}, {3, 4}}
typedef struct Initializer Initializer;
struct Initializer {
Initializer *Next; // 下一个
Type *Ty; // 原始类型
Token *Tok; // 终结符
bool IsFlexible; // 可调整的,表示需要重新构造
// 如果不是聚合类型并且有一个初始化器Expr 有对应的初始化表达式。
Node *Expr;
// 如果是聚合类型如数组或结构体Children有子节点的初始化器
Initializer **Children;
// 联合体中只有一个成员能被初始化,此处用来标记是哪个成员被初始化
Member *Mem;
};
// 指派初始化,用于局部变量的初始化器
typedef struct InitDesig InitDesig;
struct InitDesig {
InitDesig *Next; // 下一个
int Idx; // 数组中的索引
Member *Mem; // 成员变量
Obj *Var; // 对应的变量
};
// 在解析时,全部的变量实例都被累加到这个列表里。
Obj *Locals; // 局部变量
Obj *Globals; // 全局变量
// 所有的域的链表
static Scope *Scp = &(Scope){};
// 指向当前正在解析的函数
static Obj *CurrentFn;
// 当前函数内的goto和标签列表
static Node *Gotos;
static Node *Labels;
// 当前goto跳转的目标
static char *BrkLabel;
// 当前continue跳转的目标
static char *ContLabel;
// 如果我们正在解析switch语句则指向表示switch的节点。
// 否则为空。
static Node *CurrentSwitch;
// 内建的Alloca函数
static Obj *BuiltinAlloca;
// program = (typedef | functionDefinition | globalVariable)*
// functionDefinition = declspec declarator "{" compoundStmt*
// declspec = ("void" | "_Bool" | char" | "short" | "int" | "long"
// | "typedef" | "static" | "extern" | "inline"
// | "_Thread_local" | "__thread"
// | "_Alignas" ("(" typeName | constExpr ")")
// | "signed" | "unsigned"
// | structDecl | unionDecl | typedefName
// | enumSpecifier | typeofSpecifier
// | "const" | "volatile" | "auto" | "register" | "restrict"
// | "__restrict" | "__restrict__" | "_Noreturn")+
// enumSpecifier = ident? "{" enumList? "}"
// | ident ("{" enumList? "}")?
// enumList = ident ("=" constExpr)? ("," ident ("=" constExpr)?)* ","?
// declarator = pointers ("(" ident ")" | "(" declarator ")" | ident) typeSuffix
// pointers = ("*" ("const" | "volatile" | "restrict")*)*
// typeSuffix = "(" funcParams | "[" arrayDimensions | ε
// arrayDimensions = ("static" | "restrict")* constExpr? "]" typeSuffix
// funcParams = ("void" | param ("," param)* ("," "...")?)? ")"
// param = declspec declarator
// compoundStmt = (typedef | declaration | stmt)* "}"
// declaration = declspec (declarator ("=" initializer)?
// ("," declarator ("=" initializer)?)*)? ";"
// initializer = stringInitializer | arrayInitializer | structInitializer
// | unionInitializer |assign
// stringInitializer = stringLiteral
// arrayInitializer = arrayInitializer1 | arrayInitializer2
// arrayInitializer1 = "{" initializer ("," initializer)* ","? "}"
// arrayIntializer2 = initializer ("," initializer)* ","?
// structInitializer = structInitializer1 | structInitializer2
// structInitializer1 = "{" initializer ("," initializer)* ","? "}"
// structIntializer2 = initializer ("," initializer)* ","?
// unionInitializer = "{" initializer "}"
// stmt = "return" expr? ";"
// | "if" "(" expr ")" stmt ("else" stmt)?
// | "switch" "(" expr ")" stmt
// | "case" constExpr ("..." constExpr)? ":" stmt
// | "default" ":" stmt
// | "for" "(" exprStmt expr? ";" expr? ")" stmt
// | "while" "(" expr ")" stmt
// | "do" stmt "while" "(" expr ")" ";"
// | asmStmt
// | "goto" (ident | "*" expr) ";"
// | "break" ";"
// | "continue" ";"
// | ident ":" stmt
// | "{" compoundStmt
// | exprStmt
// asmStmt = "asm" ("volatile" | "inline")* "(" stringLiteral ")"
// exprStmt = expr? ";"
// expr = assign ("," expr)?
// assign = conditional (assignOp assign)?
// conditional = logOr ("?" expr? ":" conditional)?
// logOr = logAnd ("||" logAnd)*
// logAnd = bitOr ("&&" bitOr)*
// bitOr = bitXor ("|" bitXor)*
// bitXor = bitAnd ("^" bitAnd)*
// bitAnd = equality ("&" equality)*
// assignOp = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^="
// | "<<=" | ">>="
// equality = relational ("==" relational | "!=" relational)*
// relational = shift ("<" shift | "<=" shift | ">" shift | ">=" shift)*
// shift = add ("<<" add | ">>" add)*
// add = mul ("+" mul | "-" mul)*
// mul = cast ("*" cast | "/" cast | "%" cast)*
// cast = "(" typeName ")" cast | unary
// unary = ("+" | "-" | "*" | "&" | "!" | "~") cast
// | ("++" | "--") unary
// | "&&" ident
// | postfix
// structMembers = (declspec declarator ("," declarator)* ";")*
// structDecl = structUnionDecl
// unionDecl = structUnionDecl
// structUnionDecl = attribute? ident? ("{" structMembers)?
// attribute = ("__attribute__" "(" "(" ("packed")
// | ("aligned" "(" N ")") ")" ")")*
// postfix = "(" typeName ")" "{" initializerList "}"
// = ident "(" funcArgs ")" postfixTail*
// | primary postfixTail*
//
// postfixTail = "[" expr "]"
// | "(" funcArgs ")"
// | "." ident
// | "->" ident
// | "++"
// | "--"
// primary = "(" "{" stmt+ "}" ")"
// | "(" expr ")"
// | "sizeof" "(" typeName ")"
// | "sizeof" unary
// | "_Alignof" "(" typeName ")"
// | "_Alignof" unary
// | "_Generic" genericSelection
// | "__builtin_types_compatible_p" "(" typeName, typeName, ")"
// | ident
// | str
// | num
// genericSelection = "(" assign "," genericAssoc ("," genericAssoc)* ")"
// genericAssoc = typeName ":" assign
// | "default" ":" assign
// typeName = declspec abstractDeclarator
// abstractDeclarator = pointers ("(" abstractDeclarator ")")? typeSuffix
// funcall = (assign ("," assign)*)? ")"
static bool isTypename(Token *Tok);
static Type *declspec(Token **Rest, Token *Tok, VarAttr *Attr);
static Type *typename(Token **Rest, Token *Tok);
static Type *enumSpecifier(Token **Rest, Token *Tok);
static Type *typeofSpecifier(Token **Rest, Token *Tok);
static Type *typeSuffix(Token **Rest, Token *Tok, Type *Ty);
static Type *declarator(Token **Rest, Token *Tok, Type *Ty);
static Node *declaration(Token **Rest, Token *Tok, Type *BaseTy, VarAttr *Attr);
static void arrayInitializer2(Token **Rest, Token *Tok, Initializer *Init,
int I);
static void structInitializer2(Token **Rest, Token *Tok, Initializer *Init,
Member *Mem);
static void initializer2(Token **Rest, Token *Tok, Initializer *Init);
static Initializer *initializer(Token **Rest, Token *Tok, Type *Ty,
Type **NewTy);
static Node *LVarInitializer(Token **Rest, Token *Tok, Obj *Var);
static void GVarInitializer(Token **Rest, Token *Tok, Obj *Var);
static Node *compoundStmt(Token **Rest, Token *Tok);
static Node *stmt(Token **Rest, Token *Tok);
static Node *exprStmt(Token **Rest, Token *Tok);
static Node *expr(Token **Rest, Token *Tok);
static int64_t eval(Node *Nd);
static int64_t eval2(Node *Nd, char ***Label);
static int64_t evalRVal(Node *Nd, char ***Label);
static double evalDouble(Node *Nd);
static bool isConstExpr(Node *Nd);
static Node *assign(Token **Rest, Token *Tok);
static Node *conditional(Token **Rest, Token *Tok);
static Node *logOr(Token **Rest, Token *Tok);
static Node *logAnd(Token **Rest, Token *Tok);
static Node *bitOr(Token **Rest, Token *Tok);
static Node *bitXor(Token **Rest, Token *Tok);
static Node *bitAnd(Token **Rest, Token *Tok);
static Node *equality(Token **Rest, Token *Tok);
static Node *relational(Token **Rest, Token *Tok);
static Node *shift(Token **Rest, Token *Tok);
static Node *add(Token **Rest, Token *Tok);
static Node *newAdd(Node *LHS, Node *RHS, Token *Tok);
static Node *newSub(Node *LHS, Node *RHS, Token *Tok);
static Node *mul(Token **Rest, Token *Tok);
static Node *cast(Token **Rest, Token *Tok);
static Member *getStructMember(Type *Ty, Token *Tok);
static Type *structDecl(Token **Rest, Token *Tok);
static Type *unionDecl(Token **Rest, Token *Tok);
static Node *unary(Token **Rest, Token *Tok);
static Node *postfix(Token **Rest, Token *Tok);
static Node *funCall(Token **Rest, Token *Tok, Node *Nd);
static Node *primary(Token **Rest, Token *Tok);
static Token *parseTypedef(Token *Tok, Type *BaseTy);
static bool isFunction(Token *Tok);
static Token *function(Token *Tok, Type *BaseTy, VarAttr *Attr);
static Token *globalVariable(Token *Tok, Type *Basety, VarAttr *Attr);
// 向下对齐值
// N % Align != 0 , 即 N 未对齐时, AlignDown(N) = AlignTo(N) - Align
// N % Align == 0 , 即 N 已对齐时, AlignDown(N) = AlignTo(N)
static int alignDown(int N, int Align) { return alignTo(N - Align + 1, Align); }
// 进入域
static void enterScope(void) {
Scope *S = calloc(1, sizeof(Scope));
// 后来的在链表头部
// 类似于栈的结构,栈顶对应最近的域
S->Next = Scp;
Scp = S;
}
// 结束当前域
static void leaveScope(void) { Scp = Scp->Next; }
// 通过名称,查找一个变量
static VarScope *findVar(Token *Tok) {
// 此处越先匹配的域,越深层
for (Scope *S = Scp; S; S = S->Next) {
// 遍历域内的所有变量
VarScope *S2 = hashmapGet2(&S->Vars, Tok->Loc, Tok->Len);
if (S2)
return S2;
}
return NULL;
}
// 通过Token查找标签
static Type *findTag(Token *Tok) {
for (Scope *S = Scp; S; S = S->Next) {
Type *Ty = hashmapGet2(&S->Tags, Tok->Loc, Tok->Len);
if (Ty)
return Ty;
}
return NULL;
}
// 新建一个节点
static Node *newNode(NodeKind Kind, Token *Tok) {
Node *Nd = calloc(1, sizeof(Node));
Nd->Kind = Kind;
Nd->Tok = Tok;
return Nd;
}
// 新建一个单叉树
static Node *newUnary(NodeKind Kind, Node *Expr, Token *Tok) {
Node *Nd = newNode(Kind, Tok);
Nd->LHS = Expr;
return Nd;
}
// 新建一个二叉树节点
static Node *newBinary(NodeKind Kind, Node *LHS, Node *RHS, Token *Tok) {
Node *Nd = newNode(Kind, Tok);
Nd->LHS = LHS;
Nd->RHS = RHS;
return Nd;
}
// 新建一个数字节点
static Node *newNum(int64_t Val, Token *Tok) {
Node *Nd = newNode(ND_NUM, Tok);
Nd->Val = Val;
return Nd;
}
// 新建一个长整型节点
static Node *newLong(int64_t Val, Token *Tok) {
Node *Nd = newNode(ND_NUM, Tok);
Nd->Val = Val;
Nd->Ty = TyLong;
return Nd;
}
// 新建一个无符号长整型节点
static Node *newULong(long Val, Token *Tok) {
Node *node = newNode(ND_NUM, Tok);
node->Val = Val;
node->Ty = TyULong;
return node;
}
// 新变量
static Node *newVarNode(Obj *Var, Token *Tok) {
Node *Nd = newNode(ND_VAR, Tok);
Nd->Var = Var;
return Nd;
}
// VLA指针
static Node *newVLAPtr(Obj *Var, Token *Tok) {
Node *Nd = newNode(ND_VLA_PTR, Tok);
Nd->Var = Var;
return Nd;
}
// 新转换
Node *newCast(Node *Expr, Type *Ty) {
addType(Expr);
Node *Nd = calloc(1, sizeof(Node));
Nd->Kind = ND_CAST;
Nd->Tok = Expr->Tok;
Nd->LHS = Expr;
Nd->Ty = copyType(Ty);
return Nd;
}
// 将变量存入当前的域中
static VarScope *pushScope(char *Name) {
VarScope *S = calloc(1, sizeof(VarScope));
hashmapPut(&Scp->Vars, Name, S);
return S;
}
// 新建初始化器
static Initializer *newInitializer(Type *Ty, bool IsFlexible) {
Initializer *Init = calloc(1, sizeof(Initializer));
// 存储原始类型
Init->Ty = Ty;
// 处理数组类型
if (Ty->Kind == TY_ARRAY) {
// 判断是否需要调整数组元素数并且数组不完整
if (IsFlexible && Ty->Size < 0) {
// 设置初始化器为可调整的,之后进行完数组元素数的计算后,再构造初始化器
Init->IsFlexible = true;
return Init;
}
// 为数组的最外层的每个元素分配空间
Init->Children = calloc(Ty->ArrayLen, sizeof(Initializer *));
// 遍历解析数组最外层的每个元素
for (int I = 0; I < Ty->ArrayLen; ++I)
Init->Children[I] = newInitializer(Ty->Base, false);
}
// 处理结构体和联合体
if (Ty->Kind == TY_STRUCT || Ty->Kind == TY_UNION) {
// 计算结构体成员的数量
int Len = 0;
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next)
++Len;
// 初始化器的子项
Init->Children = calloc(Len, sizeof(Initializer *));
// 遍历子项进行赋值
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
// 判断结构体是否是灵活的,同时成员也是灵活的并且是最后一个
// 在这里直接构造,避免对于灵活数组的解析
if (IsFlexible && Ty->IsFlexible && !Mem->Next) {
Initializer *Child = calloc(1, sizeof(Initializer));
Child->Ty = Mem->Ty;
Child->IsFlexible = true;
Init->Children[Mem->Idx] = Child;
} else {
// 对非灵活子项进行赋值
Init->Children[Mem->Idx] = newInitializer(Mem->Ty, false);
}
}
return Init;
}
return Init;
}
// 新建变量
static Obj *newVar(char *Name, Type *Ty) {
Obj *Var = calloc(1, sizeof(Obj));
Var->Name = Name;
Var->Ty = Ty;
// 设置变量默认的对齐量为类型的对齐量
Var->Align = Ty->Align;
pushScope(Name)->Var = Var;
return Var;
}
// 在链表中新增一个局部变量
static Obj *newLVar(char *Name, Type *Ty) {
Obj *Var = newVar(Name, Ty);
Var->IsLocal = true;
// 将变量插入头部
Var->Next = Locals;
Locals = Var;
return Var;
}
// 在链表中新增一个全局变量
static Obj *newGVar(char *Name, Type *Ty) {
Obj *Var = newVar(Name, Ty);
Var->Next = Globals;
// static全局变量
Var->IsStatic = true;
// 存在定义
Var->IsDefinition = true;
Globals = Var;
return Var;
}
// 新增唯一名称
static char *newUniqueName(void) {
static int Id = 0;
return format(".L..%d", Id++);
}
// 新增匿名全局变量
static Obj *newAnonGVar(Type *Ty) { return newGVar(newUniqueName(), Ty); }
// 新增字符串字面量
static Obj *newStringLiteral(char *Str, Type *Ty) {
Obj *Var = newAnonGVar(Ty);
Var->InitData = Str;
return Var;
}
// 获取标识符
static char *getIdent(Token *Tok) {
if (Tok->Kind != TK_IDENT)
errorTok(Tok, "expected an identifier");
return strndup(Tok->Loc, Tok->Len);
}
// 查找类型别名
static Type *findTypedef(Token *Tok) {
// 类型别名是个标识符
if (Tok->Kind == TK_IDENT) {
// 查找是否存在于变量域内
VarScope *S = findVar(Tok);
if (S)
return S->Typedef;
}
return NULL;
}
static void pushTagScope(Token *Tok, Type *Ty) {
hashmapPut2(&Scp->Tags, Tok->Loc, Tok->Len, Ty);
}
// declspec = ("void" | "_Bool" | char" | "short" | "int" | "long"
// | "typedef" | "static" | "extern" | "inline"
// | "_Thread_local" | "__thread"
// | "_Alignas" ("(" typeName | constExpr ")")
// | "signed" | "unsigned"
// | structDecl | unionDecl | typedefName
// | enumSpecifier | typeofSpecifier
// | "const" | "volatile" | "auto" | "register" | "restrict"
// | "__restrict" | "__restrict__" | "_Noreturn")+
// declarator specifier
static Type *declspec(Token **Rest, Token *Tok, VarAttr *Attr) {
// 类型的组合被表示为例如LONG+LONG=1<<9
// 可知long int和int long是等价的。
enum {
VOID = 1 << 0,
BOOL = 1 << 2,
CHAR = 1 << 4,
SHORT = 1 << 6,
INT = 1 << 8,
LONG = 1 << 10,
FLOAT = 1 << 12,
DOUBLE = 1 << 14,
OTHER = 1 << 16,
SIGNED = 1 << 17,
UNSIGNED = 1 << 18,
};
Type *Ty = TyInt;
int Counter = 0; // 记录类型相加的数值
bool IsAtomic = false; // 标记是否为原子的
// 遍历所有类型名的Tok
while (isTypename(Tok)) {
// 处理typedef等关键字
if (equal(Tok, "typedef") || equal(Tok, "static") || equal(Tok, "extern") ||
equal(Tok, "inline") || equal(Tok, "_Thread_local") ||
equal(Tok, "__thread")) {
if (!Attr)
errorTok(Tok, "storage class specifier is not allowed in this context");
if (equal(Tok, "typedef"))
Attr->IsTypedef = true;
else if (equal(Tok, "static"))
Attr->IsStatic = true;
else if (equal(Tok, "extern"))
Attr->IsExtern = true;
else if (equal(Tok, "inline"))
Attr->IsInline = true;
else
Attr->IsTLS = true;
// typedef不应与static/extern/inline/__thread/_Thread_local一起使用
if (Attr->IsTypedef &&
(Attr->IsStatic || Attr->IsExtern || Attr->IsInline || Attr->IsTLS))
errorTok(Tok, "typedef and static/extern/inline/__thread/_Thread_local "
"may not be used together");
Tok = Tok->Next;
continue;
}
// 识别这些关键字并忽略
if (consume(&Tok, Tok, "const") || consume(&Tok, Tok, "volatile") ||
consume(&Tok, Tok, "auto") || consume(&Tok, Tok, "register") ||
consume(&Tok, Tok, "restrict") || consume(&Tok, Tok, "__restrict") ||
consume(&Tok, Tok, "__restrict__") || consume(&Tok, Tok, "_Noreturn"))
continue;
// 匹配是否为原子的
if (equal(Tok, "_Atomic")) {
Tok = Tok->Next;
if (equal(Tok, "(")) {
Ty = typename(&Tok, Tok->Next);
Tok = skip(Tok, ")");
}
IsAtomic = true;
continue;
}
// _Alignas "(" typeName | constExpr ")"
if (equal(Tok, "_Alignas")) {
// 不存在变量属性时,无法设置对齐值
if (!Attr)
errorTok(Tok, "_Alignas is not allowed in this context");
Tok = skip(Tok->Next, "(");
// 判断是类型名,或者常量表达式
if (isTypename(Tok))
Attr->Align = typename(&Tok, Tok)->Align;
else
Attr->Align = constExpr(&Tok, Tok);
Tok = skip(Tok, ")");
continue;
}
// 处理用户定义的类型
Type *Ty2 = findTypedef(Tok);
if (equal(Tok, "struct") || equal(Tok, "union") || equal(Tok, "enum") ||
equal(Tok, "typeof") || Ty2) {
if (Counter)
break;
if (equal(Tok, "struct")) {
Ty = structDecl(&Tok, Tok->Next);
} else if (equal(Tok, "union")) {
Ty = unionDecl(&Tok, Tok->Next);
} else if (equal(Tok, "enum")) {
Ty = enumSpecifier(&Tok, Tok->Next);
} else if (equal(Tok, "typeof")) {
Ty = typeofSpecifier(&Tok, Tok->Next);
} else {
// 将类型设为类型别名指向的类型
Ty = Ty2;
Tok = Tok->Next;
}
Counter += OTHER;
continue;
}
// 对于出现的类型名加入Counter
// 每一步的Counter都需要有合法值
if (equal(Tok, "void"))
Counter += VOID;
else if (equal(Tok, "_Bool"))
Counter += BOOL;
else if (equal(Tok, "char"))
Counter += CHAR;
else if (equal(Tok, "short"))
Counter += SHORT;
else if (equal(Tok, "int"))
Counter += INT;
else if (equal(Tok, "long"))
Counter += LONG;
else if (equal(Tok, "float"))
Counter += FLOAT;
else if (equal(Tok, "double"))
Counter += DOUBLE;
else if (equal(Tok, "signed"))
Counter |= SIGNED;
else if (equal(Tok, "unsigned"))
Counter |= UNSIGNED;
else
unreachable();
// 根据Counter值映射到对应的Type
switch (Counter) {
case VOID:
Ty = TyVoid;
break;
case BOOL:
Ty = TyBool;
break;
case SIGNED + CHAR:
Ty = TyChar;
break;
// RISCV当中char是无符号类型的
case CHAR:
case UNSIGNED + CHAR:
Ty = TyUChar;
break;
case SHORT:
case SHORT + INT:
case SIGNED + SHORT:
case SIGNED + SHORT + INT:
Ty = TyShort;
break;
case UNSIGNED + SHORT:
case UNSIGNED + SHORT + INT:
Ty = TyUShort;
break;
case INT:
case SIGNED:
case SIGNED + INT:
Ty = TyInt;
break;
case UNSIGNED:
case UNSIGNED + INT:
Ty = TyUInt;
break;
case LONG:
case LONG + INT:
case LONG + LONG:
case LONG + LONG + INT:
case SIGNED + LONG:
case SIGNED + LONG + INT:
case SIGNED + LONG + LONG:
case SIGNED + LONG + LONG + INT:
Ty = TyLong;
break;
case UNSIGNED + LONG:
case UNSIGNED + LONG + INT:
case UNSIGNED + LONG + LONG:
case UNSIGNED + LONG + LONG + INT:
Ty = TyULong;
break;
case FLOAT:
Ty = TyFloat;
break;
case DOUBLE:
Ty = TyDouble;
break;
case LONG + DOUBLE:
Ty = TyLDouble;
break;
default:
errorTok(Tok, "invalid type");
}
Tok = Tok->Next;
} // while (isTypename(Tok))
if (IsAtomic) {
Ty = copyType(Ty);
// 类型被标记为原子的
Ty->IsAtomic = true;
}
*Rest = Tok;
return Ty;
}
// funcParams = ("void" | param ("," param)* ("," "...")?)? ")"
// param = declspec declarator
static Type *funcParams(Token **Rest, Token *Tok, Type *Ty) {
// "void"
if (equal(Tok, "void") && equal(Tok->Next, ")")) {
*Rest = Tok->Next->Next;
return funcType(Ty);
}
Type Head = {};
Type *Cur = &Head;
bool IsVariadic = false;
while (!equal(Tok, ")")) {
// funcParams = param ("," param)*
// param = declspec declarator
if (Cur != &Head)
Tok = skip(Tok, ",");
// ("," "...")?
if (equal(Tok, "...")) {
IsVariadic = true;
Tok = Tok->Next;
skip(Tok, ")");
break;
}
Type *Ty2 = declspec(&Tok, Tok, NULL);
Ty2 = declarator(&Tok, Tok, Ty2);
// 存储名称
Token *Name = Ty2->Name;
// T类型的数组或函数被转换为T*
if (Ty2->Kind == TY_ARRAY) {
Ty2 = pointerTo(Ty2->Base);
Ty2->Name = Name;
} else if (Ty2->Kind == TY_FUNC) {
Ty2 = pointerTo(Ty2);
Ty2->Name = Name;
}
// 将类型复制到形参链表一份
Cur->Next = copyType(Ty2);
Cur = Cur->Next;
}
// 设置空参函数调用为可变的
if (Cur == &Head)
IsVariadic = true;
// 封装一个函数节点
Ty = funcType(Ty);
// 传递形参
Ty->Params = Head.Next;
// 传递可变参数
Ty->IsVariadic = IsVariadic;
*Rest = Tok->Next;
return Ty;
}
// 数组维数
// arrayDimensions = ("static" | "restrict")* constExpr? "]" typeSuffix
static Type *arrayDimensions(Token **Rest, Token *Tok, Type *Ty) {
// ("static" | "restrict")*
while (equal(Tok, "static") || equal(Tok, "restrict"))
Tok = Tok->Next;
// "]" 无数组维数的 "[]"
if (equal(Tok, "]")) {
Ty = typeSuffix(Rest, Tok->Next, Ty);
return arrayOf(Ty, -1);
}
// 有数组维数的情况
Node *Expr = conditional(&Tok, Tok);
Tok = skip(Tok, "]");
Ty = typeSuffix(Rest, Tok, Ty);
// 处理可变长度数组
if (Ty->Kind == TY_VLA || !isConstExpr(Expr))
return VLAOf(Ty, Expr);
// 处理固定长度数组
return arrayOf(Ty, eval(Expr));
}
// typeSuffix = "(" funcParams | "[" arrayDimensions | ε
static Type *typeSuffix(Token **Rest, Token *Tok, Type *Ty) {
// "(" funcParams
if (equal(Tok, "("))
return funcParams(Rest, Tok->Next, Ty);
// "[" arrayDimensions
if (equal(Tok, "["))
return arrayDimensions(Rest, Tok->Next, Ty);
*Rest = Tok;
return Ty;
}
// pointers = ("*" ("const" | "volatile" | "restrict")*)*
static Type *pointers(Token **Rest, Token *Tok, Type *Ty) {
// "*"*
// 构建所有的(多重)指针
while (consume(&Tok, Tok, "*")) {
Ty = pointerTo(Ty);
// 识别这些关键字并忽略
while (equal(Tok, "const") || equal(Tok, "volatile") ||
equal(Tok, "restrict") || equal(Tok, "__restrict") ||
equal(Tok, "__restrict__"))
Tok = Tok->Next;
}
*Rest = Tok;
return Ty;
}
// declarator = pointers ("(" ident ")" | "(" declarator ")" | ident) typeSuffix
static Type *declarator(Token **Rest, Token *Tok, Type *Ty) {
// pointers
Ty = pointers(&Tok, Tok, Ty);
// "(" declarator ")"
if (equal(Tok, "(")) {
// 记录"("的位置
Token *Start = Tok;
Type Dummy = {};
// 使Tok前进到")"后面的位置
declarator(&Tok, Start->Next, &Dummy);
Tok = skip(Tok, ")");
// 获取到括号后面的类型后缀Ty为解析完的类型Rest指向分号
Ty = typeSuffix(Rest, Tok, Ty);
// 解析Ty整体作为Base去构造返回Type的值
return declarator(&Tok, Start->Next, Ty);
}
// 默认名称为空
Token *Name = NULL;
// 名称位置指向类型后的区域
Token *NamePos = Tok;
// 存在名字则赋值
if (Tok->Kind == TK_IDENT) {
Name = Tok;
Tok = Tok->Next;
}
// typeSuffix
Ty = typeSuffix(Rest, Tok, Ty);
// ident
// 变量名 或 函数名
Ty->Name = Name;
Ty->NamePos = NamePos;
return Ty;
}
// abstractDeclarator = pointers ("(" abstractDeclarator ")")? typeSuffix
static Type *abstractDeclarator(Token **Rest, Token *Tok, Type *Ty) {
// pointers
Ty = pointers(&Tok, Tok, Ty);
// ("(" abstractDeclarator ")")?
if (equal(Tok, "(")) {
Token *Start = Tok;
Type Dummy = {};
// 使Tok前进到")"后面的位置
abstractDeclarator(&Tok, Start->Next, &Dummy);
Tok = skip(Tok, ")");
// 获取到括号后面的类型后缀Ty为解析完的类型Rest指向分号
Ty = typeSuffix(Rest, Tok, Ty);
// 解析Ty整体作为Base去构造返回Type的值
return abstractDeclarator(&Tok, Start->Next, Ty);
}
// typeSuffix
return typeSuffix(Rest, Tok, Ty);
}
// typeName = declspec abstractDeclarator
// 获取类型的相关信息
static Type *typename(Token **Rest, Token *Tok) {
// declspec
Type *Ty = declspec(&Tok, Tok, NULL);
// abstractDeclarator
return abstractDeclarator(Rest, Tok, Ty);
}
// 判断是否终结符匹配到了结尾
static bool isEnd(Token *Tok) {
// "}" | ",}"
return equal(Tok, "}") || (equal(Tok, ",") && equal(Tok->Next, "}"));
}
// 消耗掉结尾的终结符
// "}" | ",}"
static bool consumeEnd(Token **Rest, Token *Tok) {
// "}"
if (equal(Tok, "}")) {
*Rest = Tok->Next;
return true;
}
// ",}"
if (equal(Tok, ",") && equal(Tok->Next, "}")) {
*Rest = Tok->Next->Next;
return true;
}
// 没有消耗到指定字符
return false;
}
// 获取枚举类型信息
// enumSpecifier = ident? "{" enumList? "}"
// | ident ("{" enumList? "}")?
// enumList = ident ("=" constExpr)? ("," ident ("=" constExpr)?)* ","?
static Type *enumSpecifier(Token **Rest, Token *Tok) {
Type *Ty = enumType();
// 读取标签
// ident?
Token *Tag = NULL;
if (Tok->Kind == TK_IDENT) {
Tag = Tok;
Tok = Tok->Next;
}
// 处理没有{}的情况
if (Tag && !equal(Tok, "{")) {
Type *Ty = findTag(Tag);
if (!Ty)
errorTok(Tag, "unknown enum type");
if (Ty->Kind != TY_ENUM)
errorTok(Tag, "not an enum tag");
*Rest = Tok;
return Ty;
}
// "{" enumList? "}"
Tok = skip(Tok, "{");
// enumList
// 读取枚举列表
int I = 0; // 第几个枚举常量
int Val = 0; // 枚举常量的值
while (!consumeEnd(Rest, Tok)) {
if (I++ > 0)
Tok = skip(Tok, ",");
char *Name = getIdent(Tok);
Tok = Tok->Next;
// 判断是否存在赋值
if (equal(Tok, "="))
Val = constExpr(&Tok, Tok->Next);
// 存入枚举常量
VarScope *S = pushScope(Name);
S->EnumTy = Ty;
S->EnumVal = Val++;
}
if (Tag)
pushTagScope(Tag, Ty);
return Ty;
}
// typeofSpecifier = "(" (expr | typename) ")"
// typeof 获取对应的类型
static Type *typeofSpecifier(Token **Rest, Token *Tok) {
// "("
Tok = skip(Tok, "(");
Type *Ty;
if (isTypename(Tok)) {
// typename
// 匹配到相应的类型
Ty = typename(&Tok, Tok);
} else {
// expr
// 计算表达式,然后获取表达式的类型
Node *Nd = expr(&Tok, Tok);
addType(Nd);
Ty = Nd->Ty;
}
// ")"
*Rest = skip(Tok, ")");
// 将获取的类型进行返回
return Ty;
}
// 生成代码计算VLA的大小
static Node *computeVLASize(Type *Ty, Token *Tok) {
// 空表达式
Node *Nd = newNode(ND_NULL_EXPR, Tok);
// 处理指针的基部
if (Ty->Base)
Nd = newBinary(ND_COMMA, Nd, computeVLASize(Ty->Base, Tok), Tok);
// 如果都不是VLA则返回空表达式
if (Ty->Kind != TY_VLA)
return Nd;
// 基类的大小
Node *BaseSz;
if (Ty->Base->Kind == TY_VLA)
// 指向的是VLA
BaseSz = newVarNode(Ty->Base->VLASize, Tok);
else
// 本身是VLA
BaseSz = newNum(Ty->Base->Size, Tok);
Ty->VLASize = newLVar("", TyULong);
// VLASize=VLALen*BaseSzVLA大小=基类个数*基类大小
Node *Expr = newBinary(ND_ASSIGN, newVarNode(Ty->VLASize, Tok),
newBinary(ND_MUL, Ty->VLALen, BaseSz, Tok), Tok);
return newBinary(ND_COMMA, Nd, Expr, Tok);
}
// 根据相应Sz新建一个Alloca函数
static Node *newAlloca(Node *Sz) {
Node *Nd = newUnary(ND_FUNCALL, newVarNode(BuiltinAlloca, Sz->Tok), Sz->Tok);
Nd->FuncType = BuiltinAlloca->Ty;
Nd->Ty = BuiltinAlloca->Ty->ReturnTy;
Nd->Args = Sz;
addType(Sz);
return Nd;
}
// declaration = declspec (declarator ("=" initializer)?
// ("," declarator ("=" initializer)?)*)? ";"
static Node *declaration(Token **Rest, Token *Tok, Type *BaseTy,
VarAttr *Attr) {
Node Head = {};
Node *Cur = &Head;
// 对变量声明次数计数
int I = 0;
// (declarator ("=" expr)? ("," declarator ("=" expr)?)*)?
while (!equal(Tok, ";")) {
// 第1个变量不必匹配 ","
if (I++ > 0)
Tok = skip(Tok, ",");
// declarator
// 声明获取到变量类型,包括变量名
Type *Ty = declarator(&Tok, Tok, BaseTy);
if (Ty->Kind == TY_VOID)
errorTok(Tok, "variable declared void");
if (!Ty->Name)
errorTok(Ty->NamePos, "variable name omitted");
if (Attr && Attr->IsStatic) {
// 静态局部变量
Obj *Var = newAnonGVar(Ty);
pushScope(getIdent(Ty->Name))->Var = Var;
if (equal(Tok, "="))
GVarInitializer(&Tok, Tok->Next, Var);
continue;
}
// 生成代码计算VLA的大小
// 在此生成是因为即使Ty不是VLA但也可能是一个指向VLA的指针
Cur->Next = newUnary(ND_EXPR_STMT, computeVLASize(Ty, Tok), Tok);
Cur = Cur->Next;
// 处理可变长度数组
if (Ty->Kind == TY_VLA) {
if (equal(Tok, "="))
errorTok(Tok, "variable-sized object may not be initialized");
// VLA被改写为alloca()调用
// 例如:`int X[N]`被改写为`Tmp = N, X = alloca(Tmp)`
// X
Obj *Var = newLVar(getIdent(Ty->Name), Ty);
// X的类型名
Token *Tok = Ty->Name;
// X = alloca(Tmp)VLASize对应N
Node *Expr = newBinary(ND_ASSIGN, newVLAPtr(Var, Tok),
newAlloca(newVarNode(Ty->VLASize, Tok)), Tok);
// 存放在表达式语句中
Cur->Next = newUnary(ND_EXPR_STMT, Expr, Tok);
Cur = Cur->Next;
continue;
}
Obj *Var = newLVar(getIdent(Ty->Name), Ty);
// 读取是否存在变量的对齐值
if (Attr && Attr->Align)
Var->Align = Attr->Align;
// 如果不存在"="则为变量声明不需要生成节点已经存储在Locals中了
if (equal(Tok, "=")) {
// 解析变量的初始化器
Node *Expr = LVarInitializer(&Tok, Tok->Next, Var);
// 存放在表达式语句中
Cur->Next = newUnary(ND_EXPR_STMT, Expr, Tok);
Cur = Cur->Next;
}
if (Var->Ty->Size < 0)
errorTok(Ty->Name, "variable has incomplete type");
if (Var->Ty->Kind == TY_VOID)
errorTok(Ty->Name, "variable declared void");
}
// 将所有表达式语句,存放在代码块中
Node *Nd = newNode(ND_BLOCK, Tok);
Nd->Body = Head.Next;
*Rest = Tok->Next;
return Nd;
}
// 跳过多余的元素
static Token *skipExcessElement(Token *Tok) {
if (equal(Tok, "{")) {
Tok = skipExcessElement(Tok->Next);
return skip(Tok, "}");
}
// 解析并舍弃多余的元素
assign(&Tok, Tok);
return Tok;
}
// stringInitializer = stringLiteral
static void stringInitializer(Token **Rest, Token *Tok, Initializer *Init) {
// 如果是可调整的,就构造一个包含数组的初始化器
// 字符串字面量在词法解析部分已经增加了'\0'
if (Init->IsFlexible)
*Init = *newInitializer(arrayOf(Init->Ty->Base, Tok->Ty->ArrayLen), false);
// 取数组和字符串的最短长度
int Len = MIN(Init->Ty->ArrayLen, Tok->Ty->ArrayLen);
// 获取字符串字面量
switch (Init->Ty->Base->Size) {
case 1: {
// char类型
char *Str = Tok->Str;
// 遍历赋值
for (int I = 0; I < Len; I++)
Init->Children[I]->Expr = newNum(Str[I], Tok);
break;
}
case 2: {
// UTF-16类型
uint16_t *Str = (uint16_t *)Tok->Str;
for (int I = 0; I < Len; I++)
Init->Children[I]->Expr = newNum(Str[I], Tok);
break;
}
case 4: {
// UTF-32类型
uint32_t *Str = (uint32_t *)Tok->Str;
for (int I = 0; I < Len; I++)
Init->Children[I]->Expr = newNum(Str[I], Tok);
break;
}
default:
unreachable();
}
*Rest = Tok->Next;
}
// 数组指派器,用于从指定位置开始初始化
static void arrayDesignator(Token **Rest, Token *Tok, Type *Ty, int *Begin,
int *End) {
// 获取指定位置的索引
*Begin = constExpr(&Tok, Tok->Next);
if (*Begin >= Ty->ArrayLen)
errorTok(Tok, "array designator index exceeds array bounds");
// 匹配...后面的索引值
if (equal(Tok, "...")) {
// ...后面的索引值
*End = constExpr(&Tok, Tok->Next);
if (*End >= Ty->ArrayLen)
errorTok(Tok, "array designator index exceeds array bounds");
if (*End < *Begin)
errorTok(Tok, "array designator range [%d, %d] is empty", *Begin, *End);
} else {
// 没有...的情况
*End = *Begin;
}
*Rest = skip(Tok, "]");
}
// struct-designator = "." ident
// 结构体指派器
static Member *structDesignator(Token **Rest, Token *Tok, Type *Ty) {
Token *Start = Tok;
Tok = skip(Tok, ".");
if (Tok->Kind != TK_IDENT)
errorTok(Tok, "expected a field designator");
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
// 匿名结构体成员
if (Mem->Ty->Kind == TY_STRUCT && !Mem->Name) {
if (getStructMember(Mem->Ty, Tok)) {
*Rest = Start;
return Mem;
}
continue;
}
// 常规结构体成员
if (Mem->Name->Len == Tok->Len &&
!strncmp(Mem->Name->Loc, Tok->Loc, Tok->Len)) {
*Rest = Tok->Next;
return Mem;
}
}
errorTok(Tok, "struct has no such member");
}
// designation = ("[" const-expr "]" | "." ident)* "="? initializer
// 进行指派
static void designation(Token **Rest, Token *Tok, Initializer *Init) {
// 多层[索引]的解析
if (equal(Tok, "[")) {
if (Init->Ty->Kind != TY_ARRAY)
errorTok(Tok, "array index in non-array initializer");
// 获取索引值
int Begin, End;
arrayDesignator(&Tok, Tok, Init->Ty, &Begin, &End);
// 遍历范围内的值,进行递归指派
Token *Tok2;
for (int I = Begin; I <= End; I++)
designation(&Tok2, Tok, Init->Children[I]);
// 进行后续初始化
arrayInitializer2(Rest, Tok2, Init, Begin + 1);
return;
}
// 多层结构体的解析
if (equal(Tok, ".") && Init->Ty->Kind == TY_STRUCT) {
// 获取成员
Member *Mem = structDesignator(&Tok, Tok, Init->Ty);
// 递归指派
designation(&Tok, Tok, Init->Children[Mem->Idx]);
Init->Expr = NULL;
// 进行后续初始化
structInitializer2(Rest, Tok, Init, Mem->Next);
return;
}
// 多层联合体的解析
if (equal(Tok, ".") && Init->Ty->Kind == TY_UNION) {
// 获取成员
Member *Mem = structDesignator(&Tok, Tok, Init->Ty);
Init->Mem = Mem;
// 递归指派
designation(Rest, Tok, Init->Children[Mem->Idx]);
return;
}
if (equal(Tok, "."))
errorTok(Tok, "field name not in struct or union initializer");
if (equal(Tok, "="))
Tok = Tok->Next;
// 对该位置进行初始化
initializer2(Rest, Tok, Init);
}
// 计算数组初始化元素个数
static int countArrayInitElements(Token *Tok, Type *Ty) {
bool First = true;
Initializer *Dummy = newInitializer(Ty->Base, true);
// 项数,最大项数
int I = 0, Max = 0;
// 遍历所有匹配的项
while (!consumeEnd(&Tok, Tok)) {
if (!First)
Tok = skip(Tok, ",");
First = false;
// 处理指派
if (equal(Tok, "[")) {
I = constExpr(&Tok, Tok->Next);
if (equal(Tok, "..."))
I = constExpr(&Tok, Tok->Next);
Tok = skip(Tok, "]");
designation(&Tok, Tok, Dummy);
} else {
initializer2(&Tok, Tok, Dummy);
}
I++;
// 当前项数与之前最大项数取最大数
Max = MAX(Max, I);
}
return Max;
}
// arrayInitializer1 = "{" initializer ("," initializer)* ","? "}"
static void arrayInitializer1(Token **Rest, Token *Tok, Initializer *Init) {
Tok = skip(Tok, "{");
bool First = true;
// 如果数组是可调整的,那么就计算数组的元素数,然后进行初始化器的构造
if (Init->IsFlexible) {
int Len = countArrayInitElements(Tok, Init->Ty);
// 在这里Ty也被重新构造为了数组
*Init = *newInitializer(arrayOf(Init->Ty->Base, Len), false);
}
// 遍历数组
for (int I = 0; !consumeEnd(Rest, Tok); I++) {
if (!First)
Tok = skip(Tok, ",");
First = false;
// 如果存在指派器,那么就解析指派
if (equal(Tok, "[")) {
// 获取最外层指派器的所使用的位置
int Begin, End;
arrayDesignator(&Tok, Tok, Init->Ty, &Begin, &End);
// 遍历对范围内的位置进行指派
Token *Tok2;
for (int J = Begin; J <= End; J++)
designation(&Tok2, Tok, Init->Children[J]);
Tok = Tok2;
I = End;
continue;
}
// 正常解析元素
if (I < Init->Ty->ArrayLen)
initializer2(&Tok, Tok, Init->Children[I]);
// 跳过多余的元素
else
Tok = skipExcessElement(Tok);
}
}
// arrayIntializer2 = initializer ("," initializer)* ","?
static void arrayInitializer2(Token **Rest, Token *Tok, Initializer *Init,
int I) {
// 如果数组是可调整的,那么就计算数组的元素数,然后进行初始化器的构造
if (Init->IsFlexible) {
int Len = countArrayInitElements(Tok, Init->Ty);
*Init = *newInitializer(arrayOf(Init->Ty->Base, Len), false);
}
// 遍历数组
for (; I < Init->Ty->ArrayLen && !isEnd(Tok); I++) {
Token *Start = Tok;
if (I > 0)
Tok = skip(Tok, ",");
// 匹配到了指派器,那么就返回到上层函数进行初始化
if (equal(Tok, "[") || equal(Tok, ".")) {
*Rest = Start;
return;
}
initializer2(&Tok, Tok, Init->Children[I]);
}
*Rest = Tok;
}
// structInitializer1 = "{" initializer ("," initializer)* ","? "}"
static void structInitializer1(Token **Rest, Token *Tok, Initializer *Init) {
Tok = skip(Tok, "{");
// 成员变量的链表
Member *Mem = Init->Ty->Mems;
bool First = true;
while (!consumeEnd(Rest, Tok)) {
// 判断是否为第一个成员
if (!First)
Tok = skip(Tok, ",");
First = false;
// 匹配指派初始化
if (equal(Tok, ".")) {
// 成员进行指派初始化
Mem = structDesignator(&Tok, Tok, Init->Ty);
designation(&Tok, Tok, Init->Children[Mem->Idx]);
Mem = Mem->Next;
continue;
}
if (Mem) {
// 处理成员
initializer2(&Tok, Tok, Init->Children[Mem->Idx]);
Mem = Mem->Next;
} else {
// 处理多余的成员
Tok = skipExcessElement(Tok);
}
}
}
// structIntializer2 = initializer ("," initializer)* ","?
static void structInitializer2(Token **Rest, Token *Tok, Initializer *Init,
Member *Mem) {
bool First = true;
// 遍历所有成员变量
for (; Mem && !isEnd(Tok); Mem = Mem->Next) {
Token *Start = Tok;
if (!First)
Tok = skip(Tok, ",");
First = false;
// 匹配到了指派器,那么就返回到上层函数进行初始化
if (equal(Tok, "[") || equal(Tok, ".")) {
*Rest = Start;
return;
}
initializer2(&Tok, Tok, Init->Children[Mem->Idx]);
}
*Rest = Tok;
}
// unionInitializer = "{" initializer "}"
static void unionInitializer(Token **Rest, Token *Tok, Initializer *Init) {
// 联合体只接受一个成员用来初始化,默认为第一个
// 可以通过指派,使用其他成员进行初始化
if (equal(Tok, "{") && equal(Tok->Next, ".")) {
// 获取成员
Member *Mem = structDesignator(&Tok, Tok->Next, Init->Ty);
Init->Mem = Mem;
// 进行指派
designation(&Tok, Tok, Init->Children[Mem->Idx]);
*Rest = skip(Tok, "}");
return;
}
// 默认将第一个成员存入初始化器的Mem
Init->Mem = Init->Ty->Mems;
if (equal(Tok, "{")) {
// 存在括号的情况
initializer2(&Tok, Tok->Next, Init->Children[0]);
// ","?
consume(&Tok, Tok, ",");
*Rest = skip(Tok, "}");
} else {
// 不存在括号的情况
initializer2(Rest, Tok, Init->Children[0]);
}
}
// initializer = stringInitializer | arrayInitializer | structInitializer
// | unionInitializer |assign
static void initializer2(Token **Rest, Token *Tok, Initializer *Init) {
// 字符串字面量的初始化
if (Init->Ty->Kind == TY_ARRAY && Tok->Kind == TK_STR) {
stringInitializer(Rest, Tok, Init);
return;
}
// 数组的初始化
if (Init->Ty->Kind == TY_ARRAY) {
if (equal(Tok, "{"))
// 存在括号的情况
arrayInitializer1(Rest, Tok, Init);
else
// 不存在括号的情况
arrayInitializer2(Rest, Tok, Init, 0);
return;
}
// 结构体的初始化
if (Init->Ty->Kind == TY_STRUCT) {
// 匹配使用其他结构体来赋值,其他结构体需要先被解析过
// 存在括号的情况
if (equal(Tok, "{")) {
structInitializer1(Rest, Tok, Init);
return;
}
// 不存在括号的情况
Node *Expr = assign(Rest, Tok);
addType(Expr);
if (Expr->Ty->Kind == TY_STRUCT) {
Init->Expr = Expr;
return;
}
structInitializer2(Rest, Tok, Init, Init->Ty->Mems);
return;
}
// 联合体的初始化
if (Init->Ty->Kind == TY_UNION) {
unionInitializer(Rest, Tok, Init);
return;
}
// 处理标量外的大括号例如int x = {3};
if (equal(Tok, "{")) {
initializer2(&Tok, Tok->Next, Init);
*Rest = skip(Tok, "}");
return;
}
// assign
// 为节点存储对应的表达式
Init->Expr = assign(Rest, Tok);
}
// 复制结构体的类型
static Type *copyStructType(Type *Ty) {
// 复制结构体的类型
Ty = copyType(Ty);
// 复制结构体成员的类型
Member Head = {};
Member *Cur = &Head;
// 遍历成员
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
Member *M = calloc(1, sizeof(Member));
*M = *Mem;
Cur->Next = M;
Cur = Cur->Next;
}
Ty->Mems = Head.Next;
return Ty;
}
// 初始化器
static Initializer *initializer(Token **Rest, Token *Tok, Type *Ty,
Type **NewTy) {
// 新建一个解析了类型的初始化器
Initializer *Init = newInitializer(Ty, true);
// 解析需要赋值到Init中
initializer2(Rest, Tok, Init);
if ((Ty->Kind == TY_STRUCT || Ty->Kind == TY_UNION) && Ty->IsFlexible) {
// 复制结构体类型
Ty = copyStructType(Ty);
Member *Mem = Ty->Mems;
// 遍历到最后一个成员
while (Mem->Next)
Mem = Mem->Next;
// 灵活数组类型替换为实际的数组类型
Mem->Ty = Init->Children[Mem->Idx]->Ty;
// 增加结构体的类型大小
Ty->Size += Mem->Ty->Size;
// 将新类型传回变量
*NewTy = Ty;
return Init;
}
// 将新类型传回变量
*NewTy = Init->Ty;
return Init;
}
// 指派初始化表达式
static Node *initDesigExpr(InitDesig *Desig, Token *Tok) {
// 返回Desig中的变量
if (Desig->Var)
return newVarNode(Desig->Var, Tok);
// 返回Desig中的成员变量
if (Desig->Mem) {
Node *Nd = newUnary(ND_MEMBER, initDesigExpr(Desig->Next, Tok), Tok);
Nd->Mem = Desig->Mem;
return Nd;
}
// 需要赋值的变量名
// 递归到次外层Desig有此时最外层有Desig->Var或者Desig->Mem
// 然后逐层计算偏移量
Node *LHS = initDesigExpr(Desig->Next, Tok);
// 偏移量
Node *RHS = newNum(Desig->Idx, Tok);
// 返回偏移后的变量地址
return newUnary(ND_DEREF, newAdd(LHS, RHS, Tok), Tok);
}
// 创建局部变量的初始化
static Node *createLVarInit(Initializer *Init, Type *Ty, InitDesig *Desig,
Token *Tok) {
if (Ty->Kind == TY_ARRAY) {
// 预备空表达式的情况
Node *Nd = newNode(ND_NULL_EXPR, Tok);
for (int I = 0; I < Ty->ArrayLen; I++) {
// 这里next指向了上一级Desig的信息以及在其中的偏移量。
InitDesig Desig2 = {Desig, I};
// 局部变量进行初始化
Node *RHS = createLVarInit(Init->Children[I], Ty->Base, &Desig2, Tok);
// 构造一个形如NULL_EXPREXPR1EXPR2…的二叉树
Nd = newBinary(ND_COMMA, Nd, RHS, Tok);
}
return Nd;
}
// 被其他结构体赋过值则会存在Expr因而不解析
if (Ty->Kind == TY_STRUCT && !Init->Expr) {
// 构造结构体的初始化器结构
Node *Nd = newNode(ND_NULL_EXPR, Tok);
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
// Desig2存储了成员变量
InitDesig Desig2 = {Desig, 0, Mem};
Node *RHS =
createLVarInit(Init->Children[Mem->Idx], Mem->Ty, &Desig2, Tok);
Nd = newBinary(ND_COMMA, Nd, RHS, Tok);
}
return Nd;
}
if (Ty->Kind == TY_UNION) {
// 存在指派初始化的成员则使用,否则默认为第一个成员
Member *Mem = Init->Mem ? Init->Mem : Ty->Mems;
// Desig2存储了成员变量
InitDesig Desig2 = {Desig, 0, Mem};
// 只处理第一个成员变量
return createLVarInit(Init->Children[Mem->Idx], Mem->Ty, &Desig2, Tok);
}
// 如果需要作为右值的表达式为空,则设为空表达式
if (!Init->Expr)
return newNode(ND_NULL_EXPR, Tok);
// 变量等可以直接赋值的左值
Node *LHS = initDesigExpr(Desig, Tok);
return newBinary(ND_ASSIGN, LHS, Init->Expr, Tok);
}
// 局部变量初始化器
static Node *LVarInitializer(Token **Rest, Token *Tok, Obj *Var) {
// 获取初始化器,将值与数据结构一一对应
Initializer *Init = initializer(Rest, Tok, Var->Ty, &Var->Ty);
// 指派初始化
InitDesig Desig = {NULL, 0, NULL, Var};
// 我们首先为所有元素赋0然后有指定值的再进行赋值
Node *LHS = newNode(ND_MEMZERO, Tok);
LHS->Var = Var;
// 创建局部变量的初始化
Node *RHS = createLVarInit(Init, Var->Ty, &Desig, Tok);
// 左部为全部清零,右部为需要赋值的部分
return newBinary(ND_COMMA, LHS, RHS, Tok);
}
// 对临时转换Buf类型读取Sz大小的数值
static uint64_t readBuf(char *Buf, int Sz) {
if (Sz == 1)
return *Buf;
if (Sz == 2)
return *(uint16_t *)Buf;
if (Sz == 4)
return *(uint32_t *)Buf;
if (Sz == 8)
return *(uint64_t *)Buf;
unreachable();
return -1;
}
// 临时转换Buf类型对Val进行存储
static void writeBuf(char *Buf, uint64_t Val, int Sz) {
if (Sz == 1)
*Buf = Val;
else if (Sz == 2)
*(uint16_t *)Buf = Val;
else if (Sz == 4)
*(uint32_t *)Buf = Val;
else if (Sz == 8)
*(uint64_t *)Buf = Val;
else
unreachable();
}
// 对全局变量的初始化器写入数据
static Relocation *writeGVarData(Relocation *Cur, Initializer *Init, Type *Ty,
char *Buf, int Offset) {
// 处理数组
if (Ty->Kind == TY_ARRAY) {
int Sz = Ty->Base->Size;
for (int I = 0; I < Ty->ArrayLen; I++)
Cur =
writeGVarData(Cur, Init->Children[I], Ty->Base, Buf, Offset + Sz * I);
return Cur;
}
// 处理结构体
if (Ty->Kind == TY_STRUCT) {
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
if (Mem->IsBitfield) {
// 结构体位域成员
Node *Expr = Init->Children[Mem->Idx]->Expr;
if (!Expr)
break;
// 获取相对于缓冲区的偏移量
char *Loc = Buf + Offset + Mem->Offset;
// 读取已经写入的值
uint64_t OldVal = readBuf(Loc, Mem->Ty->Size);
// 计算需要写入的新值
uint64_t NewVal = eval(Expr);
// 获取位域长度的掩码
uint64_t Mask = (1L << Mem->BitWidth) - 1;
// 对新值取交位域长度的位,然后左移到相应的偏移位置
// 最后与旧值取或,得到合并之后的值
uint64_t Combined = OldVal | ((NewVal & Mask) << Mem->BitOffset);
// 写入合并之后的值
writeBuf(Loc, Combined, Mem->Ty->Size);
} else {
// 结构体常规成员
Cur = writeGVarData(Cur, Init->Children[Mem->Idx], Mem->Ty, Buf,
Offset + Mem->Offset);
}
}
return Cur;
}
// 处理联合体
if (Ty->Kind == TY_UNION) {
if (!Init->Mem)
return Cur;
return writeGVarData(Cur, Init->Children[Init->Mem->Idx], Init->Mem->Ty,
Buf, Offset);
}
// 这里返回则会使Buf值为0
if (!Init->Expr)
return Cur;
// 处理单精度浮点数
if (Ty->Kind == TY_FLOAT) {
// 将缓冲区加上偏移量转换为float*后访问
*(float *)(Buf + Offset) = evalDouble(Init->Expr);
return Cur;
}
// 处理双精度浮点数
if (Ty->Kind == TY_DOUBLE) {
// 将缓冲区加上偏移量转换为double*后访问
*(double *)(Buf + Offset) = evalDouble(Init->Expr);
return Cur;
}
// 预设使用到的 其他全局变量的名称
char **Label = NULL;
uint64_t Val = eval2(Init->Expr, &Label);
// 如果不存在Label说明可以直接计算常量表达式的值
if (!Label) {
writeBuf(Buf + Offset, Val, Ty->Size);
return Cur;
}
// 存在Label则表示使用了其他全局变量
Relocation *Rel = calloc(1, sizeof(Relocation));
Rel->Offset = Offset;
Rel->Label = Label;
Rel->Addend = Val;
// 压入链表顶部
Cur->Next = Rel;
return Cur->Next;
}
// 全局变量在编译时需计算出初始化的值,然后写入.data段。
static void GVarInitializer(Token **Rest, Token *Tok, Obj *Var) {
// 获取到初始化器
Initializer *Init = initializer(Rest, Tok, Var->Ty, &Var->Ty);
// 写入计算过后的数据
// 新建一个重定向的链表
Relocation Head = {};
char *Buf = calloc(1, Var->Ty->Size);
writeGVarData(&Head, Init, Var->Ty, Buf, 0);
// 全局变量的数据
Var->InitData = Buf;
// Head为空所以返回Head.Next的数据
Var->Rel = Head.Next;
}
// 判断是否为类型名
static bool isTypename(Token *Tok) {
static HashMap Map;
// 哈希表容量为0说明还没初始化
if (Map.Capacity == 0) {
static char *Kw[] = {
"void", "_Bool", "char", "short", "int",
"long", "struct", "union", "typedef", "enum",
"static", "extern", "_Alignas", "signed", "unsigned",
"const", "volatile", "auto", "register", "restrict",
"__restrict", "__restrict__", "_Noreturn", "float", "double",
"typeof", "inline", "_Thread_local", "__thread", "_Atomic",
};
// 遍历类型名列表插入哈希表
for (int I = 0; I < sizeof(Kw) / sizeof(*Kw); I++)
hashmapPut(&Map, Kw[I], (void *)1);
}
// 查找是否为类型别名
return hashmapGet2(&Map, Tok->Loc, Tok->Len) || findTypedef(Tok);
}
// asmStmt = "asm" ("volatile" | "inline")* "(" stringLiteral ")"
static Node *asmStmt(Token **Rest, Token *Tok) {
Node *Nd = newNode(ND_ASM, Tok);
Tok = Tok->Next;
// ("volatile" | "inline")*
while (equal(Tok, "volatile") || equal(Tok, "inline"))
Tok = Tok->Next;
// "("
Tok = skip(Tok, "(");
// stringLiteral
if (Tok->Kind != TK_STR || Tok->Ty->Base->Kind != TY_CHAR)
errorTok(Tok, "expected string literal");
Nd->AsmStr = Tok->Str;
// ")"
*Rest = skip(Tok->Next, ")");
return Nd;
}
// 解析语句
// stmt = "return" expr? ";"
// | "if" "(" expr ")" stmt ("else" stmt)?
// | "switch" "(" expr ")" stmt
// | "case" constExpr ("..." constExpr)? ":" stmt
// | "default" ":" stmt
// | "for" "(" exprStmt expr? ";" expr? ")" stmt
// | "while" "(" expr ")" stmt
// | "do" stmt "while" "(" expr ")" ";"
// | asmStmt
// | "goto" (ident | "*" expr) ";"
// | "break" ";"
// | "continue" ";"
// | ident ":" stmt
// | "{" compoundStmt
// | exprStmt
static Node *stmt(Token **Rest, Token *Tok) {
// "return" expr ";"
if (equal(Tok, "return")) {
Node *Nd = newNode(ND_RETURN, Tok);
// 空返回语句
if (consume(Rest, Tok->Next, ";"))
return Nd;
Node *Exp = expr(&Tok, Tok->Next);
*Rest = skip(Tok, ";");
addType(Exp);
// 对于返回值进行类型转换
Type *Ty = CurrentFn->Ty->ReturnTy;
// 对于返回值为结构体时不进行类型转换
if (Ty->Kind != TY_STRUCT && Ty->Kind != TY_UNION)
Exp = newCast(Exp, CurrentFn->Ty->ReturnTy);
Nd->LHS = Exp;
return Nd;
}
// 解析if语句
// "if" "(" expr ")" stmt ("else" stmt)?
if (equal(Tok, "if")) {
Node *Nd = newNode(ND_IF, Tok);
// "(" expr ")",条件内语句
Tok = skip(Tok->Next, "(");
Nd->Cond = expr(&Tok, Tok);
Tok = skip(Tok, ")");
// stmt符合条件后的语句
Nd->Then = stmt(&Tok, Tok);
// ("else" stmt)?,不符合条件后的语句
if (equal(Tok, "else"))
Nd->Els = stmt(&Tok, Tok->Next);
*Rest = Tok;
return Nd;
}
// "switch" "(" expr ")" stmt
if (equal(Tok, "switch")) {
Node *Nd = newNode(ND_SWITCH, Tok);
Tok = skip(Tok->Next, "(");
Nd->Cond = expr(&Tok, Tok);
Tok = skip(Tok, ")");
// 记录此前的CurrentSwitch
Node *Sw = CurrentSwitch;
// 设置当前的CurrentSwitch
CurrentSwitch = Nd;
// 存储此前break标签的名称
char *Brk = BrkLabel;
// 设置break标签的名称
BrkLabel = Nd->BrkLabel = newUniqueName();
// 进入解析各个case
// stmt
Nd->Then = stmt(Rest, Tok);
// 恢复此前CurrentSwitch
CurrentSwitch = Sw;
// 恢复此前break标签的名称
BrkLabel = Brk;
return Nd;
}
// "case" constExpr ":" stmt
if (equal(Tok, "case")) {
if (!CurrentSwitch)
errorTok(Tok, "stray case");
Node *Nd = newNode(ND_CASE, Tok);
// case后面的数值
int Begin = constExpr(&Tok, Tok->Next);
// ...后面的数值
int End;
// 存在...
if (equal(Tok, "...")) {
// 解析...后面的数值
End = constExpr(&Tok, Tok->Next);
if (End < Begin)
errorTok(Tok, "empty case range specified");
} else {
// 不存在...
End = Begin;
}
Tok = skip(Tok, ":");
Nd->Label = newUniqueName();
// case中的语句
Nd->LHS = stmt(Rest, Tok);
// case对应的数值
Nd->Begin = Begin;
Nd->End = End;
// 将旧的CurrentSwitch链表的头部存入Nd的CaseNext
Nd->CaseNext = CurrentSwitch->CaseNext;
// 将Nd存入CurrentSwitch的CaseNext
CurrentSwitch->CaseNext = Nd;
return Nd;
}
// "default" ":" stmt
if (equal(Tok, "default")) {
if (!CurrentSwitch)
errorTok(Tok, "stray default");
Node *Nd = newNode(ND_CASE, Tok);
Tok = skip(Tok->Next, ":");
Nd->Label = newUniqueName();
Nd->LHS = stmt(Rest, Tok);
// 存入CurrentSwitch->DefaultCase的默认标签
CurrentSwitch->DefaultCase = Nd;
return Nd;
}
// "for" "(" exprStmt expr? ";" expr? ")" stmt
if (equal(Tok, "for")) {
Node *Nd = newNode(ND_FOR, Tok);
// "("
Tok = skip(Tok->Next, "(");
// 进入for循环域
enterScope();
// 存储此前break和continue标签的名称
char *Brk = BrkLabel;
char *Cont = ContLabel;
// 设置break和continue标签的名称
BrkLabel = Nd->BrkLabel = newUniqueName();
ContLabel = Nd->ContLabel = newUniqueName();
// exprStmt
if (isTypename(Tok)) {
// 初始化循环变量
Type *BaseTy = declspec(&Tok, Tok, NULL);
Nd->Init = declaration(&Tok, Tok, BaseTy, NULL);
} else {
// 初始化语句
Nd->Init = exprStmt(&Tok, Tok);
}
// expr?
if (!equal(Tok, ";"))
Nd->Cond = expr(&Tok, Tok);
// ";"
Tok = skip(Tok, ";");
// expr?
if (!equal(Tok, ")"))
Nd->Inc = expr(&Tok, Tok);
// ")"
Tok = skip(Tok, ")");
// stmt
Nd->Then = stmt(Rest, Tok);
// 退出for循环域
leaveScope();
// 恢复此前的break和continue标签
BrkLabel = Brk;
ContLabel = Cont;
return Nd;
}
// "while" "(" expr ")" stmt
if (equal(Tok, "while")) {
Node *Nd = newNode(ND_FOR, Tok);
// "("
Tok = skip(Tok->Next, "(");
// expr
Nd->Cond = expr(&Tok, Tok);
// ")"
Tok = skip(Tok, ")");
// 存储此前break和continue标签的名称
char *Brk = BrkLabel;
char *Cont = ContLabel;
// 设置break和continue标签的名称
BrkLabel = Nd->BrkLabel = newUniqueName();
ContLabel = Nd->ContLabel = newUniqueName();
// stmt
Nd->Then = stmt(Rest, Tok);
// 恢复此前的break和continue标签
BrkLabel = Brk;
ContLabel = Cont;
return Nd;
}
// asmStmt
if (equal(Tok, "asm"))
return asmStmt(Rest, Tok);
// "goto" ident ";"
if (equal(Tok, "goto")) {
if (equal(Tok->Next, "*")) {
// `goto *Ptr`跳转到Ptr指向的地址
Node *Nd = newNode(ND_GOTO_EXPR, Tok);
Nd->LHS = expr(&Tok, Tok->Next->Next);
*Rest = skip(Tok, ";");
return Nd;
}
Node *Nd = newNode(ND_GOTO, Tok);
Nd->Label = getIdent(Tok->Next);
// 将Nd同时存入Gotos最后用于解析UniqueLabel
Nd->GotoNext = Gotos;
Gotos = Nd;
*Rest = skip(Tok->Next->Next, ";");
return Nd;
}
// "do" stmt "while" "(" expr ")" ";"
if (equal(Tok, "do")) {
Node *Nd = newNode(ND_DO, Tok);
// 存储此前break和continue标签的名称
char *Brk = BrkLabel;
char *Cont = ContLabel;
// 设置break和continue标签的名称
BrkLabel = Nd->BrkLabel = newUniqueName();
ContLabel = Nd->ContLabel = newUniqueName();
// stmt
// do代码块内的语句
Nd->Then = stmt(&Tok, Tok->Next);
// 恢复此前的break和continue标签
BrkLabel = Brk;
ContLabel = Cont;
// "while" "(" expr ")" ";"
Tok = skip(Tok, "while");
Tok = skip(Tok, "(");
// expr
// while使用的条件表达式
Nd->Cond = expr(&Tok, Tok);
Tok = skip(Tok, ")");
*Rest = skip(Tok, ";");
return Nd;
}
// "break" ";"
if (equal(Tok, "break")) {
if (!BrkLabel)
errorTok(Tok, "stray break");
// 跳转到break标签的位置
Node *Nd = newNode(ND_GOTO, Tok);
Nd->UniqueLabel = BrkLabel;
*Rest = skip(Tok->Next, ";");
return Nd;
}
// "continue" ";"
if (equal(Tok, "continue")) {
if (!ContLabel)
errorTok(Tok, "stray continue");
// 跳转到continue标签的位置
Node *Nd = newNode(ND_GOTO, Tok);
Nd->UniqueLabel = ContLabel;
*Rest = skip(Tok->Next, ";");
return Nd;
}
// ident ":" stmt
if (Tok->Kind == TK_IDENT && equal(Tok->Next, ":")) {
Node *Nd = newNode(ND_LABEL, Tok);
Nd->Label = strndup(Tok->Loc, Tok->Len);
Nd->UniqueLabel = newUniqueName();
Nd->LHS = stmt(Rest, Tok->Next->Next);
// 将Nd同时存入Labels最后用于goto解析UniqueLabel
Nd->GotoNext = Labels;
Labels = Nd;
return Nd;
}
// "{" compoundStmt
if (equal(Tok, "{"))
return compoundStmt(Rest, Tok->Next);
// exprStmt
return exprStmt(Rest, Tok);
}
// 解析复合语句
// compoundStmt = (typedef | declaration | stmt)* "}"
static Node *compoundStmt(Token **Rest, Token *Tok) {
Node *Nd = newNode(ND_BLOCK, Tok);
// 这里使用了和词法分析类似的单向链表结构
Node Head = {};
Node *Cur = &Head;
// 进入新的域
enterScope();
// (declaration | stmt)* "}"
while (!equal(Tok, "}")) {
// declaration
if (isTypename(Tok) && !equal(Tok->Next, ":")) {
VarAttr Attr = {};
Type *BaseTy = declspec(&Tok, Tok, &Attr);
// 解析typedef的语句
if (Attr.IsTypedef) {
Tok = parseTypedef(Tok, BaseTy);
continue;
}
// 解析函数
if (isFunction(Tok)) {
Tok = function(Tok, BaseTy, &Attr);
continue;
}
// 解析外部全局变量
if (Attr.IsExtern) {
Tok = globalVariable(Tok, BaseTy, &Attr);
continue;
}
// 解析变量声明语句
Cur->Next = declaration(&Tok, Tok, BaseTy, &Attr);
}
// stmt
else {
Cur->Next = stmt(&Tok, Tok);
}
Cur = Cur->Next;
// 构造完AST后为节点添加类型信息
addType(Cur);
}
// 结束当前的域
leaveScope();
// Nd的Body存储了{}内解析的语句
Nd->Body = Head.Next;
*Rest = Tok->Next;
return Nd;
}
// 解析表达式语句
// exprStmt = expr? ";"
static Node *exprStmt(Token **Rest, Token *Tok) {
// ";"
if (equal(Tok, ";")) {
*Rest = Tok->Next;
return newNode(ND_BLOCK, Tok);
}
// expr ";"
Node *Nd = newNode(ND_EXPR_STMT, Tok);
Nd->LHS = expr(&Tok, Tok);
*Rest = skip(Tok, ";");
return Nd;
}
// 解析表达式
// expr = assign ("," expr)?
static Node *expr(Token **Rest, Token *Tok) {
Node *Nd = assign(&Tok, Tok);
if (equal(Tok, ","))
return newBinary(ND_COMMA, Nd, expr(Rest, Tok->Next), Tok);
*Rest = Tok;
return Nd;
}
static int64_t eval(Node *Nd) { return eval2(Nd, NULL); }
// 计算给定节点的常量表达式计算
// 常量表达式可以是数字或者是 ptr±nptr是指向全局变量的指针n是偏移量。
static int64_t eval2(Node *Nd, char ***Label) {
addType(Nd);
// 处理浮点数
if (isFloNum(Nd->Ty))
return evalDouble(Nd);
switch (Nd->Kind) {
case ND_ADD:
return eval2(Nd->LHS, Label) + eval(Nd->RHS);
case ND_SUB:
return eval2(Nd->LHS, Label) - eval(Nd->RHS);
case ND_MUL:
return eval(Nd->LHS) * eval(Nd->RHS);
case ND_DIV:
if (Nd->Ty->IsUnsigned)
return (uint64_t)eval(Nd->LHS) / eval(Nd->RHS);
return eval(Nd->LHS) / eval(Nd->RHS);
case ND_NEG:
return -eval(Nd->LHS);
case ND_MOD:
if (Nd->Ty->IsUnsigned)
return (uint64_t)eval(Nd->LHS) % eval(Nd->RHS);
return eval(Nd->LHS) % eval(Nd->RHS);
case ND_BITAND:
return eval(Nd->LHS) & eval(Nd->RHS);
case ND_BITOR:
return eval(Nd->LHS) | eval(Nd->RHS);
case ND_BITXOR:
return eval(Nd->LHS) ^ eval(Nd->RHS);
case ND_SHL:
return eval(Nd->LHS) << eval(Nd->RHS);
case ND_SHR:
if (Nd->Ty->IsUnsigned && Nd->Ty->Size == 8)
return (uint64_t)eval(Nd->LHS) >> eval(Nd->RHS);
return eval(Nd->LHS) >> eval(Nd->RHS);
case ND_EQ:
return eval(Nd->LHS) == eval(Nd->RHS);
case ND_NE:
return eval(Nd->LHS) != eval(Nd->RHS);
case ND_LT:
if (Nd->LHS->Ty->IsUnsigned)
return (uint64_t)eval(Nd->LHS) < eval(Nd->RHS);
return eval(Nd->LHS) < eval(Nd->RHS);
case ND_LE:
if (Nd->LHS->Ty->IsUnsigned)
return (uint64_t)eval(Nd->LHS) <= eval(Nd->RHS);
return eval(Nd->LHS) <= eval(Nd->RHS);
case ND_COND:
return eval(Nd->Cond) ? eval2(Nd->Then, Label) : eval2(Nd->Els, Label);
case ND_COMMA:
return eval2(Nd->RHS, Label);
case ND_NOT:
return !eval(Nd->LHS);
case ND_BITNOT:
return ~eval(Nd->LHS);
case ND_LOGAND:
return eval(Nd->LHS) && eval(Nd->RHS);
case ND_LOGOR:
return eval(Nd->LHS) || eval(Nd->RHS);
case ND_CAST: {
int64_t Val = eval2(Nd->LHS, Label);
if (isInteger(Nd->Ty)) {
switch (Nd->Ty->Size) {
case 1:
return Nd->Ty->IsUnsigned ? (uint8_t)Val : (int8_t)Val;
case 2:
return Nd->Ty->IsUnsigned ? (uint16_t)Val : (int16_t)Val;
case 4:
return Nd->Ty->IsUnsigned ? (uint32_t)Val : (int32_t)Val;
}
}
return Val;
}
case ND_ADDR:
return evalRVal(Nd->LHS, Label);
case ND_LABEL_VAL:
// 将标签值也作为常量
*Label = &Nd->UniqueLabel;
return 0;
case ND_MEMBER:
// 未开辟Label的地址则表明不是表达式常量
if (!Label)
errorTok(Nd->Tok, "not a compile-time constant");
// 不能为数组
if (Nd->Ty->Kind != TY_ARRAY)
errorTok(Nd->Tok, "invalid initializer");
// 返回左部的值并解析Label加上成员变量的偏移量
return evalRVal(Nd->LHS, Label) + Nd->Mem->Offset;
case ND_VAR:
// 未开辟Label的地址则表明不是表达式常量
if (!Label)
errorTok(Nd->Tok, "not a compile-time constant");
// 不能为数组或者函数
if (Nd->Var->Ty->Kind != TY_ARRAY && Nd->Var->Ty->Kind != TY_FUNC)
errorTok(Nd->Tok, "invalid initializer");
// 将标签值也作为常量
*Label = &Nd->Var->Name;
return 0;
case ND_NUM:
return Nd->Val;
default:
break;
}
errorTok(Nd->Tok, "not a compile-time constant");
return -1;
}
// 计算重定位变量
static int64_t evalRVal(Node *Nd, char ***Label) {
switch (Nd->Kind) {
case ND_VAR:
// 局部变量不能参与全局变量的初始化
if (Nd->Var->IsLocal)
errorTok(Nd->Tok, "not a compile-time constant");
// 将标签值也作为常量
*Label = &Nd->Var->Name;
return 0;
case ND_DEREF:
// 直接进入到解引用的地址
return eval2(Nd->LHS, Label);
case ND_MEMBER:
// 加上成员变量的偏移量
return evalRVal(Nd->LHS, Label) + Nd->Mem->Offset;
default:
break;
}
errorTok(Nd->Tok, "invalid initializer");
return -1;
}
// 判断是否为常量表达式
static bool isConstExpr(Node *Nd) {
addType(Nd);
switch (Nd->Kind) {
case ND_ADD:
case ND_SUB:
case ND_MUL:
case ND_DIV:
case ND_BITAND:
case ND_BITOR:
case ND_BITXOR:
case ND_SHL:
case ND_SHR:
case ND_EQ:
case ND_NE:
case ND_LT:
case ND_LE:
case ND_LOGAND:
case ND_LOGOR:
// 左部右部 都为常量表达式时 为真
return isConstExpr(Nd->LHS) && isConstExpr(Nd->RHS);
case ND_COND:
// 条件不为常量表达式时 为假
if (!isConstExpr(Nd->Cond))
return false;
// 条件为常量表达式时,判断相应分支语句是否为真
return isConstExpr(eval(Nd->Cond) ? Nd->Then : Nd->Els);
case ND_COMMA:
// 判断逗号最右表达式是否为 常量表达式
return isConstExpr(Nd->RHS);
case ND_NEG:
case ND_NOT:
case ND_BITNOT:
case ND_CAST:
// 判断左部是否为常量表达式
return isConstExpr(Nd->LHS);
case ND_NUM:
// 数字恒为常量表达式
return true;
default:
// 其他情况默认为假
return false;
}
}
// 解析常量表达式
int64_t constExpr(Token **Rest, Token *Tok) {
// 进行常量表达式的构造
Node *Nd = conditional(Rest, Tok);
// 进行常量表达式的计算
return eval(Nd);
}
// 解析浮点表达式
static double evalDouble(Node *Nd) {
addType(Nd);
// 处理是整型的情况
if (isInteger(Nd->Ty)) {
if (Nd->Ty->IsUnsigned)
return (unsigned long)eval(Nd);
return eval(Nd);
}
switch (Nd->Kind) {
case ND_ADD:
return evalDouble(Nd->LHS) + evalDouble(Nd->RHS);
case ND_SUB:
return evalDouble(Nd->LHS) - evalDouble(Nd->RHS);
case ND_MUL:
return evalDouble(Nd->LHS) * evalDouble(Nd->RHS);
case ND_DIV:
return evalDouble(Nd->LHS) / evalDouble(Nd->RHS);
case ND_NEG:
return -evalDouble(Nd->LHS);
case ND_COND:
return evalDouble(Nd->Cond) ? evalDouble(Nd->Then) : evalDouble(Nd->Els);
case ND_COMMA:
return evalDouble(Nd->RHS);
case ND_CAST:
if (isFloNum(Nd->LHS->Ty))
return evalDouble(Nd->LHS);
return eval(Nd->LHS);
case ND_NUM:
return Nd->FVal;
default:
errorTok(Nd->Tok, "not a compile-time constant");
return -1;
}
}
// 转换 A op= B为 TMP = &A, *TMP = *TMP op B
// 结构体需要特殊处理
static Node *toAssign(Node *Binary) {
// A
addType(Binary->LHS);
// B
addType(Binary->RHS);
Token *Tok = Binary->Tok;
// 转换 A.X op= B 为 TMP = &A, (*TMP).X = (*TMP).X op B
if (Binary->LHS->Kind == ND_MEMBER) {
// TMP
Obj *Var = newLVar("", pointerTo(Binary->LHS->LHS->Ty));
// TMP = &A
Node *Expr1 = newBinary(ND_ASSIGN, newVarNode(Var, Tok),
newUnary(ND_ADDR, Binary->LHS->LHS, Tok), Tok);
// (*TMP).X op=左边的
Node *Expr2 =
newUnary(ND_MEMBER, newUnary(ND_DEREF, newVarNode(Var, Tok), Tok), Tok);
Expr2->Mem = Binary->LHS->Mem;
// (*TMP).X op=右边的
Node *Expr3 =
newUnary(ND_MEMBER, newUnary(ND_DEREF, newVarNode(Var, Tok), Tok), Tok);
Expr3->Mem = Binary->LHS->Mem;
// (*TMP).X = (*TMP).X op B
Node *Expr4 =
newBinary(ND_ASSIGN, Expr2,
newBinary(Binary->Kind, Expr3, Binary->RHS, Tok), Tok);
// TMP = &A, (*TMP).X = (*TMP).X op B
return newBinary(ND_COMMA, Expr1, Expr4, Tok);
}
// 如果 A 是原子的类型,那么 `A op= B` 被转换为
//
// ({
// T1 *Addr = &A; T2 Val = (B); T1 Old = *Addr; T1 New;
// do {
// New = Old op Val;
// } while (!atomic_compare_exchange_strong(Addr, &Old, New));
// New;
// })
if (Binary->LHS->Ty->IsAtomic) {
Node Head = {};
Node *Cur = &Head;
Obj *Addr = newLVar("", pointerTo(Binary->LHS->Ty));
Obj *Val = newLVar("", Binary->RHS->Ty);
Obj *Old = newLVar("", Binary->LHS->Ty);
Obj *New = newLVar("", Binary->LHS->Ty);
// T1 *Addr = &A;
Cur = Cur->Next =
newUnary(ND_EXPR_STMT,
newBinary(ND_ASSIGN, newVarNode(Addr, Tok),
newUnary(ND_ADDR, Binary->LHS, Tok), Tok),
Tok);
// T2 Val = (B);
Cur = Cur->Next = newUnary(
ND_EXPR_STMT,
newBinary(ND_ASSIGN, newVarNode(Val, Tok), Binary->RHS, Tok), Tok);
// T1 Old = *Addr;
Cur = Cur->Next =
newUnary(ND_EXPR_STMT,
newBinary(ND_ASSIGN, newVarNode(Old, Tok),
newUnary(ND_DEREF, newVarNode(Addr, Tok), Tok), Tok),
Tok);
// do {
// New = Old op Val;
// }
Node *Loop = newNode(ND_DO, Tok);
Loop->BrkLabel = newUniqueName();
Loop->ContLabel = newUniqueName();
// New = Old op Val;
Node *Body = newBinary(ND_ASSIGN, newVarNode(New, Tok),
newBinary(Binary->Kind, newVarNode(Old, Tok),
newVarNode(Val, Tok), Tok),
Tok);
Loop->Then = newNode(ND_BLOCK, Tok);
Loop->Then->Body = newUnary(ND_EXPR_STMT, Body, Tok);
// !atomic_compare_exchange_strong(Addr, &Old, New)
Node *Cas = newNode(ND_CAS, Tok);
Cas->CasAddr = newVarNode(Addr, Tok);
Cas->CasOld = newUnary(ND_ADDR, newVarNode(Old, Tok), Tok);
Cas->CasNew = newVarNode(New, Tok);
Loop->Cond = newUnary(ND_NOT, Cas, Tok);
// while (!atomic_compare_exchange_strong(Addr, &Old, New));
Cur = Cur->Next = Loop;
Cur = Cur->Next = newUnary(ND_EXPR_STMT, newVarNode(New, Tok), Tok);
Node *Nd = newNode(ND_STMT_EXPR, Tok);
Nd->Body = Head.Next;
return Nd;
}
// 转换 A op= B为 TMP = &A, *TMP = *TMP op B
// TMP
Obj *Var = newLVar("", pointerTo(Binary->LHS->Ty));
// TMP = &A
Node *Expr1 = newBinary(ND_ASSIGN, newVarNode(Var, Tok),
newUnary(ND_ADDR, Binary->LHS, Tok), Tok);
// *TMP = *TMP op B
Node *Expr2 = newBinary(
ND_ASSIGN, newUnary(ND_DEREF, newVarNode(Var, Tok), Tok),
newBinary(Binary->Kind, newUnary(ND_DEREF, newVarNode(Var, Tok), Tok),
Binary->RHS, Tok),
Tok);
// TMP = &A, *TMP = *TMP op B
return newBinary(ND_COMMA, Expr1, Expr2, Tok);
}
// 解析赋值
// assign = conditional (assignOp assign)?
// assignOp = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^="
// | "<<=" | ">>="
static Node *assign(Token **Rest, Token *Tok) {
// conditional
Node *Nd = conditional(&Tok, Tok);
// 可能存在递归赋值如a=b=1
// ("=" assign)?
if (equal(Tok, "="))
return Nd = newBinary(ND_ASSIGN, Nd, assign(Rest, Tok->Next), Tok);
// ("+=" assign)?
if (equal(Tok, "+="))
return toAssign(newAdd(Nd, assign(Rest, Tok->Next), Tok));
// ("-=" assign)?
if (equal(Tok, "-="))
return toAssign(newSub(Nd, assign(Rest, Tok->Next), Tok));
// ("*=" assign)?
if (equal(Tok, "*="))
return toAssign(newBinary(ND_MUL, Nd, assign(Rest, Tok->Next), Tok));
// ("/=" assign)?
if (equal(Tok, "/="))
return toAssign(newBinary(ND_DIV, Nd, assign(Rest, Tok->Next), Tok));
// ("%=" assign)?
if (equal(Tok, "%="))
return toAssign(newBinary(ND_MOD, Nd, assign(Rest, Tok->Next), Tok));
// ("&=" assign)?
if (equal(Tok, "&="))
return toAssign(newBinary(ND_BITAND, Nd, assign(Rest, Tok->Next), Tok));
// ("|=" assign)?
if (equal(Tok, "|="))
return toAssign(newBinary(ND_BITOR, Nd, assign(Rest, Tok->Next), Tok));
// ("^=" assign)?
if (equal(Tok, "^="))
return toAssign(newBinary(ND_BITXOR, Nd, assign(Rest, Tok->Next), Tok));
// ("<<=" assign)?
if (equal(Tok, "<<="))
return toAssign(newBinary(ND_SHL, Nd, assign(Rest, Tok->Next), Tok));
// (">>=" assign)?
if (equal(Tok, ">>="))
return toAssign(newBinary(ND_SHR, Nd, assign(Rest, Tok->Next), Tok));
*Rest = Tok;
return Nd;
}
// 解析条件运算符
// conditional = logOr ("?" expr? ":" conditional)?
static Node *conditional(Token **Rest, Token *Tok) {
// logOr
Node *Cond = logOr(&Tok, Tok);
// "?"
if (!equal(Tok, "?")) {
*Rest = Tok;
return Cond;
}
// "?" ":"
if (equal(Tok->Next, ":")) {
// `A ?: B` 等价于 `Tmp = A, Tmp ? Tmp : B`
addType(Cond);
// Tmp
Obj *Var = newLVar("", Cond->Ty);
// Tmp = A
Node *LHS = newBinary(ND_ASSIGN, newVarNode(Var, Tok), Cond, Tok);
// Tmp ? Tmp : B
Node *RHS = newNode(ND_COND, Tok);
RHS->Cond = newVarNode(Var, Tok);
RHS->Then = newVarNode(Var, Tok);
RHS->Els = conditional(Rest, Tok->Next->Next);
// Tmp = A, Tmp ? Tmp : B
return newBinary(ND_COMMA, LHS, RHS, Tok);
}
// expr ":" conditional
Node *Nd = newNode(ND_COND, Tok);
Nd->Cond = Cond;
// expr ":"
Nd->Then = expr(&Tok, Tok->Next);
Tok = skip(Tok, ":");
// conditional这里不能被解析为赋值式
Nd->Els = conditional(Rest, Tok);
return Nd;
}
// 逻辑或
// logOr = logAnd ("||" logAnd)*
static Node *logOr(Token **Rest, Token *Tok) {
Node *Nd = logAnd(&Tok, Tok);
while (equal(Tok, "||")) {
Token *Start = Tok;
Nd = newBinary(ND_LOGOR, Nd, logAnd(&Tok, Tok->Next), Start);
}
*Rest = Tok;
return Nd;
}
// 逻辑与
// logAnd = bitOr ("&&" bitOr)*
static Node *logAnd(Token **Rest, Token *Tok) {
Node *Nd = bitOr(&Tok, Tok);
while (equal(Tok, "&&")) {
Token *Start = Tok;
Nd = newBinary(ND_LOGAND, Nd, bitOr(&Tok, Tok->Next), Start);
}
*Rest = Tok;
return Nd;
}
// 按位或
// bitOr = bitXor ("|" bitXor)*
static Node *bitOr(Token **Rest, Token *Tok) {
Node *Nd = bitXor(&Tok, Tok);
while (equal(Tok, "|")) {
Token *Start = Tok;
Nd = newBinary(ND_BITOR, Nd, bitXor(&Tok, Tok->Next), Start);
}
*Rest = Tok;
return Nd;
}
// 按位异或
// bitXor = bitAnd ("^" bitAnd)*
static Node *bitXor(Token **Rest, Token *Tok) {
Node *Nd = bitAnd(&Tok, Tok);
while (equal(Tok, "^")) {
Token *Start = Tok;
Nd = newBinary(ND_BITXOR, Nd, bitAnd(&Tok, Tok->Next), Start);
}
*Rest = Tok;
return Nd;
}
// 按位与
// bitAnd = equality ("&" equality)*
static Node *bitAnd(Token **Rest, Token *Tok) {
Node *Nd = equality(&Tok, Tok);
while (equal(Tok, "&")) {
Token *Start = Tok;
Nd = newBinary(ND_BITAND, Nd, equality(&Tok, Tok->Next), Start);
}
*Rest = Tok;
return Nd;
}
// 解析相等性
// equality = relational ("==" relational | "!=" relational)*
static Node *equality(Token **Rest, Token *Tok) {
// relational
Node *Nd = relational(&Tok, Tok);
// ("==" relational | "!=" relational)*
while (true) {
Token *Start = Tok;
// "==" relational
if (equal(Tok, "==")) {
Nd = newBinary(ND_EQ, Nd, relational(&Tok, Tok->Next), Start);
continue;
}
// "!=" relational
if (equal(Tok, "!=")) {
Nd = newBinary(ND_NE, Nd, relational(&Tok, Tok->Next), Start);
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析比较关系
// relational = shift ("<" shift | "<=" shift | ">" shift | ">=" shift)*
static Node *relational(Token **Rest, Token *Tok) {
// shift
Node *Nd = shift(&Tok, Tok);
// ("<" shift | "<=" shift | ">" shift | ">=" shift)*
while (true) {
Token *Start = Tok;
// "<" shift
if (equal(Tok, "<")) {
Nd = newBinary(ND_LT, Nd, shift(&Tok, Tok->Next), Start);
continue;
}
// "<=" shift
if (equal(Tok, "<=")) {
Nd = newBinary(ND_LE, Nd, shift(&Tok, Tok->Next), Start);
continue;
}
// ">" shift
// X>Y等价于Y<X
if (equal(Tok, ">")) {
Nd = newBinary(ND_LT, shift(&Tok, Tok->Next), Nd, Start);
continue;
}
// ">=" shift
// X>=Y等价于Y<=X
if (equal(Tok, ">=")) {
Nd = newBinary(ND_LE, shift(&Tok, Tok->Next), Nd, Start);
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析位移
// shift = add ("<<" add | ">>" add)*
static Node *shift(Token **Rest, Token *Tok) {
// add
Node *Nd = add(&Tok, Tok);
while (true) {
Token *Start = Tok;
// "<<" add
if (equal(Tok, "<<")) {
Nd = newBinary(ND_SHL, Nd, add(&Tok, Tok->Next), Start);
continue;
}
// ">>" add
if (equal(Tok, ">>")) {
Nd = newBinary(ND_SHR, Nd, add(&Tok, Tok->Next), Start);
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析各种加法
static Node *newAdd(Node *LHS, Node *RHS, Token *Tok) {
// 为左右部添加类型
addType(LHS);
addType(RHS);
// num + num
if (isNumeric(LHS->Ty) && isNumeric(RHS->Ty))
return newBinary(ND_ADD, LHS, RHS, Tok);
// 不能解析 ptr + ptr
if (LHS->Ty->Base && RHS->Ty->Base)
errorTok(Tok, "invalid operands");
// 将 num + ptr 转换为 ptr + num
if (!LHS->Ty->Base && RHS->Ty->Base) {
Node *Tmp = LHS;
LHS = RHS;
RHS = Tmp;
}
// VLA + num
// 指针加法需要num×VLASize操作
if (LHS->Ty->Base->Kind == TY_VLA) {
RHS = newBinary(ND_MUL, RHS, newVarNode(LHS->Ty->Base->VLASize, Tok), Tok);
return newBinary(ND_ADD, LHS, RHS, Tok);
}
// ptr + num
// 指针加法ptr+11不是1个字节而是1个元素的空间所以需要×Size操作
// 指针用long类型存储
RHS = newBinary(ND_MUL, RHS, newLong(LHS->Ty->Base->Size, Tok), Tok);
return newBinary(ND_ADD, LHS, RHS, Tok);
}
// 解析各种减法
static Node *newSub(Node *LHS, Node *RHS, Token *Tok) {
// 为左右部添加类型
addType(LHS);
addType(RHS);
// num - num
if (isNumeric(LHS->Ty) && isNumeric(RHS->Ty))
return newBinary(ND_SUB, LHS, RHS, Tok);
// ptr - num
if (LHS->Ty->Base && isInteger(RHS->Ty)) {
// 指针用long类型存储
RHS = newBinary(ND_MUL, RHS, newLong(LHS->Ty->Base->Size, Tok), Tok);
addType(RHS);
Node *Nd = newBinary(ND_SUB, LHS, RHS, Tok);
// 节点类型为指针
Nd->Ty = LHS->Ty;
return Nd;
}
// ptr - ptr返回两指针间有多少元素
if (LHS->Ty->Base && RHS->Ty->Base) {
Node *Nd = newBinary(ND_SUB, LHS, RHS, Tok);
Nd->Ty = TyLong;
return newBinary(ND_DIV, Nd, newNum(LHS->Ty->Base->Size, Tok), Tok);
}
errorTok(Tok, "invalid operands");
return NULL;
}
// 解析加减
// add = mul ("+" mul | "-" mul)*
static Node *add(Token **Rest, Token *Tok) {
// mul
Node *Nd = mul(&Tok, Tok);
// ("+" mul | "-" mul)*
while (true) {
Token *Start = Tok;
// "+" mul
if (equal(Tok, "+")) {
Nd = newAdd(Nd, mul(&Tok, Tok->Next), Start);
continue;
}
// "-" mul
if (equal(Tok, "-")) {
Nd = newSub(Nd, mul(&Tok, Tok->Next), Start);
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析乘除
// mul = cast ("*" cast | "/" cast | "%" cast)*
static Node *mul(Token **Rest, Token *Tok) {
// cast
Node *Nd = cast(&Tok, Tok);
// ("*" cast | "/" cast | "%" cast)*
while (true) {
Token *Start = Tok;
// "*" cast
if (equal(Tok, "*")) {
Nd = newBinary(ND_MUL, Nd, cast(&Tok, Tok->Next), Start);
continue;
}
// "/" cast
if (equal(Tok, "/")) {
Nd = newBinary(ND_DIV, Nd, cast(&Tok, Tok->Next), Start);
continue;
}
// "%" cast
if (equal(Tok, "%")) {
Nd = newBinary(ND_MOD, Nd, cast(&Tok, Tok->Next), Start);
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析类型转换
// cast = "(" typeName ")" cast | unary
static Node *cast(Token **Rest, Token *Tok) {
// cast = "(" typeName ")" cast
if (equal(Tok, "(") && isTypename(Tok->Next)) {
Token *Start = Tok;
Type *Ty = typename(&Tok, Tok->Next);
Tok = skip(Tok, ")");
// 复合字面量
if (equal(Tok, "{"))
return unary(Rest, Start);
// 解析嵌套的类型转换
Node *Nd = newCast(cast(Rest, Tok), Ty);
Nd->Tok = Start;
return Nd;
}
// unary
return unary(Rest, Tok);
}
// 解析一元运算
// unary = ("+" | "-" | "*" | "&" | "!" | "~") cast
// | ("++" | "--") unary
// | "&&" ident
// | postfix
static Node *unary(Token **Rest, Token *Tok) {
// "+" cast
if (equal(Tok, "+"))
return cast(Rest, Tok->Next);
// "-" cast
if (equal(Tok, "-"))
return newUnary(ND_NEG, cast(Rest, Tok->Next), Tok);
// "&" cast
if (equal(Tok, "&")) {
Node *LHS = cast(Rest, Tok->Next);
addType(LHS);
// 不能够获取位域的地址
if (LHS->Kind == ND_MEMBER && LHS->Mem->IsBitfield)
errorTok(Tok, "cannot take address of bitfield");
return newUnary(ND_ADDR, LHS, Tok);
}
// "*" cast
if (equal(Tok, "*")) {
Node *Nd = cast(Rest, Tok->Next);
addType(Nd);
// 如果func是函数那么*func等价于func
if (Nd->Ty->Kind == TY_FUNC)
return Nd;
return newUnary(ND_DEREF, Nd, Tok);
}
// "!" cast
if (equal(Tok, "!"))
return newUnary(ND_NOT, cast(Rest, Tok->Next), Tok);
// "~" cast
if (equal(Tok, "~"))
return newUnary(ND_BITNOT, cast(Rest, Tok->Next), Tok);
// 转换 ++i 为 i+=1
// "++" unary
if (equal(Tok, "++"))
return toAssign(newAdd(unary(Rest, Tok->Next), newNum(1, Tok), Tok));
// 转换 +-i 为 i-=1
// "--" unary
if (equal(Tok, "--"))
return toAssign(newSub(unary(Rest, Tok->Next), newNum(1, Tok), Tok));
// GOTO的标签作为值
if (equal(Tok, "&&")) {
Node *Nd = newNode(ND_LABEL_VAL, Tok);
Nd->Label = getIdent(Tok->Next);
// 将Nd同时存入Gotos最后用于解析UniqueLabel
Nd->GotoNext = Gotos;
Gotos = Nd;
*Rest = Tok->Next->Next;
return Nd;
}
// postfix
return postfix(Rest, Tok);
}
// structMembers = (declspec declarator ("," declarator)* ";")*
static void structMembers(Token **Rest, Token *Tok, Type *Ty) {
Member Head = {};
Member *Cur = &Head;
// 记录成员变量的索引值
int Idx = 0;
while (!equal(Tok, "}")) {
// declspec
VarAttr Attr = {};
Type *BaseTy = declspec(&Tok, Tok, &Attr);
int First = true;
// 匿名的结构体成员
if ((BaseTy->Kind == TY_STRUCT || BaseTy->Kind == TY_UNION) &&
consume(&Tok, Tok, ";")) {
Member *Mem = calloc(1, sizeof(Member));
Mem->Ty = BaseTy;
Mem->Idx = Idx++;
// 如果对齐值不存在,则使用匿名成员的对齐值
Mem->Align = Attr.Align ? Attr.Align : Mem->Ty->Align;
Cur = Cur->Next = Mem;
continue;
}
// 常规结构体成员
while (!consume(&Tok, Tok, ";")) {
if (!First)
Tok = skip(Tok, ",");
First = false;
Member *Mem = calloc(1, sizeof(Member));
// declarator
Mem->Ty = declarator(&Tok, Tok, BaseTy);
Mem->Name = Mem->Ty->Name;
// 成员变量对应的索引值
Mem->Idx = Idx++;
// 设置对齐值
Mem->Align = Attr.Align ? Attr.Align : Mem->Ty->Align;
// 位域成员赋值
if (consume(&Tok, Tok, ":")) {
Mem->IsBitfield = true;
Mem->BitWidth = constExpr(&Tok, Tok);
}
Cur = Cur->Next = Mem;
}
}
// 解析灵活数组成员数组大小设为0
if (Cur != &Head && Cur->Ty->Kind == TY_ARRAY && Cur->Ty->ArrayLen < 0) {
Cur->Ty = arrayOf(Cur->Ty->Base, 0);
// 设置类型为灵活的
Ty->IsFlexible = true;
}
*Rest = Tok->Next;
Ty->Mems = Head.Next;
}
// attribute = ("__attribute__" "(" "(" ("packed")
// | ("aligned" "(" N ")") ")" ")")*
static Token *attributeList(Token *Tok, Type *Ty) {
// 解析__attribute__相关的属性
while (consume(&Tok, Tok, "__attribute__")) {
Tok = skip(Tok, "(");
Tok = skip(Tok, "(");
bool First = true;
while (!consume(&Tok, Tok, ")")) {
if (!First)
Tok = skip(Tok, ",");
First = false;
// "packed"
if (consume(&Tok, Tok, "packed")) {
Ty->IsPacked = true;
continue;
}
// "aligned" "(" N ")"
if (consume(&Tok, Tok, "aligned")) {
Tok = skip(Tok, "(");
Ty->Align = constExpr(&Tok, Tok);
Tok = skip(Tok, ")");
continue;
}
errorTok(Tok, "unknown attribute");
}
Tok = skip(Tok, ")");
}
return Tok;
}
// structUnionDecl = attribute? ident? ("{" structMembers)?
static Type *structUnionDecl(Token **Rest, Token *Tok) {
// 构造结构体类型
Type *Ty = structType();
// 设置相关属性
Tok = attributeList(Tok, Ty);
// 读取标签
Token *Tag = NULL;
if (Tok->Kind == TK_IDENT) {
Tag = Tok;
Tok = Tok->Next;
}
// 构造不完整结构体
if (Tag && !equal(Tok, "{")) {
*Rest = Tok;
Type *Ty2 = findTag(Tag);
if (Ty2)
return Ty2;
Ty->Size = -1;
pushTagScope(Tag, Ty);
return Ty;
}
// ("{" structMembers)?
Tok = skip(Tok, "{");
// 构造一个结构体
structMembers(&Tok, Tok, Ty);
*Rest = attributeList(Tok, Ty);
// 如果是重复定义,就覆盖之前的定义。否则有名称就注册结构体类型
if (Tag) {
Type *Ty2 = hashmapGet2(&Scp->Tags, Tag->Loc, Tag->Len);
if (Ty2) {
*Ty2 = *Ty;
return Ty2;
}
pushTagScope(Tag, Ty);
}
return Ty;
}
// structDecl = structUnionDecl
static Type *structDecl(Token **Rest, Token *Tok) {
Type *Ty = structUnionDecl(Rest, Tok);
Ty->Kind = TY_STRUCT;
// 不完整结构体
if (Ty->Size < 0)
return Ty;
// 计算结构体内成员的偏移量
int Bits = 0;
// 遍历成员
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
if (Mem->IsBitfield && Mem->BitWidth == 0) {
// 零宽度的位域有特殊含义,仅作用于对齐
Bits = alignTo(Bits, Mem->Ty->Size * 8);
} else if (Mem->IsBitfield) {
// 位域成员变量
int Sz = Mem->Ty->Size;
// Bits此时对应成员最低位Bits + Mem->BitWidth - 1对应成员最高位
// 二者若不相等,则说明当前这个类型剩余的空间存不下,需要新开辟空间
if (Bits / (Sz * 8) != (Bits + Mem->BitWidth - 1) / (Sz * 8))
// 新开辟一个当前当前类型的空间
Bits = alignTo(Bits, Sz * 8);
// 若当前字节能够存下,则向下对齐,得到成员变量的偏移量
Mem->Offset = alignDown(Bits / 8, Sz);
Mem->BitOffset = Bits % (Sz * 8);
Bits += Mem->BitWidth;
} else {
// 常规结构体成员变量
if (!Ty->IsPacked)
Bits = alignTo(Bits, Mem->Align * 8);
Mem->Offset = Bits / 8;
Bits += Mem->Ty->Size * 8;
}
// 类型的对齐值,不小于当前成员变量的对齐值
if (!Ty->IsPacked && Ty->Align < Mem->Align)
Ty->Align = Mem->Align;
}
// 结构体的大小
Ty->Size = alignTo(Bits, Ty->Align * 8) / 8;
return Ty;
}
// unionDecl = structUnionDecl
static Type *unionDecl(Token **Rest, Token *Tok) {
Type *Ty = structUnionDecl(Rest, Tok);
Ty->Kind = TY_UNION;
// 联合体需要设置为最大的对齐量与大小变量偏移量都默认为0
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
if (Ty->Align < Mem->Align)
Ty->Align = Mem->Align;
if (Ty->Size < Mem->Ty->Size)
Ty->Size = Mem->Ty->Size;
}
// 将大小对齐
Ty->Size = alignTo(Ty->Size, Ty->Align);
return Ty;
}
// 获取结构体成员
static Member *getStructMember(Type *Ty, Token *Tok) {
for (Member *Mem = Ty->Mems; Mem; Mem = Mem->Next) {
// 匿名结构体成员,可以由上一级的结构体进行访问
if ((Mem->Ty->Kind == TY_STRUCT || Mem->Ty->Kind == TY_UNION) &&
!Mem->Name) {
if (getStructMember(Mem->Ty, Tok))
return Mem;
continue;
}
// 常规结构体成员
if (Mem->Name->Len == Tok->Len &&
!strncmp(Mem->Name->Loc, Tok->Loc, Tok->Len))
return Mem;
}
return NULL;
}
// 构建结构体成员的节点
// 匿名结构体成员,可以由上一级的结构体进行访问
static Node *structRef(Node *Nd, Token *Tok) {
addType(Nd);
if (Nd->Ty->Kind != TY_STRUCT && Nd->Ty->Kind != TY_UNION)
errorTok(Nd->Tok, "not a struct nor a union");
// 节点类型
Type *Ty = Nd->Ty;
// 遍历匿名的成员,直到匹配到具名的
while (true) {
// 获取结构体成员
Member *Mem = getStructMember(Ty, Tok);
if (!Mem)
errorTok(Tok, "no such member");
// 构造成员节点
Nd = newUnary(ND_MEMBER, Nd, Tok);
Nd->Mem = Mem;
// 判断是否具名
if (Mem->Name)
break;
// 继续遍历匿名成员的成员
Ty = Mem->Ty;
}
return Nd;
}
// 转换 A++ 为 `(typeof A)((A += 1) - 1)`
// Increase Decrease
static Node *newIncDec(Node *Nd, Token *Tok, int Addend) {
addType(Nd);
return newCast(newAdd(toAssign(newAdd(Nd, newNum(Addend, Tok), Tok)),
newNum(-Addend, Tok), Tok),
Nd->Ty);
}
// postfix = "(" typeName ")" "{" initializerList "}"
// = ident "(" funcArgs ")" postfixTail*
// | primary postfixTail*
//
// postfixTail = "[" expr "]"
// | "(" funcArgs ")"
// | "." ident
// | "->" ident
// | "++"
// | "--"
static Node *postfix(Token **Rest, Token *Tok) {
// "(" typeName ")" "{" initializerList "}"
if (equal(Tok, "(") && isTypename(Tok->Next)) {
// 复合字面量
Token *Start = Tok;
Type *Ty = typename(&Tok, Tok->Next);
Tok = skip(Tok, ")");
if (Scp->Next == NULL) {
Obj *Var = newAnonGVar(Ty);
GVarInitializer(Rest, Tok, Var);
return newVarNode(Var, Start);
}
Obj *Var = newLVar("", Ty);
Node *LHS = LVarInitializer(Rest, Tok, Var);
Node *RHS = newVarNode(Var, Tok);
return newBinary(ND_COMMA, LHS, RHS, Start);
}
// primary
Node *Nd = primary(&Tok, Tok);
// ("[" expr "]")*
while (true) {
// ident "(" funcArgs ")"
// 匹配到函数调用
if (equal(Tok, "(")) {
Nd = funCall(&Tok, Tok->Next, Nd);
continue;
}
if (equal(Tok, "[")) {
// x[y] 等价于 *(x+y)
Token *Start = Tok;
Node *Idx = expr(&Tok, Tok->Next);
Tok = skip(Tok, "]");
Nd = newUnary(ND_DEREF, newAdd(Nd, Idx, Start), Start);
continue;
}
// "." ident
if (equal(Tok, ".")) {
Nd = structRef(Nd, Tok->Next);
Tok = Tok->Next->Next;
continue;
}
// "->" ident
if (equal(Tok, "->")) {
// x->y 等价于 (*x).y
Nd = newUnary(ND_DEREF, Nd, Tok);
Nd = structRef(Nd, Tok->Next);
Tok = Tok->Next->Next;
continue;
}
if (equal(Tok, "++")) {
Nd = newIncDec(Nd, Tok, 1);
Tok = Tok->Next;
continue;
}
if (equal(Tok, "--")) {
Nd = newIncDec(Nd, Tok, -1);
Tok = Tok->Next;
continue;
}
*Rest = Tok;
return Nd;
}
}
// 解析函数调用
// funcall = (assign ("," assign)*)? ")"
static Node *funCall(Token **Rest, Token *Tok, Node *Fn) {
addType(Fn);
// 检查函数指针
if (Fn->Ty->Kind != TY_FUNC &&
(Fn->Ty->Kind != TY_PTR || Fn->Ty->Base->Kind != TY_FUNC))
errorTok(Fn->Tok, "not a function");
// 处理函数的类型设为非指针的类型
Type *Ty = (Fn->Ty->Kind == TY_FUNC) ? Fn->Ty : Fn->Ty->Base;
// 函数形参的类型
Type *ParamTy = Ty->Params;
Node Head = {};
Node *Cur = &Head;
while (!equal(Tok, ")")) {
if (Cur != &Head)
Tok = skip(Tok, ",");
// assign
Node *Arg = assign(&Tok, Tok);
addType(Arg);
if (ParamTy) {
if (ParamTy->Kind != TY_STRUCT && ParamTy->Kind != TY_UNION)
// 将参数节点的类型进行转换
Arg = newCast(Arg, ParamTy);
// 前进到下一个形参类型
ParamTy = ParamTy->Next;
} else if (Arg->Ty->Kind == TY_FLOAT) {
// 若无形参类型浮点数会被提升为double
Arg = newCast(Arg, TyDouble);
}
// 对参数进行存储
Cur->Next = Arg;
Cur = Cur->Next;
addType(Cur);
}
*Rest = skip(Tok, ")");
// 构造一个函数调用的节点
Node *Nd = newUnary(ND_FUNCALL, Fn, Tok);
// 函数类型
Nd->FuncType = Ty;
// 读取的返回类型
Nd->Ty = Ty->ReturnTy;
Nd->Args = Head.Next;
// 如果函数返回值是结构体,那么调用者需为返回值开辟一块空间
if (Nd->Ty->Kind == TY_STRUCT || Nd->Ty->Kind == TY_UNION)
Nd->RetBuffer = newLVar("", Nd->Ty);
return Nd;
}
// genericSelection = "(" assign "," genericAssoc ("," genericAssoc)* ")"
//
// genericAssoc = typeName ":" assign
// | "default" ":" assign
// 泛型选择
static Node *genericSelection(Token **Rest, Token *Tok) {
Token *Start = Tok;
// "("
Tok = skip(Tok, "(");
// assign
// 泛型控制选择的值
Node *Ctrl = assign(&Tok, Tok);
addType(Ctrl);
// 获取控制选择的值类型
Type *T1 = Ctrl->Ty;
// 函数转换为函数指针
if (T1->Kind == TY_FUNC)
T1 = pointerTo(T1);
// 数组转换为数组指针
else if (T1->Kind == TY_ARRAY)
T1 = pointerTo(T1->Base);
// 泛型返回的结果值
Node *Ret = NULL;
// "," genericAssoc ("," genericAssoc)*
while (!consume(Rest, Tok, ")")) {
Tok = skip(Tok, ",");
// 默认类型及其对应的值
// "default" ":" assign
if (equal(Tok, "default")) {
Tok = skip(Tok->Next, ":");
Node *Nd = assign(&Tok, Tok);
if (!Ret)
Ret = Nd;
continue;
}
// 各个类型及其对应的值
// typeName ":" assign
Type *T2 = typename(&Tok, Tok);
Tok = skip(Tok, ":");
Node *Nd = assign(&Tok, Tok);
// 判断类型是否与控制选择的值类型相同
if (isCompatible(T1, T2))
Ret = Nd;
}
if (!Ret)
errorTok(Start, "controlling expression type not compatible with"
" any generic association type");
// 返回泛型最后的值
return Ret;
}
// 解析括号、数字、变量
// primary = "(" "{" stmt+ "}" ")"
// | "(" expr ")"
// | "sizeof" "(" typeName ")"
// | "sizeof" unary
// | "_Alignof" "(" typeName ")"
// | "_Alignof" unary
// | "_Generic" genericSelection
// | "__builtin_types_compatible_p" "(" typeName, typeName, ")"
// | ident
// | str
// | num
static Node *primary(Token **Rest, Token *Tok) {
Token *Start = Tok;
// "(" "{" stmt+ "}" ")"
if (equal(Tok, "(") && equal(Tok->Next, "{")) {
// This is a GNU statement expresssion.
Node *Nd = newNode(ND_STMT_EXPR, Tok);
Nd->Body = compoundStmt(&Tok, Tok->Next->Next)->Body;
*Rest = skip(Tok, ")");
return Nd;
}
// "(" expr ")"
if (equal(Tok, "(")) {
Node *Nd = expr(&Tok, Tok->Next);
*Rest = skip(Tok, ")");
return Nd;
}
// "sizeof" "(" typeName ")"
if (equal(Tok, "sizeof") && equal(Tok->Next, "(") &&
isTypename(Tok->Next->Next)) {
Type *Ty = typename(&Tok, Tok->Next->Next);
*Rest = skip(Tok, ")");
// sizeof 可变长度数组的大小
if (Ty->Kind == TY_VLA) {
// 对于变量的sizeof操作
if (Ty->VLASize)
return newVarNode(Ty->VLASize, Tok);
// 对于VLA类型的sizeof操作
// 获取VLA类型的VLASize
Node *LHS = computeVLASize(Ty, Tok);
Node *RHS = newVarNode(Ty->VLASize, Tok);
return newBinary(ND_COMMA, LHS, RHS, Tok);
}
return newULong(Ty->Size, Start);
}
// "sizeof" unary
if (equal(Tok, "sizeof")) {
Node *Nd = unary(Rest, Tok->Next);
addType(Nd);
// sizeof 可变长度数组的大小
if (Nd->Ty->Kind == TY_VLA)
return newVarNode(Nd->Ty->VLASize, Tok);
return newULong(Nd->Ty->Size, Tok);
}
// "_Alignof" "(" typeName ")"
// 读取类型的对齐值
if (equal(Tok, "_Alignof") && equal(Tok->Next, "(") &&
isTypename(Tok->Next->Next)) {
Type *Ty = typename(&Tok, Tok->Next->Next);
*Rest = skip(Tok, ")");
return newULong(Ty->Align, Tok);
}
// "_Alignof" unary
// 读取变量的对齐值
if (equal(Tok, "_Alignof")) {
Node *Nd = unary(Rest, Tok->Next);
addType(Nd);
return newULong(Nd->Ty->Align, Tok);
}
// "_Generic" genericSelection
// 进入到泛型的解析
if (equal(Tok, "_Generic"))
return genericSelection(Rest, Tok->Next);
// "__builtin_types_compatible_p" "(" typeName, typeName, ")"
// 匹配内建的类型兼容性函数
if (equal(Tok, "__builtin_types_compatible_p")) {
Tok = skip(Tok->Next, "(");
// 类型1
Type *T1 = typename(&Tok, Tok);
Tok = skip(Tok, ",");
// 类型2
Type *T2 = typename(&Tok, Tok);
*Rest = skip(Tok, ")");
// 返回二者兼容检查函数的结果
return newNum(isCompatible(T1, T2), Start);
}
// 原子比较交换
if (equal(Tok, "__builtin_compare_and_swap")) {
Node *Nd = newNode(ND_CAS, Tok);
Tok = skip(Tok->Next, "(");
Nd->CasAddr = assign(&Tok, Tok);
Tok = skip(Tok, ",");
Nd->CasOld = assign(&Tok, Tok);
Tok = skip(Tok, ",");
Nd->CasNew = assign(&Tok, Tok);
*Rest = skip(Tok, ")");
return Nd;
}
// 原子交换
if (equal(Tok, "__builtin_atomic_exchange")) {
Node *Nd = newNode(ND_EXCH, Tok);
Tok = skip(Tok->Next, "(");
Nd->LHS = assign(&Tok, Tok);
Tok = skip(Tok, ",");
Nd->RHS = assign(&Tok, Tok);
*Rest = skip(Tok, ")");
return Nd;
}
// ident
if (Tok->Kind == TK_IDENT) {
// 查找变量(或枚举常量)
VarScope *S = findVar(Tok);
*Rest = Tok->Next;
// 用于static inline函数
// 变量存在且为函数
if (S && S->Var && S->Var->IsFunction) {
if (CurrentFn)
// 如果函数体内存在其他函数,则记录引用的其他函数
strArrayPush(&CurrentFn->Refs, S->Var->Name);
else
// 标记为根函数
S->Var->IsRoot = true;
}
if (S) {
// 是否为变量
if (S->Var)
return newVarNode(S->Var, Tok);
// 否则为枚举常量
if (S->EnumTy)
return newNum(S->EnumVal, Tok);
}
if (equal(Tok->Next, "("))
errorTok(Tok, "implicit declaration of a function");
errorTok(Tok, "undefined variable");
}
// str
if (Tok->Kind == TK_STR) {
Obj *Var = newStringLiteral(Tok->Str, Tok->Ty);
*Rest = Tok->Next;
return newVarNode(Var, Tok);
}
// num
if (Tok->Kind == TK_NUM) {
Node *Nd;
if (isFloNum(Tok->Ty)) {
// 浮点数节点
Nd = newNode(ND_NUM, Tok);
Nd->FVal = Tok->FVal;
} else {
// 整型节点
Nd = newNum(Tok->Val, Tok);
}
// 设置类型为终结符的类型
Nd->Ty = Tok->Ty;
*Rest = Tok->Next;
return Nd;
}
errorTok(Tok, "expected an expression");
return NULL;
}
// 解析类型别名
static Token *parseTypedef(Token *Tok, Type *BaseTy) {
bool First = true;
while (!consume(&Tok, Tok, ";")) {
if (!First)
Tok = skip(Tok, ",");
First = false;
Type *Ty = declarator(&Tok, Tok, BaseTy);
if (!Ty->Name)
errorTok(Ty->NamePos, "typedef name omitted");
// 类型别名的变量名存入变量域中,并设置类型
pushScope(getIdent(Ty->Name))->Typedef = Ty;
}
return Tok;
}
// 将形参添加到Locals
static void createParamLVars(Type *Param) {
if (Param) {
// 递归到形参最底部
// 先将最底部的加入Locals中之后的都逐个加入到顶部保持顺序不变
createParamLVars(Param->Next);
if (!Param->Name)
errorTok(Param->NamePos, "parameter name omitted");
// 添加到Locals中
newLVar(getIdent(Param->Name), Param);
}
}
// 匹配goto和标签
// 因为标签可能会出现在goto后面所以要在解析完函数后再进行goto和标签的解析
static void resolveGotoLabels(void) {
// 遍历使goto对应上label
for (Node *X = Gotos; X; X = X->GotoNext) {
for (Node *Y = Labels; Y; Y = Y->GotoNext) {
if (!strcmp(X->Label, Y->Label)) {
X->UniqueLabel = Y->UniqueLabel;
break;
}
}
if (X->UniqueLabel == NULL)
errorTok(X->Tok->Next, "use of undeclared label");
}
Gotos = NULL;
Labels = NULL;
}
// 查找是否存在函数
static Obj *findFunc(char *Name) {
Scope *Sc = Scp;
// 递归到最内层域
while (Sc->Next)
Sc = Sc->Next;
// 遍历查找函数是否存在
VarScope *Sc2 = hashmapGet(&Sc->Vars, Name);
if (Sc2 && Sc2->Var && Sc2->Var->IsFunction)
return Sc2->Var;
return NULL;
}
// 将函数标记为存活状态
static void markLive(Obj *Var) {
// 如果不是函数或已存活,直接返回
if (!Var->IsFunction || Var->IsLive)
return;
// 将函数设置为存活状态
Var->IsLive = true;
// 遍历该函数的所有引用过的函数,将它们也设为存活状态
for (int I = 0; I < Var->Refs.Len; I++) {
Obj *Fn = findFunc(Var->Refs.Data[I]);
if (Fn)
markLive(Fn);
}
}
// functionDefinition = declspec declarator "{" compoundStmt*
static Token *function(Token *Tok, Type *BaseTy, VarAttr *Attr) {
Type *Ty = declarator(&Tok, Tok, BaseTy);
if (!Ty->Name)
errorTok(Ty->NamePos, "function name omitted");
// 函数名称
char *NameStr = getIdent(Ty->Name);
Obj *Fn = findFunc(NameStr);
if (Fn) {
// 重复定义的函数
if (!Fn->IsFunction)
errorTok(Tok, "redeclared as a different kind of symbol");
if (Fn->IsDefinition && equal(Tok, "{"))
errorTok(Tok, "redefinition of %s", NameStr);
if (!Fn->IsStatic && Attr->IsStatic)
errorTok(Tok, "static declaration follows a non-static declaration");
Fn->IsDefinition = Fn->IsDefinition || equal(Tok, "{");
} else {
Fn = newGVar(NameStr, Ty);
Fn->IsFunction = true;
Fn->IsDefinition = equal(Tok, "{");
Fn->IsStatic = Attr->IsStatic || (Attr->IsInline && !Attr->IsExtern);
Fn->IsInline = Attr->IsInline;
}
// 非static inline函数标记为根函数
Fn->IsRoot = !(Fn->IsStatic && Fn->IsInline);
// 判断是否没有函数定义
if (consume(&Tok, Tok, ";"))
return Tok;
CurrentFn = Fn;
// 清空全局变量Locals
Locals = NULL;
// 进入新的域
enterScope();
// 函数参数
createParamLVars(Ty->Params);
// 有大于16字节的结构体返回值的函数
Type *RTy = Ty->ReturnTy;
if ((RTy->Kind == TY_STRUCT || RTy->Kind == TY_UNION) && RTy->Size > 16)
// 第一个形参是隐式的,包含了结构体的地址
newLVar("", pointerTo(RTy));
Fn->Params = Locals;
// 判断是否为可变参数
if (Ty->IsVariadic)
Fn->VaArea = newLVar("__va_area__", arrayOf(TyChar, 0));
// 记录Alloca区域底部
Fn->AllocaBottom = newLVar("__alloca_size__", pointerTo(TyChar));
Tok = skip(Tok, "{");
// __func__被定义为包含当前函数名称的局部变量
pushScope("__func__")->Var =
newStringLiteral(Fn->Name, arrayOf(TyChar, strlen(Fn->Name) + 1));
// [GNU] __FUNCTION__也被定义为包含当前函数名称的局部变量
pushScope("__FUNCTION__")->Var =
newStringLiteral(Fn->Name, arrayOf(TyChar, strlen(Fn->Name) + 1));
// 函数体存储语句的ASTLocals存储变量
Fn->Body = compoundStmt(&Tok, Tok);
Fn->Locals = Locals;
// 结束当前域
leaveScope();
// 处理goto和标签
resolveGotoLabels();
return Tok;
}
// 构造全局变量
static Token *globalVariable(Token *Tok, Type *Basety, VarAttr *Attr) {
bool First = true;
while (!consume(&Tok, Tok, ";")) {
if (!First)
Tok = skip(Tok, ",");
First = false;
Type *Ty = declarator(&Tok, Tok, Basety);
if (!Ty->Name)
errorTok(Ty->NamePos, "variable name omitted");
// 全局变量初始化
Obj *Var = newGVar(getIdent(Ty->Name), Ty);
// 是否具有定义
Var->IsDefinition = !Attr->IsExtern;
// 传递是否为static
Var->IsStatic = Attr->IsStatic;
// 传递是否为TLS
Var->IsTLS = Attr->IsTLS;
// 若有设置,则覆盖全局变量的对齐值
if (Attr->Align)
Var->Align = Attr->Align;
if (equal(Tok, "="))
GVarInitializer(&Tok, Tok->Next, Var);
else if (!Attr->IsExtern && !Attr->IsTLS)
// 没有初始化器的全局变量设为试探性的
Var->IsTentative = true;
}
return Tok;
}
// 区分 函数还是全局变量
static bool isFunction(Token *Tok) {
if (equal(Tok, ";"))
return false;
// 虚设变量用于调用declarator
Type Dummy = {};
Type *Ty = declarator(&Tok, Tok, &Dummy);
return Ty->Kind == TY_FUNC;
}
// 删除冗余的试探性定义
static void scanGlobals(void) {
// 新的全局变量的链表
Obj Head;
Obj *Cur = &Head;
// 遍历全局变量,删除冗余的试探性定义
for (Obj *Var = Globals; Var; Var = Var->Next) {
// 不是试探性定义,直接加入到新链表中
if (!Var->IsTentative) {
Cur = Cur->Next = Var;
continue;
}
// 查找其他具有定义的同名标志符
// 从头遍历
Obj *Var2 = Globals;
for (; Var2; Var2 = Var2->Next)
// 判断 不是同一个变量,变量具有定义,二者同名
if (Var != Var2 && Var2->IsDefinition && !strcmp(Var->Name, Var2->Name))
break;
// 如果Var2为空说明需要生成代码加入到新链表中
// 如果Var2不为空说明存在定义那么就不需要生成试探性定义
if (!Var2)
Cur = Cur->Next = Var;
}
// 替换为新的全局变量链表
Cur->Next = NULL;
Globals = Head.Next;
}
// 声明内建函数
static void declareBuiltinFunctions(void) {
// 处理alloca函数
Type *Ty = funcType(pointerTo(TyVoid));
Ty->Params = copyType(TyInt);
BuiltinAlloca = newGVar("alloca", Ty);
BuiltinAlloca->IsDefinition = false;
}
// 语法解析入口函数
// program = (typedef | functionDefinition | globalVariable)*
Obj *parse(Token *Tok) {
// 声明内建函数
declareBuiltinFunctions();
Globals = NULL;
while (Tok->Kind != TK_EOF) {
VarAttr Attr = {};
Type *BaseTy = declspec(&Tok, Tok, &Attr);
// typedef
if (Attr.IsTypedef) {
Tok = parseTypedef(Tok, BaseTy);
continue;
}
// 函数
if (isFunction(Tok)) {
Tok = function(Tok, BaseTy, &Attr);
continue;
}
// 全局变量
Tok = globalVariable(Tok, BaseTy, &Attr);
}
// 遍历所有的函数
for (Obj *Var = Globals; Var; Var = Var->Next)
// 如果为根函数,则设置为存活状态
if (Var->IsRoot)
markLive(Var);
// 删除冗余的试探性定义
scanGlobals();
return Globals;
}