Float128 *GetFloatExpression(ENODE **pnode) /* simple integer value */ { TYP *tp; ENODE *node; Float128 *flt; flt = (Float128 *)allocx(sizeof(Float128)); tp = NonCommaExpression(&node); if (node==NULL) { error(ERR_SYNTAX); return 0; } opt_const(&node); // This should reduce to a single integer expression if (node==NULL) { fatal("Compiler Error: GetFloatExpression: node is NULL"); return 0; } if (node->nodetype != en_fcon) { if (node->nodetype==en_uminus) { if (node->p[0]->nodetype != en_fcon) { printf("\r\nnode:%d \r\n", node->nodetype); error(ERR_INT_CONST); return 0; } Float128::Assign(flt, &node->p[0]->f128); flt->sign = !flt->sign; if (pnode) *pnode = node; return (flt); } } if (pnode) *pnode = node; return &node->f128; }
static void scan_compound(Statement *stmt) { SYM *sp; sp = stmt->ssyms.head; while (sp) { if (sp->initexp) { opt_const(&sp->initexp); scanexpr(sp->initexp,0); } sp = sp->next; } scan(stmt->s1); }
static void scan_compound(Statement *stmt) { SYM *sp; sp = sp->GetPtr(stmt->ssyms.GetHead()); while (sp) { if (sp->initexp) { opt_const(&sp->initexp); scanexpr(sp->initexp,0); } sp = sp->GetNextPtr(); } scan(stmt->s1); }
int64_t GetIntegerExpression(ENODE **pnode) /* simple integer value */ { TYP *tp; ENODE *node; tp = NonCommaExpression(&node); if (node==NULL) { error(ERR_SYNTAX); return 0; } opt_const(&node); // This should reduce to a single integer expression if (node==NULL) { fatal("Compiler Error: GetIntegerExpression: node is NULL"); return 0; } if (node->nodetype != en_icon && node->nodetype != en_cnacon) { printf("\r\nnode:%d \r\n", node->nodetype); error(ERR_INT_CONST); return 0; } if (pnode) *pnode = node; return node->i; }
/* * NAME: optimize->stmt() * DESCRIPTION: optimize a statement */ node *opt_stmt(node *first, Uint *depth) { node *n, **m, **prev; Uint d; Uint d1, d2; int i; node *side; if (first == (node *) NULL) { *depth = 0; return (node *) NULL; } d = 0; prev = m = &first; for (;;) { n = ((*m)->type == N_PAIR) ? (*m)->l.left : *m; switch (n->type) { case N_BLOCK: n->l.left = opt_stmt(n->l.left, &d1); if (n->l.left == (node *) NULL) { n = (node *) NULL; } d = max2(d, d1); break; case N_CASE: n->l.left = opt_stmt(n->l.left, &d1); d = max2(d, d1); break; case N_COMPOUND: n->l.left = opt_stmt(n->l.left, &d1); if (n->l.left == (node *) NULL) { n = (node *) NULL; } else if (n->r.right != (node *) NULL) { n->r.right = opt_stmt(n->r.right, &d2); d1 = max2(d1, d2); } d = max2(d, d1); break; case N_DO: n->r.right = opt_stmt(n->r.right, &d1); side_start(&side, depth); d2 = opt_cond(&n->l.left, FALSE); d2 = max2(d2, side_end(&n->l.left, side, (node **) NULL, 0)); d = max3(d, d1, d2); break; case N_FOR: side_start(&side, depth); d1 = opt_cond(&n->l.left, FALSE); d1 = max2(d1, side_end(&n->l.left, side, (node **) NULL, 0)); i = opt_const(n->l.left); if (i == 0) { /* never */ n->r.right = opt_skip(n->r.right); if (n->r.right == (node *) NULL) { n->type = N_POP; n = opt_stmt(n, &d1); d = max2(d, d1); break; } } else if (i > 0) { /* always */ n->type = N_FOREVER; n = opt_stmt(n, &d1); d = max2(d, d1); break; } n->r.right = opt_stmt(n->r.right, &d2); d = max3(d, d1, d2); break; case N_FOREVER: if (n->l.left != (node *) NULL) { side_start(&side, depth); d1 = opt_expr(&n->l.left, TRUE); if (d1 == 0) { n->l.left = (node *) NULL; } d1 = max2(d1, side_end(&n->l.left, side, (node **) NULL, 0)); if (d1 == 0) { n->l.left = (node *) NULL; } } else { d1 = 0; } n->r.right = opt_stmt(n->r.right, &d2); d = max3(d, d1, d2); break; case N_RLIMITS: side_start(&side, depth); d1 = opt_expr(&n->l.left->l.left, FALSE); d1 = max2(d1, side_end(&n->l.left->l.left, side, (node **) NULL, 0)); side_start(&side, depth); d2 = opt_expr(&n->l.left->r.right, FALSE); d2 = max2(d2, side_end(&n->l.left->r.right, side, (node **) NULL, 0)); d1 = max2(d1, d2 + 1); n->r.right = opt_stmt(n->r.right, &d2); d = max3(d, d1, d2); break; case N_CATCH: n->l.left = opt_stmt(n->l.left, &d1); if (n->l.left == (node *) NULL) { n = opt_stmt(opt_skip(n->r.right), &d1); d = max2(d, d1); } else { n->r.right = opt_stmt(n->r.right, &d2); d = max3(d, d1, d2); } break; case N_IF: side_start(&side, depth); d1 = opt_cond(&n->l.left, FALSE); d1 = max2(d1, side_end(&n->l.left, side, (node **) NULL, 0)); i = opt_const(n->l.left); if (i == 0) { n->r.right->l.left = opt_skip(n->r.right->l.left); } else if (i > 0) { n->r.right->r.right = opt_skip(n->r.right->r.right); } n->r.right->l.left = opt_stmt(n->r.right->l.left, &d2); d1 = max2(d1, d2); n->r.right->r.right = opt_stmt(n->r.right->r.right, &d2); if (n->r.right->l.left == (node *) NULL) { if (n->r.right->r.right == (node *) NULL) { n->type = N_POP; n = opt_stmt(n, &d1); d = max2(d, d1); break; } n->l.left = opt_not(n->l.left); n->r.right->l.left = n->r.right->r.right; n->r.right->r.right = (node *) NULL; } d = max3(d, d1, d2); break; case N_PAIR: n = opt_stmt(n, &d1); d = max2(d, d1); break; case N_POP: side_start(&side, depth); d1 = opt_expr(&n->l.left, TRUE); if (d1 == 0) { n->l.left = (node *) NULL; } d = max3(d, d1, side_end(&n->l.left, side, (node **) NULL, 0)); if (n->l.left == (node *) NULL) { n = (node *) NULL; } break; case N_RETURN: side_start(&side, depth); d1 = opt_expr(&n->l.left, FALSE); d = max3(d, d1, side_end(&n->l.left, side, (node **) NULL, 0)); break; case N_SWITCH_INT: case N_SWITCH_RANGE: case N_SWITCH_STR: n->r.right->r.right = opt_stmt(n->r.right->r.right, &d1); if (n->r.right->r.right == (node *) NULL) { n = n->r.right; n->type = N_POP; n = opt_stmt(n, &d1); d = max2(d, d1); } else { side_start(&side, depth); d2 = opt_expr(&n->r.right->l.left, FALSE); d2 = max2(d2, side_end(&n->r.right->l.left, side, (node **) NULL, 0)); d = max3(d, d1, d2); } break; } if ((*m)->type == N_PAIR) { if (n == (node *) NULL) { *m = (*m)->r.right; } else { (*m)->l.left = n; if (n->flags & F_END) { n = opt_skip((*m)->r.right); if (n == (node *) NULL) { *m = (*m)->l.left; break; } (*m)->r.right = n; } prev = m; m = &(*m)->r.right; } } else { *m = n; if (n == (node *) NULL && prev != m) { *prev = (*prev)->l.left; } break; } } *depth = d; return first; }
/* * scan will gather all optimizable expressions into the expression * list for a block of statements. */ static void scan(Statement *block) { while( block != NULL ) { switch( block->stype ) { case st_compound: scan_compound(block); break; case st_check: case st_return: case st_throw: case st_expr: opt_const(&block->exp); scanexpr(block->exp,0); break; case st_while: case st_until: case st_do: case st_dountil: opt_const(&block->exp); scanexpr(block->exp,0); case st_doloop: case st_forever: scan(block->s1); break; case st_for: opt_const(&block->initExpr); scanexpr(block->initExpr,0); opt_const(&block->exp); scanexpr(block->exp,0); scan(block->s1); opt_const(&block->incrExpr); scanexpr(block->incrExpr,0); break; case st_if: opt_const(&block->exp); scanexpr(block->exp,0); scan(block->s1); scan(block->s2); break; case st_switch: opt_const(&block->exp); scanexpr(block->exp,0); scan(block->s1); break; case st_firstcall: case st_case: case st_default: scan(block->s1); break; case st_spinlock: scan(block->s1); scan(block->s2); break; // nothing to process for these statement case st_break: case st_continue: case st_goto: break; default: ;// printf("Uncoded statement in scan():%d\r\n", block->stype); } block = block->next; } }