//Input: Two expressions x and y, and a relational operator op //Output: One conditional expression x op y NC* createConditionalExpression( NC *expr1, char *relOp, NC *expr2 ) { NC *andExpr, *orExpr, *relExpr; NC *newExpr1, *newExpr2; NC *newExpr; int operator; operator = getRelOperatorIndex(relOp); newExpr1 = copylist(expr1); newExpr2 = copylist(expr2); newExpr2 = negateExpression(newExpr2); newExpr = (NC*) malloc (sizeof(NC)); Add_Sums(newExpr1, newExpr2, newExpr); relExpr = (NC*) malloc (sizeof(NC)); relExpr->list = NULL; relExpr->type = 'R'; relExpr->inc = operator; relExpr->link = newExpr; orExpr = (NC*) malloc (sizeof(NC)); orExpr->list = NULL; orExpr->type = 'O'; orExpr->inc = 0; orExpr->link = relExpr; andExpr = (NC*) malloc (sizeof(NC)); andExpr->list = NULL; andExpr->type = 'A'; andExpr->inc = 0; andExpr->link = orExpr; return andExpr; }
static void untangleBranches(Stack *statements, int start, int stop, Branchtype type, int indent) { Stack s; Tree t; int i, offset, end, hasElse, wasIf = 0; for(i=start; i<stop; ++i) { s = statements[i]; t = s->data.tree; if(s->target > i && t->action != SWFACTION_BRANCHIFTRUE) { /* it's a do loop */ int target = s->target; if(s->target < start || s->target > stop) error("stmt %i: do target (%i) outside scope (%i,%i)!", i, s->target, start, stop); putchar('\n'); INDENT printf("do\n"); INDENT printf("{\n"); s->target = -1; untangleBranches(statements, i, target, BRANCH_DO, indent+1); INDENT printf("}\n"); INDENT printf("while("); listItem(statements[target]->data.tree->left, SWFACTION_END); printf(");\n"); wasIf = 1; i = target; continue; } if(t->action == SWFACTION_BRANCHALWAYS) error("stmt %i: unexpected unconditional branch!", i); if(t->action != SWFACTION_BRANCHIFTRUE) { /* it's just a statement. */ if(wasIf) putchar('\n'); INDENT listItem(s, SWFACTION_END); putchar(';'); putchar('\n'); wasIf = 0; continue; } offset = (int)t->right; if(offset < start || offset > stop) error("stmt %i: branch target (%i) outside scope (%i,%i)!", i, offset, start, stop); if(offset < i) error("stmt %i: Unexpected backwards branch!", i); if(type==BRANCH_WHILE || type==BRANCH_DO) { if(offset == stop) { INDENT printf("break;\n"); continue; } else if(offset == start) { INDENT printf("continue;\n"); continue; /*ha!*/ } } if(statements[offset-1]->data.tree->action == SWFACTION_BRANCHALWAYS && (int)statements[offset-1]->data.tree->right == i) { /* it's a while loop */ putchar('\n'); INDENT printf("while("); listItem(negateExpression(t->left), SWFACTION_END); printf(")\n"); if(i < offset-3) { INDENT putchar('{'); putchar('\n'); } untangleBranches(statements, i+1, offset-1, BRANCH_WHILE, indent+1); if(i < offset-3) { INDENT putchar('}'); putchar('\n'); } wasIf = 1; i = offset-1; continue; } /* it's an if */ if(i>start) putchar('\n'); if(statements[offset-1]->data.tree->action == SWFACTION_BRANCHALWAYS) { /* got an else */ hasElse = 1; end = (int)statements[offset-1]->data.tree->right; } else { hasElse = 0; end = offset; } if(end < start || end > stop) error("stmt %i: else target (%i) outside scope (%i,%i)!", i, end, start, stop); if(end < i) error("stmt %i: Unexpected backwards branch!", i); INDENT printf("if("); /* XXX - would like to reverse else and if if expression is already negated.. */ listItem(negateExpression(t->left), SWFACTION_END); putchar(')'); putchar('\n'); if(i < offset-(hasElse?3:2)) { INDENT putchar('{'); putchar('\n'); } /* if hasElse, i+1 to offset-1 */ untangleBranches(statements, i+1, offset-(hasElse?1:0), BRANCH_IF, indent+1); if(i < offset-(hasElse?3:2)) { INDENT putchar('}'); putchar('\n'); } if(hasElse) { INDENT printf("else\n"); if(offset+2 < end) { INDENT putchar('{'); putchar('\n'); } untangleBranches(statements, offset, end, BRANCH_ELSE, indent+1); if(offset+2 < end) { INDENT putchar('}'); putchar('\n'); } } wasIf = 1; i = end-1; } }