UNPKG

godprotocol

Version:
266 lines (224 loc) 7.76 kB
import Vm_utils from "../utils/vm_utils"; class Callable extends Vm_utils { constructor() { super(); this.objects = new Object(); } parse_aircode = async (result, { config, chain }) => { if (result == null) result = "void"; let res = await this.account.compiler.to_sequence( JSON.stringify(result), config.location.split("/").slice(2).join("/") )[0].body[0]; await chain.add_config(res); result = await this.execute(res, { chain }); return result; }; resolve_address = async (path, chain) => { let oracle = this.account.manager.oracle, fs = oracle.fs; if (typeof path !== "string") { return path; } if (path == "g") throw new Error(); let conf = await fs.read(`${path}/.config`), value; if (!conf.current) { value = await fs.read(`${path}/${conf.index - 1}`); value = JSON.parse(value.content); } else value = await fs.read(`${path}/${conf.current}`); value.path = path; return value; }; instantiate = async (config, { chain, hash, pure }) => { let instance_chain = await chain.chain( config.type === "void" ? config.value : config.location ); let uid = this.gen_uid(); if (config.type === "twain") { if (!pure) { for (let p in config.value) { let pair = config.value[p]; pair[0] = (await this.execute(pair[0], { chain })).value; pair[1] = (await this.execute(pair[1], { chain })).value; } } config.value = JSON.stringify(config.value); } else if (config.type === "array") { if (!pure) { for (let i = 0; i < config.value.length; i++) { let item = config.value[i]; config.value[i] = (await this.execute(item, { chain })).value; } } config.value = JSON.stringify(config.value); } let res = await instance_chain.write( { content: config.value, __classifier__: config.type, uid }, { hash, is_instance: true } ); return res; }; operate_result = async (value, call_config, chain) => { let result; if (value && value.error) { result = value; } else if (value && value.type === "address") { result = value; } else result = await this.parse_aircode(value, { config: call_config, chain }); return result; }; object_identifier = async (call_config, chain) => { let { identifier } = call_config, result, oracle = this.account.manager.oracle; let conf = await oracle.fs.read(`${identifier.object}/.config`); let obj = await oracle.fs.read(`${identifier.object}/${conf.current}`); let res = await this.cloth_content({ ...obj, path: identifier.object }); let classifier = await res.get("__classifier__"); if (this.datatypes.includes(classifier)) { for (let a = 0; a < call_config.arguments.length; a++) call_config.arguments[a] = await this.execute( call_config.arguments[a], { chain, cloth: true } ); let value = await res.operate(identifier.value, call_config.arguments, { classifier, config: call_config, chain, }); result = await this.operate_result(value, call_config, chain); } else { let conf = await oracle.fs.read(`${identifier.value}/.config`); conf = await oracle.fs.read(`${identifier.value}/${conf.index - 1}`); let content = JSON.parse(conf.content); let val = await this.execute(content, { chain, call_config: { ...call_config, object: { type: "address", value: identifier.object }, }, }); result = val; } return result; }; execute_call = async (call_config, { chain, obj }) => { let { identifier, arguments: args } = call_config, result; if (typeof identifier !== "string") { if (identifier.object) { result = await this.object_identifier(call_config, chain); } else { let conf = await this.read_config(identifier.value); if (!["function", "class"].includes(conf.type)) { conf = await obj.get(identifier.prev_name, { obj: identifier.prev_name, }); conf = await this.resolve_address(conf.value); } result = await this.execute(conf, { call_config, chain }); } } else if (identifier.includes("/")) { let oracle = this.account.manager.oracle; let i_chain = identifier.startsWith(this.account.manager.path) ? { path: identifier } : await chain.chain(identifier); let conf = await oracle.fs.read(`${i_chain.path}/.config`); if (conf.sibling) { let config = await oracle.fs.read(conf.sibling); if (config.content.type === "address") { if (config.content.object) { result = await this.object_identifier( { ...call_config, identifier: config.content }, chain ); } else { let iconf = await oracle.fs.read(`${config.content.value}/.config`); let configg = await oracle.fs.read( `${config.content.value}/${iconf.index - 1}` ); result = await this.execute(JSON.parse(configg.content), { call_config, chain, }); } } } else if (conf.current) { let iconf = await oracle.fs.read(`${conf.current}/.config`); let config = await oracle.fs.read(`${conf.current}/${iconf.index - 1}`); result = await this.execute(JSON.parse(config.content), { call_config, chain, }); } else { let config = await oracle.fs.read( `${call_config.identifier}/${conf.index - 1}` ); result = await this.execute(JSON.parse(config.content), { call_config, chain, }); } } else { if (this.datatypes.includes(identifier)) { } else { let { callable, config } = await this.callable(identifier); let data = {}; for (let a = 0; a < args.length; a++) { let param; let arg = args[a]; if (arg.identifier) { } else { param = config.parameters[arg.position]; if (!param) { let lst_param = config.parameters.slice(-1)[0]; if (lst_param.spread) param = lst_param; } } let res = await this.execute(arg, { chain, cloth: true }); if (param.spread) { let arr = data[param.name]; if (!arr) { arr = new Array(); data[param.name] = arr; } arr.push(res); } else data[param.name] = res; } result = await callable(data, { vm: this, config, chain }); if (["Twain", "exit", "render"].includes(identifier)) { } else result = await this.parse_aircode(result, { config: call_config, chain, }); } } return result; }; callable = async (name) => { let object = this.objects[name]; return object; }; set = (name, config) => { this.objects[name] = config; }; native_components = async (config, chain) => { let props = await this.execute(config.props, { chain, cloth: true }); let children = new Array(); for (let c = 0; c < config.children.length; c++) { let child = config.children[c]; let res = await this.execute(child, { chain, cloth: true }); children.push(await res.literal()); } let obj = { name: config.name, props: await props.literal(), children, }; return obj; }; } export default Callable;