// 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); } } }
// Builds a dictionary mapping labels to variable names void buildDict(Node program, programAux &aux, int labelLength) { Metadata m = program.metadata; // Token if (program.type == TOKEN) { if (isNumberLike(program)) { aux.step += 1 + toByteArr(program.val, m).size(); } else if (program.val[0] == '~') { aux.vars[program.val.substr(1)] = unsignedToDecimal(aux.step); } else if (program.val[0] == '$') { aux.step += labelLength + 1; } else aux.step += 1; } // A sub-program (ie. LLL) else if (program.val == "____CODE") { int step = aux.step; aux.step = 0; for (unsigned i = 0; i < program.args.size(); i++) { buildDict(program.args[i], aux, labelLength); } aux.step += step; } // Normal sub-block else { for (unsigned i = 0; i < program.args.size(); i++) { buildDict(program.args[i], aux, labelLength); } } }
// Opcodes -> bin std::string serialize(std::vector<Node> codons) { std::string o; for (unsigned i = 0; i < codons.size(); i++) { int v; if (isNumberLike(codons[i])) { v = decimalToUnsigned(codons[i].val); } else if (codons[i].val.substr(0,4) == "PUSH") { v = 95 + decimalToUnsigned(codons[i].val.substr(4)); } else { v = opcode(codons[i].val); } o += (char)v; } 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); }
// Builds a dictionary mapping labels to variable names programAux buildDict(Node program, programAux aux, int labelLength) { Metadata m = program.metadata; // Token if (program.type == TOKEN) { if (isNumberLike(program)) { aux.step += 1 + toByteArr(program.val, m).size(); } else if (program.val[0] == '~') { aux.vars[program.val.substr(1)] = unsignedToDecimal(aux.step); } else if (program.val[0] == '$') { aux.step += labelLength + 1; } else aux.step += 1; } // A sub-program (ie. LLL) else if (program.val == "____CODE") { programAux auks = Aux(); for (unsigned i = 0; i < program.args.size(); i++) { auks = buildDict(program.args[i], auks, labelLength); } for (std::map<std::string,std::string>::iterator it=auks.vars.begin(); it != auks.vars.end(); it++) { aux.vars[(*it).first] = (*it).second; } aux.step += auks.step; } // Normal sub-block else { for (unsigned i = 0; i < program.args.size(); i++) { aux = buildDict(program.args[i], aux, labelLength); } } return aux; }
Node tryNumberize(Node node) { if (node.type == TOKEN && isNumberLike(node)) return nodeToNumeric(node); return node; }
SimpleJsonParser::Token SimpleJsonParser::nextToken() { if (!m_ptr) { return Token_ERROR; } if (m_ptr == m_end) { return Token_EOF; } static const char *ws = " \t\n\r"; // skip whitespace while (m_ptr != m_end && strchr(ws, *m_ptr)) { ++m_ptr; } if (m_ptr == m_end) { return Token_EOF; } char c = *m_ptr++; switch (c) { case '{': return Token_Begin; case '}': return Token_End; case ':': return Token_Colon; case ',': return Token_Comma; } // string ? if (c == '"') { m_str.clear(); const char *ss = m_ptr; while (m_ptr != m_end && *m_ptr != '"') { ++m_ptr; } if (m_ptr == m_end) { return Token_ERROR; } m_str = QByteArray(ss, m_ptr++ - ss); return Token_String; } // number ? if (isNumberLike(c)) { const char *ss = m_ptr - 1; while (m_ptr != m_end && isNumberLike(*m_ptr)) { ++m_ptr; } bool ok; m_num = QByteArray(ss, m_ptr - ss).toDouble(&ok); if (!ok) { return Token_ERROR; } return Token_Number; } return Token_ERROR; }