//Divide the two strings representing decimal values std::string decimalDiv(std::string a, std::string b) { std::string c = b; if (decimalGt(c, a)) return "0"; int zeroes = -1; while (decimalGt(a, c, true)) { zeroes += 1; c = c + "0"; } c = c.substr(0, c.size() - 1); std::string quot = "0"; while (decimalGt(a, c, true)) { a = decimalSub(a, c); quot = decimalAdd(quot, "1"); } for (int i = 0; i < zeroes; i++) quot += "0"; return decimalAdd(quot, decimalDiv(a, b)); }
// Populate an svObj with the arguments needed to determine // the storage position of a node svObj getStorageVars(svObj pre, Node node, std::string prefix, int index) { Metadata m = node.metadata; if (!pre.globalOffset.size()) pre.globalOffset = "0"; std::vector<Node> h; std::vector<std::string> coefficients; // Array accesses or atoms if (node.val == "access" || node.type == TOKEN) { std::string tot = "1"; h = listfyStorageAccess(node); coefficients.push_back("1"); for (unsigned i = h.size() - 1; i >= 1; i--) { // Array sizes must be constant or at least arithmetically // evaluable at compile time if (!isPureArithmetic(h[i])) err("Array size must be fixed value", m); // Create a list of the coefficient associated with each // array index coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); } } // Tuples else { int startc; // Handle the (fun <fun_astnode> args...) case if (node.val == "fun") { startc = 1; h = listfyStorageAccess(node.args[0]); } // Handle the (<fun_name> args...) case, which // the serpent parser produces when the function // is a simple name and not a complex astnode else { startc = 0; h = listfyStorageAccess(token(node.val, m)); } svObj sub = pre; sub.globalOffset = "0"; // Evaluate tuple elements recursively for (unsigned i = startc; i < node.args.size(); i++) { sub = getStorageVars(sub, node.args[i], prefix+h[0].val.substr(2)+".", i-startc); } coefficients.push_back(sub.globalOffset); for (unsigned i = h.size() - 1; i >= 1; i--) { // Array sizes must be constant or at least arithmetically // evaluable at compile time if (!isPureArithmetic(h[i])) err("Array size must be fixed value", m); // Create a list of the coefficient associated with each // array index coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); } pre.offsets = sub.offsets; pre.coefficients = sub.coefficients; pre.nonfinal = sub.nonfinal; pre.nonfinal[prefix+h[0].val.substr(2)] = true; } pre.coefficients[prefix+h[0].val.substr(2)] = coefficients; pre.offsets[prefix+h[0].val.substr(2)] = pre.globalOffset; pre.indices[prefix+h[0].val.substr(2)] = index; if (decimalGt(tt176, coefficients.back())) pre.globalOffset = decimalAdd(pre.globalOffset, coefficients.back()); return pre; }