// Append list ListBox *ListBox::cons(ListBox *b) { assert(!isEmpty()); if (!b->isEmpty()) { // Replace final ListBox by B const ListBox *t = this; ListBox *attach = 0; while (!t->isEmpty()) { attach = (ListBox *)t; t = t->tail(); } assert (attach != 0); assert (attach->tail()->isEmpty()); attach->tail()->unlink(); attach->_tail() = b->link(); attach->_last = b->_last; return attach; } return 0; }
// Stacked alignment static Box *op_ualign(ListBox *args) { CHECK_ATOMS(args); UAlignBox *ret = 0; for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); if (ret == 0) ret = new UAlignBox; *ret ^= box; } // No child? Return null box. if (ret == 0) return new NullBox; // One child? Return it. if (ret->nchildren() == 1) { Box *child = (*ret)[0]->link(); ret->unlink(); return child; } // Return normalized alignment return normalize(ret); }
// Cons lists static Box *op_cons(ListBox *args) { ListBox *ret = 0; for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); if (!box->isListBox()) { VSLLib::eval_error("invalid argument -- argument is list"); if (ret) ret->unlink(); return 0; } if (!((ListBox *)box)->isEmpty()) { // Create list to append // If box is last arg, a link suffices ListBox *box2; if (b->tail()->isEmpty()) box2 = (ListBox *)box->link(); else box2 = (ListBox *)box->dup(); // Append list: // If box is first arg, copy box if (ret == 0) ret = box2; else { ret->cons(box2); box2->unlink(); } } } // No args? return [] if (ret == 0) ret = new ListBox; return ret; }
// True iff all args have some size static bool checkSize(ListBox *args) { for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); if (!box->size().isValid()) return false; } return true; }
// True iff all args are atoms static bool checkAtoms(ListBox *args) { for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); if (box->isListBox() && !box->isDummyBox()) { VSLLib::eval_error("invalid argument -- argument is list"); return false; } } return true; }
// Multiplication static Box *op_mult(ListBox *args) { CHECK_ATOMS(args); CHECK_SIZE(args); BoxSize product(1,1); for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); product *= box->size(); } return new SpaceBox(product); }
// Addition static Box *op_plus(ListBox *args) { CHECK_ATOMS(args); CHECK_SIZE(args); BoxSize sum(0,0); for (ListBox *b = args; !b->isEmpty(); b = b->tail()) { Box *box = b->head(); sum += box->size(); } return new SpaceBox(sum); }