godprotocol
Version:
A distributed computing environment for Web 4.0 — integrating AI, decentralisation, and virtual computation.
331 lines (279 loc) • 8.33 kB
JavaScript
import Arr from "../Datatypes/arr.js";
import Num from "../Datatypes/num.js";
import Str from "../Datatypes/str.js";
import Twa from "../Datatypes/twa.js";
import Voi from "../Datatypes/voi.js";
import Bool from "../Datatypes/bool.js";
import Instance from "../Datatypes/instance.js";
import Func from "../Datatypes/func.js";
import Cls from "../Datatypes/cls.js";
import Err from "../Datatypes/err.js";
import { ops } from "./ops.js";
import Fold from "godprotocol/Instances/fold.js";
import Res from "godprotocol/Instances/response.js";
import { hash } from "godprotocol/utils/hash.js";
class Vm_utils {
constructor() {
this.ops = ops;
this.datatypes = ["string", "number", "void", "boolean", "array", "twain"];
}
gen_location = (addr) => {
return `${addr || this.account.physical_address}/${this.gen_uid(true)}`;
};
error_instance = async (err_payload, alias) => {
let { chain, manager } = this.account;
let res = await this.instantiate(
{ type: "error", ...err_payload },
{ chain }
);
if (alias) {
await (await manager.ds.folder(alias.location)).write(res);
}
};
variable = async (address, { chain, config, obj }) => {
let result;
let chn = await chain.chain(address);
let fold = await chn.folder();
if (config && config._id && config.type === "reference") {
result = {
type: "address",
value: address,
_id: config._id,
};
if (config.object) result.object = config.object;
} else
result = await fold.readone(
config && config._id ? { _id: config._id } : null
);
if (obj) result = await this.cloth(result);
return result;
};
gen_uid = (loc) => {
return `_${Math.random().toString().replace(".", "")}${
loc ? "" : "_"
}${Date.now()}`;
};
spread_properties = async (object, cls, { lists, benches }) => {
for (let m in cls.methods) {
object.methods[m] = cls.methods[m];
}
for (let p in cls.properties) {
let prop = cls.properties[p];
let res = await this.nodelist(prop);
lists.push(...res);
benches[p] = lists.length - 1;
}
};
base_classes = async (
object,
config,
{ inherited, lists, benches, chain }
) => {
for (let b = 0; b < config.base_classes.length; b++) {
let blc = config.base_classes[b];
if (inherited.includes(blc.location)) continue;
let cls = await this.cloth(await this.variable(blc.location, { chain }), {
just_content: true,
});
await this.spread_properties(object, cls, { lists, benches });
if (cls.base_classes.length)
await this.base_classes(object, cls, { inherited, chain });
}
};
retrieve = async (object, o) => {
let obj, addr;
if (object.type === "instance") {
let cls = await this.cloth({
type: "function",
address: object.cls,
// _id: object.cls_id
});
addr = await cls.get_instance(object, true);
if (o) {
obj = await this.cloth(addr);
}
} else if (["twain", "array"].includes(object.type)) {
obj = await this.cloth_content(object);
await obj.retrieve(object.entries || object.items);
addr = await obj.to_address();
} else if (object.type === "function") {
console.log(object, "in here");
// process.exit()
obj = object;
addr = await object.to_address();
} else {
obj = await this.cloth_content(object);
addr = await obj.to_address();
}
return o ? obj : addr;
};
parse_dynamic = async (literal, options = {}) => {
let { chain, config } = options;
let aircode = this.account.aircode;
let sequence = aircode.to_sequence(
JSON.stringify(literal),
chain.physical_address
);
let res = await chain.add_config(sequence[0].body[0]);
let address = await this.execute(res, { chain });
return address;
};
folder = async (fold) => {
return {
type: "folder",
repo: fold.config.repo,
value: fold.address,
_id: await this.hash(fold.address),
};
};
base_val = async (type) => {
let result;
switch (type) {
case "string":
result = "";
break;
case "number":
result = "0";
break;
case "array":
result = [];
break;
case "twain":
result = {};
break;
case "boolean":
result = false;
}
return await this.typecast(result, type, true);
};
resolve_addr = (addr) => {
if (!addr) return addr;
if (addr.startsWith("@")) {
addr = `${this.account.physical_address}/${addr.slice(2)}`;
}
return addr;
};
typecast = async (obj, type) => {
return obj;
};
_split_datapath = (datapath) => {
datapath = datapath.split("/");
return [datapath.slice(0, -1).join("/"), datapath.slice(-1)[0]];
};
voided = async () => {
return await this.statics({ type: "void" });
};
statics = async (config) => {
let addr = `${this.account.physical_address}/__$STATICS/`;
let folder = await this.account.manager.ds.folder(addr);
let value = config.type === "boolean" ? config.value : "void";
let _id = await this.hash(value);
await folder.write({ type: config.type, value, _id });
return {
value: addr,
_id,
type: "address",
};
};
err_objects = [
"ZeroDivisionError",
"MathError",
"SyntaxError",
"ValueError",
"RuntimeError",
"CompileError",
"AssertionError",
];
cloth = async (address, options = {}) => {
let { just_content } = options;
let content;
if (address.config) {
address = {
type: "function",
_id: address._id,
address: address.value,
value: address.value,
};
}
if (address.type === "address") {
if (address.value.includes("/")) {
let folder = await this.account.manager.ds.folder(address.value);
if (address.object) {
folder = await folder.folder(".configs");
}
content = await folder.readone({ _id: address._id });
} else if (address.object) {
content = { ...address, type: "function" };
}
} else if (["function", "class"].includes(address.type)) {
if (address._id && address._id === address.value) {
content = address;
} else {
let folder = await this.account.manager.ds.folder(`${address.address}`);
folder = await folder.folder(".configs");
content = await folder.readone(
address._id ? { _id: address._id } : null
);
}
}
if (just_content) return content;
if (content) {
content = await this.cloth_content(content);
content.address = address.value;
if (address.is_literal && content.type === "twain")
content.is_literal = true;
}
return content;
};
cloth_content = async (content, options) => {
let obj;
if (!content) return content;
switch (content.type) {
case "number":
obj = new Num(content, this.account);
break;
case "string":
obj = new Str(content, this.account);
break;
case "boolean":
obj = new Bool(content, this.account);
break;
case "void":
obj = new Voi(content, this.account);
break;
case "array":
obj = new Arr(content, this.account);
break;
case "twain":
obj = new Twa(content, this.account);
break;
case "instance":
obj = new Instance(content, this.account);
break;
case "function":
obj = new Func(content, this.account);
break;
case "folder":
obj = new Fold(content, this.account);
break;
case "folder_response":
obj = new Res(content, this.account);
break;
case "class":
obj = new Cls(content, this.account);
break;
case "error":
obj = new Err(content, this.account);
break;
default:
obj = await this.cloth(content);
break;
}
return await obj.sync(options);
};
hash = async (value, alg) => {
if (typeof value !== "string") value = JSON.stringify(value);
return hash(value, alg);
};
}
export default Vm_utils;