?? compile.c
字號:
* ExpandIncDecExpr() - Expand increment/decrement operations.
*
* Pre increment/decrement is the simple case:
*
* ++A -> A += 1
*
* Post increment/decrement is a little more tricky:
*
* If A is simple (i.e. not an array reference):
*
* A++ -> tmp = A, A += 1, tmp
*
* If A is an array reference:
*
* A[i1]...[iN]++ ->
* tmpi1 = i1, ..., tmpiN = iN, tmpv = A[tmpi1]...[tmpiN],
* A[tmpi1]...[tmpiN] += 1, tmpv
*
*/
expr *ExpandIncDecExpr(expr *fExpr, void *arg1, int arg2)
{
int pre = 0;
int newop = -1;
expr *oneExpr;
expr *result = NULL;
if (fExpr->common.kind == UNARY_N) {
switch (fExpr->un.op) {
case PREDEC_OP:
pre = 1;
case POSTDEC_OP:
newop = ASSIGNMINUS_OP;
break;
case PREINC_OP:
pre = 1;
case POSTINC_OP:
newop = ASSIGNPLUS_OP;
break;
}
}
if (newop == -1)
return fExpr;
oneExpr = (expr *) NewIConstNode(ICONST_OP, 1, TYPE_BASE_INT);
if (pre)
result = (expr *) NewBinopNode(newop, fExpr->un.arg, oneExpr);
else {
expr *idxAssigns = IsArrayIndex(fExpr->un.arg)
? PutIndexEpxrsInTemps(fExpr->un.arg) : NULL;
expr *tmp = (expr *) NewTmp(fExpr->un.arg);
expr *tmpAssign = NewSimpleAssignment(Cg->pLastSourceLoc, tmp, fExpr->un.arg, 0);
expr *incdec = (expr *) NewBinopNode(newop, DupNode(fExpr->un.arg), oneExpr);
expr *rval = DupNode(tmp);
result = (expr *) NewBinopNode(COMMA_OP, incdec, rval);
result = (expr *) NewBinopNode(COMMA_OP, tmpAssign, result);
if (idxAssigns)
result = (expr *) NewBinopNode(COMMA_OP, idxAssigns, result);
}
return result;
} // ExpandIncDecExpr
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Expand Compound Assignment Expressions ////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* ExpandCompoundAssignmentExpr() - Transform compound assignments
* into simple assignments.
*
* If A is simple (i.e. not an array reference):
*
* A op= B -> A = A op B
*
* If A is an array reference:
*
* A[e1]...[eN] op= B ->
* tmp1 = e1, ..., tmpN = eN, A[tmp1]...[tmpN] = A[tmp1]...[tmpN] op B
*
*/
expr *ExpandCompoundAssignmentExpr(expr *fExpr, void *arg1, int arg2)
{
int newop = -1;
int opname = 0;
int intOnly = 0;
expr *lexpr, *rExpr;
expr *result = NULL;
expr *idxAssigns = NULL;
if (fExpr->common.kind == BINARY_N) {
switch (fExpr->bin.op) {
case ASSIGNMINUS_OP:
newop = SUB_OP;
opname = '-';
break;
case ASSIGNMOD_OP:
newop = MOD_OP;
opname = '%';
intOnly = 1;
break;
case ASSIGNPLUS_OP:
newop = ADD_OP;
opname = '+';
break;
case ASSIGNSLASH_OP:
newop = DIV_OP;
opname = '/';
break;
case ASSIGNSTAR_OP:
newop = MUL_OP;
opname = '*';
break;
}
}
if (newop == -1)
return fExpr;
lexpr = fExpr->bin.left;
rExpr = fExpr->bin.right;
if (IsArrayIndex(lexpr))
idxAssigns = PutIndexEpxrsInTemps(lexpr);
result = NewBinaryOperator(Cg->pLastSourceLoc, newop, opname, lexpr, rExpr, intOnly);
result = NewSimpleAssignment(Cg->pLastSourceLoc, DupNode(lexpr), result, 0);
if (idxAssigns)
result = (expr *) NewBinopNode(COMMA_OP, idxAssigns, result);
return result;
} // ExpandCompoundAssignmentExpr
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Flatten Chained Assignment Statements ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
typedef struct MData_rec {
Scope *scope;
int numtemps;
StmtList statements;
} MData;
/*
* IsConstant()
*
*/
int IsConstant(expr *fExpr)
{
switch (fExpr->common.kind) {
case CONST_N:
return 1;
default:
break;
}
return 0;
} // IsConstant
/*
* IsVariable()
*
*/
int IsVariable(expr *fExpr)
{
switch (fExpr->common.kind) {
case SYMB_N:
return 1;
default:
break;
}
return 0;
} // IsVariable
/*
* IsCompileTimeAddress()
*
*/
int IsCompileTimeAddress(expr *fExpr)
{
if (fExpr->common.IsLValue) {
switch (fExpr->common.kind) {
case SYMB_N:
return 1;
case BINARY_N:
switch (fExpr->bin.op) {
case MEMBER_SELECTOR_OP:
return IsCompileTimeAddress(fExpr->bin.left);
case ARRAY_INDEX_OP:
if (IsCompileTimeAddress(fExpr->bin.left)) {
if (IsConstant(fExpr->bin.right)) {
return 1;
}
}
break;
default:
break;
}
break;
default:
break;
}
}
return 0;
} // IsCompileTimeAddress
/*
* GetConstIndex()
*
*/
int GetConstIndex(expr *fExpr)
{
switch (fExpr->common.kind) {
case CONST_N:
switch (fExpr->co.op) {
case ICONST_OP:
case BCONST_OP:
return fExpr->co.val[0].i;
break;
case FCONST_OP:
case HCONST_OP:
case XCONST_OP:
return (int) fExpr->co.val[0].f;
break;
default:
break;
}
break;
default:
break;
}
return 0;
} // GetConstIndex
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////// Flatten comma expressions into statement lists /////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
static int IsComma(const expr *fExpr)
{
return fExpr->common.kind == BINARY_N && fExpr->bin.op == COMMA_OP;
} // IsComma
/*
* FlattenCommasExpr()
*
* op (a, b) -> a, (op b)
* (a, b) op c -> a, (b op c)
* A[e1]...[eN] = (b, c) -> (tmp1 = e1), ..., (tmpN = eN), b, A[tmp1]...[tmpN] = c
* a = (b, c) -> b, a = c
* a op (b, c) -> (tmpa = a), b, (tmpa op c)
* (a, b) ? c : d -> a, (b ? c : d)
* a ? (b, c) : d -> (tmpa = a), b, (tmpa ? c : d)
* a ? b : (c, d) -> (tmpa = a), (tmpb = b), c, (tmpa ? tmpb : d)
*/
static expr *FlattenCommasExpr(expr *fExpr, void *arg1, int arg2)
{
switch (fExpr->common.kind) {
case UNARY_N:
if (IsComma(fExpr->un.arg)) {
expr *comma = fExpr->un.arg;
fExpr->un.arg = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, fExpr);
}
break;
case BINARY_N: {
binary *bin = &fExpr->bin;
if (IsComma(bin->left)) {
expr *comma = bin->left;
bin->left = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, (expr *) bin);
}
if (bin->right && IsComma(bin->right)) {
// Assignments/lvalues are special
if (bin->op == ASSIGN_OP || bin->op == ASSIGN_V_OP) {
expr *idxAssigns = IsArrayIndex(bin->left)
? PutIndexEpxrsInTemps(bin->left) : NULL;
fExpr = (expr *) NewBinopNode(COMMA_OP, bin->right->bin.left,
fExpr);
bin->right = bin->right->bin.right;
if (idxAssigns)
fExpr = (expr *) NewBinopNode(COMMA_OP, idxAssigns, fExpr);
} else if (bin->op != COMMA_OP) {
// no need to lift comma ops above a comma op
expr *comma = bin->right;
expr *tmp = (expr *) NewTmp(bin->left);
expr *assign = NewSimpleAssignment(Cg->pLastSourceLoc, tmp, bin->left, 0);
bin->left = DupNode(tmp);
bin->right = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, (expr *) bin);
fExpr = (expr *) NewBinopNode(COMMA_OP, assign, fExpr);
}
}
break;
}
case TRINARY_N: {
trinary *tri = &fExpr->tri;
if (IsComma(tri->arg1)) {
expr *comma = tri->arg1;
tri->arg1 = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, (expr *) tri);
}
if (IsComma(tri->arg2)) {
expr *comma = tri->arg2;
expr *tmp = (expr *) NewTmp(tri->arg1);
expr *assign = NewSimpleAssignment(Cg->pLastSourceLoc, tmp, tri->arg1, 0);
tri->arg1 = DupNode(tmp);
tri->arg2 = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, (expr *) tri);
fExpr = (expr *) NewBinopNode(COMMA_OP, assign, fExpr);
}
if (IsComma(tri->arg3)) {
expr *comma = tri->arg3;
expr *tmp1 = (expr *) NewTmp(tri->arg1);
expr *tmp2 = (expr *) NewTmp(tri->arg2);
expr *assign1 = NewSimpleAssignment(Cg->pLastSourceLoc, tmp1, tri->arg1, 0);
expr *assign2 = NewSimpleAssignment(Cg->pLastSourceLoc, tmp2, tri->arg2, 0);
tri->arg1 = DupNode(tmp1);
tri->arg2 = DupNode(tmp2);
tri->arg3 = comma->bin.right;
fExpr = (expr *) NewBinopNode(COMMA_OP, comma->bin.left, (expr *) tri);
fExpr = (expr *) NewBinopNode(COMMA_OP, assign2, fExpr);
fExpr = (expr *) NewBinopNode(COMMA_OP, assign1, fExpr);
}
break;
}
}
return fExpr;
} // FlattenCommasExpr
/*
* LinearizeCommasExpr() - Gets rid of all top-level comma expressions
* by pulling them out into an expression list (returned through
* arg1).
*
*/
static expr *LinearizeCommasExpr(expr *fExpr, void *arg1, int arg2)
{
stmt ** fStmts = (stmt **) arg1;
while (IsComma(fExpr)) {
stmt * fStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, fExpr->bin.left);
*fStmts = ConcatStmts(*fStmts, fStmt);
fExpr = fExpr->bin.right;
}
return fExpr;
} // LinearizeCommasExpr
/*
* FlattenCommas()
*
*/
static stmt *FlattenCommasStmt(stmt *fStmt, void *arg1, int arg2)
{
stmt *preCommaStmts = NULL;
PreApplyToExpressionsLocal(FlattenCommasExpr, fStmt, NULL, 0);
PreApplyToExpressionsLocal(LinearizeCommasExpr, fStmt, &preCommaStmts, 0);
return ConcatStmts(preCommaStmts, fStmt);
} // FlattenCommas
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Chop Matrices up into Vectors ///////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* DeconstructMatricesExpr()
*
*/
expr *DeconstructMatricesExpr(expr *fExpr, void *arg1, int arg2)
{
Symbol *lSymb;
MData *mdata;
Type *lType;
int base, len, len2;
int vname, index;
mdata = (MData *) arg1;
switch (fExpr->common.kind) {
case BINARY_N:
switch (fExpr->bin.op) {
case ARRAY_INDEX_OP:
lType = fExpr->bin.type;
if (IsMatrix(fExpr->bin.left->common.type, &len, &len2)) {
base = GetBase(lType);
if (IsConstant(fExpr->bin.right)) {
if (IsVariable(fExpr->bin.left)) {
index = GetConstIndex(fExpr->bin.right);
vname = GenerateIndexName(fExpr->bin.left, index);
lSymb = LookUpLocalSymbol(mdata->scope, vname);
if (!lSymb)
lSymb = DefineVar(&lSymb->loc, mdata->scope, vname, lType);
fExpr = GenSymb(lSymb);
} else {
SemanticError(Cg->pLastSourceLoc, ERROR___MATRIX_NOT_SIMPLE);
}
} else {
SemanticError(Cg->pLastSourceLoc, ERROR___ARRAY_INDEX_NOT_CONSTANT);
}
}
break;
default:
break;
}
break;
default:
break;
}
return fExpr;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -