void CParser::SortBlock(CStack *op, CStack *var) { SItem *ptrOp, *ptrVar, *ptrVarPrev; bool moved; if (!op) return; do { moved = false; ptrOp = op->top; ptrVar = var->top; ptrVarPrev = NULL; while (ptrOp->next) // до конца стека { if (TOKEN(ptrOp) == tBeg) break; // конец блока /* 1 */ if (PRIOR(ptrOp) >= PRIOR(ptrOp->next)) { ptrOp = ptrOp->next; ptrVarPrev = ptrVar; ptrVar = PtrPlusNum(ptrOp, VarCount(TOKEN(ptrOp))); continue; } /* 2 */ swap_tokens(ptrOp, ptrOp->next); /* 3 */ int pos = VarCount(TOKEN(ptrOp))-1; pos = max(pos, 1)-1; move( PtrPlusNum(ptrVar, pos), // начало VarCount(TOKEN(ptrOp->next)), // длина ptrVarPrev, // куда var->top ); /* 4 */ moved = true; break; } // while (ptrOp->next) } while (moved); // пока не будет перестановок }
void EmitInstr2(Instr * instr, char * str) { Var * var; UInt8 format = 0; char * s, c; UInt32 n; BigInt bn; BigInt * pn; s = str; if (instr->op == INSTR_LINE) { PrintColor(BLUE+LIGHT); } while(c = *s++) { if (c == '%') { c = *s++; if (c == '\'') { format = 1; c = *s++; } if (c >='A' && c<='Z') { var = MACRO_ARG[c-'A']; // Variable properties if (*s == '.') { s++; if (StrEqualPrefix(s, "count", 5)) { VarCount(var, &bn); EmitBigInt(&bn); s+= 5; continue; } else if (StrEqualPrefix(s, "size", 4)) { n = VarByteSize(var); EmitInt(n); s+= 4; continue; } else if (StrEqualPrefix(s, "elemsize", 8) || StrEqualPrefix(s, "item.size", 9)) { s += 8; if (var->type->variant == TYPE_ARRAY) { n = TypeSize(var->type->element); } else { n = 0; } EmitInt(n); continue; } if (StrEqualPrefix(s, "step", 4)) { s += 4; n = 1; if (var->type->variant == TYPE_ARRAY) { n = var->type->step; } EmitInt(n); continue; } else if (StrEqualPrefix(s, "index.min", 9)) { s += 9; if (var->type->variant == TYPE_ARRAY) { pn = &var->type->index->range.min; } else { pn = Int0(); } EmitBigInt(pn); continue; } s--; } EmitVar(var, format); continue; } switch(c) { case '0': EmitVar(instr->result, format); continue; case '1': if (instr->op != INSTR_LINE) { EmitVar(instr->arg1, format); } else { EmitInt(instr->line_no); } continue; case '2': if (instr->op != INSTR_LINE) { EmitVar(instr->arg2, format); } else { EmitStr(instr->line); } continue; case '@': break; case 't': c = '\t'; break; } } EmitChar(c); } if (instr->op == INSTR_LINE) { PrintColor(RED+GREEN+BLUE); } }