static Type DeriveType(TypeDerivList tyDrvList, Type ty) { while (tyDrvList != NULL) { if (tyDrvList->ctor == POINTER_TO) { ty = Qualify(tyDrvList->qual, PointerTo(ty)); } else if (tyDrvList->ctor == ARRAY_OF) { if (ty->categ == FUNCTION || ty->size == 0 || (IsRecordType(ty) && ((RecordType)ty)->hasFlexArray)) return NULL; ty = ArrayOf(tyDrvList->len, ty); } else { if (ty->categ == ARRAY || ty->categ == FUNCTION) return NULL; ty = FunctionReturn(ty, tyDrvList->sig); } tyDrvList = tyDrvList->next; } return ty; }
/* 翻译一个复合语句 */ static void TranslateCompoundStatement (AstStatement stmt) { AstCompoundStatement compStmt = AsComp (stmt); AstNode p; Vector ilocals = compStmt->ilocals; Symbol v; int i; /* 翻译局部变量 */ for (i = 0; i < LEN (ilocals); ++i) { InitData initd; Type ty; Symbol dst, src; int size; v = GET_ITEM (ilocals, i); initd = AsVar(v)->idata; size = 0; while (initd != NULL) { if (initd->offset != size) { dst = CreateOffset (T(UCHAR), v, size); GenerateClear (dst, initd->offset - size); } ty = initd->expr->ty; if (initd->expr->op == OP_STR) { String str = initd->expr->val.p; src = AddString (ArrayOf (str->len + 1, ty->bty), str); } else { src = TranslateExpression (initd->expr); } dst = CreateOffset (ty, v, initd->offset); /* 赋值 */ GenerateMove (ty, dst, src); size = initd->offset + ty->size; initd = initd->next; } if (size < v->ty->size) { dst = CreateOffset (T(UCHAR), v, size); GenerateClear (dst, v->ty->size - size); } } for (p = compStmt->stmts; p; p = p->next) { TranslateStatement ((AstStatement)p); } }
/** * primary-expression: * ID * constant * string-literal * ( expression ) */ static AstExpression ParsePrimaryExpression(void) { AstExpression expr; switch (CurrentToken) { case TK_ID: CREATE_AST_NODE(expr, Expression); expr->op = OP_ID; expr->val = TokenValue; NEXT_TOKEN; return expr; /// Notice: Only when parsing constant and string literal, /// ty member in astExpression is used since from OP_CONST /// and OP_STR alone the expression's type can't be determined case TK_INTCONST: case TK_UINTCONST: case TK_LONGCONST: case TK_ULONGCONST: case TK_LLONGCONST: case TK_ULLONGCONST: case TK_FLOATCONST: case TK_DOUBLECONST: case TK_LDOUBLECONST: CREATE_AST_NODE(expr, Expression); if (CurrentToken >= TK_FLOATCONST) CurrentToken++; /// nasty, requires that both from TK_INTCONST to TK_LDOUBLECONST /// and from INT to LDOUBLE are consecutive expr->ty = T(INT + CurrentToken - TK_INTCONST); expr->op = OP_CONST; expr->val = TokenValue; NEXT_TOKEN; return expr; case TK_STRING: case TK_WIDESTRING: CREATE_AST_NODE(expr, Expression); expr->ty = ArrayOf(((String)TokenValue.p)->len + 1, CurrentToken == TK_STRING ? T(CHAR) : WCharType); expr->op = OP_STR; expr->val = TokenValue; NEXT_TOKEN; return expr; case TK_LPAREN: NEXT_TOKEN; expr = ParseExpression(); Expect(TK_RPAREN); return expr; default: Error(&TokenCoord, "Expect identifier, string, constant or ("); return Constant0; } }