mirror of https://github.com/sunshaoce/rvcc.git
3986 lines
107 KiB
C
3986 lines
107 KiB
C
#include "rvcc.h"
|
||
|
||
// 局部变量,全局变量,typedef,enum常量的域
|
||
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*BaseSz,VLA大小=基类个数*基类大小
|
||
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_EXPR,EXPR1,EXPR2…的二叉树
|
||
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±n,ptr是指向全局变量的指针,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+1,1不是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));
|
||
|
||
// 函数体存储语句的AST,Locals存储变量
|
||
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;
|
||
}
|