// Compiled fragtree -> compiled fragtree without labels Node dereference(Node program) { int sz = treeSize(program) * 4; int labelLength = 1; while (sz >= 256) { labelLength += 1; sz /= 256; } programAux aux = buildDict(program, Aux(), labelLength); return substDict(program, aux, labelLength); }
// Applies that dictionary void substDict(Node program, programAux aux, int labelLength, std::vector<Node> &out) { Metadata m = program.metadata; std::vector<Node> inner; if (program.type == TOKEN) { if (program.val[0] == '$') { std::string tokStr = "PUSH"+unsignedToDecimal(labelLength); out.push_back(token(tokStr, m)); int dotLoc = program.val.find('.'); if (dotLoc == -1) { std::string val = aux.vars[program.val.substr(1)]; inner = toByteArr(val, m, labelLength); } else { std::string start = aux.vars[program.val.substr(1, dotLoc-1)], end = aux.vars[program.val.substr(dotLoc + 1)], dist = decimalSub(end, start); inner = toByteArr(dist, m, labelLength); } for (unsigned i = 0; i < inner.size(); i++) out.push_back(inner[i]); } else if (program.val[0] == '~') { } else if (isNumberLike(program)) { inner = toByteArr(program.val, m); out.push_back(token("PUSH"+unsignedToDecimal(inner.size()))); for (unsigned i = 0; i < inner.size(); i++) out.push_back(inner[i]); } else out.push_back(program); } else { for (unsigned i = 0; i < program.args.size(); i++) { substDict(program.args[i], aux, labelLength, out); } } }
// Compiled fragtree -> compiled fragtree without labels std::vector<Node> dereference(Node program) { int sz = treeSize(program) * 4; int labelLength = 1; while (sz >= 256) { labelLength += 1; sz /= 256; } programAux aux = Aux(); buildDict(program, aux, labelLength); std::vector<Node> o; substDict(program, aux, labelLength, o); return o; }
// Applies that dictionary Node substDict(Node program, programAux aux, int labelLength) { Metadata m = program.metadata; std::vector<Node> out; std::vector<Node> inner; if (program.type == TOKEN) { if (program.val[0] == '$') { std::string tokStr = "PUSH"+intToDecimal(labelLength); out.push_back(token(tokStr, m)); int dotLoc = program.val.find('.'); if (dotLoc == -1) { std::string val = aux.vars[program.val.substr(1)]; inner = toByteArr(val, m, labelLength); } else { std::string start = aux.vars[program.val.substr(1, dotLoc-1)], end = aux.vars[program.val.substr(dotLoc + 1)], dist = decimalSub(end, start); inner = toByteArr(dist, m, labelLength); } out.push_back(astnode("_", inner, m)); } else if (program.val[0] == '~') { } else if (isNumberLike(program)) { inner = toByteArr(program.val, m); out.push_back(token("PUSH"+intToDecimal(inner.size()))); out.push_back(astnode("_", inner, m)); } else return program; } else { for (unsigned i = 0; i < program.args.size(); i++) { Node n = substDict(program.args[i], aux, labelLength); if (n.type == TOKEN || n.args.size()) out.push_back(n); } } return astnode("_", out, m); }