separate the idea of misty actor and scene tree actor
Some checks failed
Build and Deploy / build-macos (push) Failing after 5s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / build-linux (push) Failing after 1m30s
Build and Deploy / package-dist (push) Has been skipped
Build and Deploy / deploy-itch (push) Has been skipped
Build and Deploy / deploy-gitea (push) Has been skipped

This commit is contained in:
2025-05-23 12:20:47 -05:00
parent efd98460c5
commit b42eec96f6
9 changed files with 422 additions and 447 deletions

View File

@@ -327,6 +327,7 @@ function joinServer() {
var os = use('os')
var actor = use('actor')
for (var i in actor) console.log(i)
// Set up IO actor subscription
var ioguy = {

View File

@@ -23,12 +23,6 @@ prosperon.dispatch = function(type, data) {
var os = use_embed('os')
var actor_mod = use_embed('actor')
var tracy = use_embed('tracy')
os.trace = true;
if (os.trace)
tracy.level(1);
var js = use_embed('js')
@@ -46,19 +40,6 @@ prosperon.on('SIGSEGV', function() {
os.exit(1)
})
Object.defineProperty(Function.prototype, "hashify", {
value: function () {
var hash = new Map()
var fn = this
function hashified(...args) {
var key = args[0]
if (!hash.has(key)) hash.set(key, fn(...args))
return hash.get(key)
}
return hashified
},
})
var io = use_embed('io')
globalThis.console = use_embed('console')
@@ -70,7 +51,7 @@ var resources = js.eval(RESPATH, `(function setup_resources(){${content}})`).cal
var use_cache = {}
use_cache[resources.canonical('resources.js')] = resources
use_cache['resources'] = resources
function print_api(obj) {
for (var prop in obj) {
@@ -86,61 +67,14 @@ function print_api(obj) {
prosperon.PATH = [
"/",
"scripts/modules/",
"scripts/modules/ext/",
"scripts/modules/"
]
// path is the path of a module or script to resolve
var script_fn = function script_fn(path, args) {
var parsed = {}
var file = resources.find_script(path)
if (!file) {
parsed.module_ret = bare_load(path)
if (!parsed.module_ret) throw new Error(`Module ${path} could not be created`)
return parsed
}
var content = io.slurp(file)
var parsed = parse_file(content, file)
var module_name = file.name()
parsed.module_ret = bare_load(path)
parsed.module_ret ??= {}
if (parsed.module) {
// Create a context object with args
var context = Object.create(parsed.module_ret)
context.__args__ = args || []
var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; var exports = {}; var module = {exports: exports}; var define = undefined; var arg = this.__args__; ${parsed.module}})`
var module_fn = js.eval(file, mod_script)
parsed.module_ret = module_fn.call(context)
if (parsed.module_ret === undefined || parsed.module_ret === null)
throw new Error(`Module ${module_name} must return a value`)
parsed.module_fn = module_fn
}
parsed.program ??= ""
var prog_script = `(function use_${module_name}($_) { var self = this; var $ = this.__proto__; ${parsed.program}})`
parsed.prog_fn = js.eval(file, prog_script)
return parsed
}.hashify()
function bare_load(file) {
try {
return use_embed(file)
} catch (e) { }
try {
return use_dyn(file + so_ext)
} catch(e) { }
return undefined
}
var res_cache = {}
function console_rec(category, priority, line, file, msg) {
return `[${file}:${line}: [${category} ${priority}]: ${msg}\n`
var now = time.now()
var id = prosperon.name ? prosperon.name : prosperon.id
@@ -149,12 +83,7 @@ function console_rec(category, priority, line, file, msg) {
return `[${id}] [${time.text(now, "mb d yyyy h:nn:ss")}] ${file}:${line}: [${category} ${priority}]: ${msg}\n`
}
io.mkdir('.prosperon')
var logfile //= io.open('.prosperon/log.txt')
function pprint(msg, lvl = 0) {
if (!logfile) return
var file = "nofile"
var line = 0
@@ -169,11 +98,6 @@ function pprint(msg, lvl = 0) {
}
var fmt = console_rec("script", lvl, line, file, msg)
console.print(fmt)
if (logfile)
logfile.write(fmt)
if (tracy) tracy.message(fmt)
}
function format_args(...args) {
@@ -248,64 +172,28 @@ var fnname = "base"
script = `(function ${fnname}() { ${script}; })`
js.eval(BASEPATH, script)()
function add_timer(obj, fn, seconds) {
var timers = obj[TIMERS]
var stop = function () {
if (!timer) return
timers.delete(stop)
timer.fn = undefined
timer = undefined
}
function execute() {
if (fn) timer.remain = fn(stop.seconds)
if (!timer) return
if (!timer.remain) stop()
else stop.seconds = timer.remain
}
// var timer = os.make_timer(execute)
timer.remain = seconds
stop.remain = seconds
stop.seconds = seconds
timers.push(stop)
return stop
}
var DEAD = Symbol()
var GARBAGE = Symbol()
var FILE = Symbol()
var TIMERS = Symbol()
var REGGIES = Symbol()
var UNDERLINGS = Symbol()
var OVERLING = Symbol()
var actor = {}
globalThis.actor = actor
var so_ext
switch(os.platform()) {
case 'Windows':
so_ext = '.dll'
break
default:
so_ext = '.so'
break
}
var use_cache = {}
var inProgress = {}
var loadingStack = []
globalThis.use = function use(file, ...args) {
// If we've already begun loading this file in this chain, show the cycle
// Normalize the request - remove .js extension if present
var request_name = file
if (file.endsWith('.js')) {
request_name = file.substring(0, file.length - 3)
}
// Check cache first - both 'transform' and 'transform.js' should return same cached value
for (var cached_key in use_cache) {
if (cached_key === file || cached_key === request_name ||
cached_key === request_name + '.js' ||
(cached_key.endsWith('.js') && cached_key.substring(0, cached_key.length - 3) === request_name)) {
return use_cache[cached_key]
}
}
// Check for circular dependencies
if (loadingStack.includes(file)) {
// Find where in the stack this file first appeared
let cycleIndex = loadingStack.indexOf(file)
// Extract just the modules in the cycle
let cyclePath = loadingStack.slice(cycleIndex).concat(file)
throw new Error(
@@ -314,292 +202,81 @@ globalThis.use = function use(file, ...args) {
`Cycle specifically: ${cyclePath.join(" -> ")}`
)
}
// Already fully loaded? Return it
if (use_cache[file]) {
return use_cache[file]
// Try to find the script file
var path = resources.find_script(request_name)
// Check if there's an embedded module
var embed_mod = use_embed(request_name)
// If no script and no embedded module, error
if (!path && !embed_mod) {
throw new Error(`Module ${file} could not be found`)
}
// If it's loading (but not on the stack), mark it as a new chain entry
// (This is optional if you just rely on loadingStack.
// But if you'd like a simple “already loading” check, keep 'inProgress'.)
if (inProgress[file]) {
// If only embedded module exists, return it
if (!path && embed_mod) {
use_cache[file] = embed_mod
use_cache[request_name] = embed_mod
if (file !== request_name) {
use_cache[request_name + '.js'] = embed_mod
}
return embed_mod
}
// If we have a script path, check for circular dependency
if (inProgress[path]) {
throw new Error(`Circular dependency detected while loading "${file}"`)
}
inProgress[file] = true
// Push onto loading stack for chain tracking
inProgress[path] = true
loadingStack.push(file)
// Actually load the module with arguments
var mod = script_fn(file, args)
// Done loading, remove from the chain and mark as loaded
// Load and execute the script
var script = io.slurp(path)
var mod_name = path.name()
// Create context - if embedded module exists, script extends it
var context = {}
if (embed_mod)
context.__proto__ = embed_mod
var mod_script = `(function setup_${mod_name}_module(arg){${script};})`
var fn = js.eval(path, mod_script)
// Call the script - pass embedded module as 'this' if it exists
var ret = fn.call(context, args)
// If script doesn't return anything, check if we have embedded module
if (!ret && embed_mod) {
ret = embed_mod
} else if (!ret) {
throw new Error(`Use must be used with a module, but ${path} doesn't return a value`)
}
loadingStack.pop()
delete inProgress[file]
// Cache and return
use_cache[file] = mod.module_ret
return use_cache[file]
delete inProgress[path]
// Cache under all possible keys
use_cache[path] = ret
use_cache[file] = ret
use_cache[request_name] = ret
if (file !== request_name && !file.endsWith('.js')) {
use_cache[request_name + '.js'] = ret
}
return ret
}
globalThis.json = use('json')
var time = use('time')
function parse_file(content, file) {
if (!content) return {}
if (!/^\s*---\s*$/m.test(content)) {
var part = content.trim()
if (part.match(/return\s+[^;]+;?\s*$/)) {
return { module: part }
}
return { program: part }
}
var parts = content.split(/\n\s*---\s*\n/)
var module = parts[0]
if (!/\breturn\b/.test(module))
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.`)
try {
new Function(module)()
} catch (e) {
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.\n` + e.message)
}
var pad = '\n'.repeat(module.split('\n').length + 4)
return {
module,
program: pad + parts[1]
}
}
globalThis.Register = {
registries: [],
add_cb(name) {
var n = {}
var fns = []
n.register = function (fn, oname) {
if (typeof fn !== 'function') return
var dofn = function (...args) {
fn(...args)
}
Object.defineProperty(dofn, 'name', {value:`do_${oname}`})
var left = 0
var right = fns.length - 1
dofn.layer = fn.layer
dofn.layer ??= 0
while (left <= right) {
var mid = Math.floor((left + right) / 2)
if (fns[mid] === dofn.layer) {
left = mid
break
} else if (fns[mid].layer < dofn.layer) left = mid + 1
else right = mid - 1
}
fns.splice(left, 0, dofn)
return function () {
fns.delete(dofn)
}
}
prosperon[name] = function (...args) {
fns.forEach(fn => {
fn(...args)
})
}
Object.defineProperty(prosperon[name], 'name', {value:name})
prosperon[name].fns = fns
n.clear = function () {
fns = []
}
Register[name] = n
Register.registries[name] = n
return n
},
}
Register.pull_registers = function pull_registers(obj) {
var reggies = []
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
reggies.push(reg)
}
return reggies
}
Register.register_obj = function register_obj(obj, reg) {
var fn = obj[reg].bind(obj)
fn.layer = obj[reg].layer
var name = obj.ur ? obj.ur.name : obj.toString()
obj[TIMERS].push(Register.registries[reg].register(fn, name))
if (!obj[reg].name) Object.defineProperty(obj[reg], 'name', {value:`${obj._file}_${reg}`})
}
Register.check_registers = function check_registers(obj) {
if (obj[REGGIES]) {
if (obj[REGGIES].length == 0) return
for (var reg of obj[REGGIES])
Register.register_obj(obj,reg)
return
}
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
Register.register_obj(obj,reg)
}
}
Register.add_cb("appupdate")
Register.add_cb("update").doc = "Called once per frame."
Register.add_cb("physupdate")
Register.add_cb("gui")
Register.add_cb("hud")
Register.add_cb("draw")
Register.add_cb("imgui")
Register.add_cb("app")
function cant_kill() {
throw Error("Can't kill an object in its spawning code. Move the kill command to awake.")
}
actor.toString = function() { return this[FILE] }
actor.spawn = function spawn(script, config, actor_context) {
if (this[DEAD]) throw new Error("Attempting to spawn on a dead actor")
var prog
if (!script) {
prog = {}
prog.module_ret = {}
prog.prog_fn = function() {}
} else {
prog = script_fn(script)
if (!prog.prog_fn) throw new Error(`Script ${script} is not an actor script or has no actor component`)
}
var underling
prog.module_ret.__proto__ = actor
underling = Object.create(prog.module_ret)
underling[OVERLING] = this
underling[FILE] = script
underling[TIMERS] = []
underling[UNDERLINGS] = new Set()
// Make $_ available to the actor (either passed context or the engine's $_)
var actor_dollar = actor_context || $_
Object.defineProperty(underling, '$_', {
value: actor_dollar,
writable:false,
enumerable:false,
configurable:false
})
Object.defineProperty(underling, 'overling', {
get() { return this[OVERLING] },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'underlings', {
get() { return new Set(this[UNDERLINGS]) },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'spawn', {
value: function(script, config) {
return actor.spawn.call(this, script, config, actor_dollar)
},
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'kill', {
value: actor.kill,
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'delay', {
value: actor.delay,
writable:false,
enumerable:true,
configurable:false
})
try {
// Pass $_ as a parameter to actor scripts
prog.prog_fn.call(underling, actor_dollar)
} catch(e) { throw e; }
if (underling[DEAD]) return undefined;
if (typeof config === 'object') Object.assign(underling, config)
if (!underling[REGGIES])
underling.__proto__[REGGIES] = Register.pull_registers(underling)
Register.check_registers(underling)
if (underling.awake) underling.awake()
this[UNDERLINGS].add(underling)
if (underling.tag) act.tag_add(underling.tag, underling)
underling[GARBAGE] = underling.garbage
return underling
}
actor.clear = function actor_clear() {
this[UNDERLINGS].forEach(p => {
p.kill()
})
this[UNDERLINGS].clear()
}
var input = use('input')
actor.kill = function kill() {
if (this[DEAD]) return
this[DEAD] = true
this[TIMERS].slice().forEach(t => t())
delete this[TIMERS]
input.do_uncontrol(this)
this.clear()
this[OVERLING][UNDERLINGS].delete(this)
delete this[UNDERLINGS]
if (typeof this.garbage === "function") this.garbage()
if (typeof this.then === "function") this.then()
act.tag_clear_guid(this)
}
actor.kill.doc = `Remove this actor and all its underlings from existence.`
actor.delay = function(fn, seconds) {
if (this[DEAD]) return
add_timer(this, fn, seconds)
}
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`
var act = use('actor')
actor[UNDERLINGS] = new Set()
globalThis.mixin("color")
var DOCPATH = 'scripts/core/doc.js'
var script = io.slurp(DOCPATH)
var fnname = "doc"
script = `(function ${fnname}() { ${script}; })`
//js.eval(DOCPATH, script)()
/*
When handling a message, the message appears like this:
@@ -937,10 +614,7 @@ if (!prosperon.args.program)
os.exit(1)
if (typeof prosperon.args.program !== 'string')
prosperon.args.program = 'main.js';
// Spawn the root actor with access to $_
actor.spawn.call({[UNDERLINGS]: new Set()}, prosperon.args.program, undefined)
prosperon.args.program = 'main.js';
function destroyself() {
console.log(`Got the message to destroy self.`)
@@ -1023,4 +697,11 @@ function enet_check()
send_messages();
enet_check();
// Finally, run the program
var prog = io.slurp(prosperon.args.program)
var prog_script = `(function ${prosperon.args.program.name()}($_) { ${prog} })`
var val = js.eval(prosperon.args.program, prog_script)($_)
if (val)
throw new Error('Program must not return anything');
})()

View File

@@ -73,9 +73,6 @@ Cmdline.register_order(
else
app = actor.spawn("nogame.js")
// rm actor so it can't be tampered
globalThis.actor = undefined
var loop = use('loop')
while(1) loop.step();
},

View File

@@ -459,7 +459,6 @@ var sysfont = graphics.get_font('fonts/c64.ttf', 8)
draw.text = function text(text, rect, font = sysfont, size = 0, color = Color.white, wrap = 0, pipeline) {
if (typeof font === 'string') font = graphics.get_font(font)
var mesh = graphics.make_text_buffer(text, rect, 0, color, wrap, font)
console.log(json.encode(mesh))
render.geometry(font, mesh)
}
draw.text[prosperon.DOC] = `

View File

@@ -1,31 +0,0 @@
return {
get pos() {
if (!this.transform) return
return this.transform.pos;
},
set pos(x) {
this.transform.pos = x;
},
get angle() {
return this.transform.angle;
},
set angle(x) {
this.transform.angle = x;
},
get scale() {
return this.transform.scale;
},
set scale(x) {
this.transform.scale = x;
},
move(vec) {
this.pos = this.pos.add(vec);
},
rotate(x) {
this.transform.rotate([0, 0, -1],x);
},
grow(vec) {
if (typeof vec === "number") vec = [vec, vec];
this.scale = this.scale.map((x, i) => x * vec[i]);
},
}

View File

@@ -19,6 +19,7 @@ var io = use('io');
var render = use('render');
var actor = use('actor');
var transform = use('transform');
var gameConfig = {};
var gameDir = "";

View File

@@ -2,6 +2,19 @@ var io = use_embed('io');
var miniz = use_embed('miniz');
var os = use_embed('os');
Object.defineProperty(Function.prototype, "hashify", {
value: function () {
var hash = new Map()
var fn = this
function hashified(...args) {
var key = args[0]
if (!hash.has(key)) hash.set(key, fn(...args))
return hash.get(key)
}
return hashified
},
})
// Merge of the old resources.js and packer.js functionalities
var Resources = {}

View File

@@ -1,4 +1,259 @@
var ex = this
var input = use('input')
var DEAD = Symbol()
var GARBAGE = Symbol()
var FILE = Symbol()
var TIMERS = Symbol()
var REGGIES = Symbol()
var UNDERLINGS = Symbol()
var OVERLING = Symbol()
function add_timer(obj, fn, seconds) {
var timers = obj[TIMERS]
var stop = function () {
if (!timer) return
timers.delete(stop)
timer.fn = undefined
timer = undefined
}
function execute() {
if (fn) timer.remain = fn(stop.seconds)
if (!timer) return
if (!timer.remain) stop()
else stop.seconds = timer.remain
}
// var timer = os.make_timer(execute)
timer.remain = seconds
stop.remain = seconds
stop.seconds = seconds
timers.push(stop)
return stop
}
globalThis.Register = {
registries: [],
add_cb(name) {
var n = {}
var fns = []
n.register = function (fn, oname) {
if (typeof fn !== 'function') return
var dofn = function (...args) {
fn(...args)
}
Object.defineProperty(dofn, 'name', {value:`do_${oname}`})
var left = 0
var right = fns.length - 1
dofn.layer = fn.layer
dofn.layer ??= 0
while (left <= right) {
var mid = Math.floor((left + right) / 2)
if (fns[mid] === dofn.layer) {
left = mid
break
} else if (fns[mid].layer < dofn.layer) left = mid + 1
else right = mid - 1
}
fns.splice(left, 0, dofn)
return function () {
fns.delete(dofn)
}
}
prosperon[name] = function (...args) {
fns.forEach(fn => {
fn(...args)
})
}
Object.defineProperty(prosperon[name], 'name', {value:name})
prosperon[name].fns = fns
n.clear = function () {
fns = []
}
Register[name] = n
Register.registries[name] = n
return n
},
}
Register.pull_registers = function pull_registers(obj) {
var reggies = []
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
reggies.push(reg)
}
return reggies
}
Register.register_obj = function register_obj(obj, reg) {
var fn = obj[reg].bind(obj)
fn.layer = obj[reg].layer
var name = obj.ur ? obj.ur.name : obj.toString()
obj[TIMERS].push(Register.registries[reg].register(fn, name))
if (!obj[reg].name) Object.defineProperty(obj[reg], 'name', {value:`${obj._file}_${reg}`})
}
Register.check_registers = function check_registers(obj) {
if (obj[REGGIES]) {
if (obj[REGGIES].length == 0) return
for (var reg of obj[REGGIES])
Register.register_obj(obj,reg)
return
}
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
Register.register_obj(obj,reg)
}
}
Register.add_cb("appupdate")
Register.add_cb("update").doc = "Called once per frame."
Register.add_cb("physupdate")
Register.add_cb("gui")
Register.add_cb("hud")
Register.add_cb("draw")
Register.add_cb("imgui")
Register.add_cb("app")
var actor = {}
actor.toString = function() { return this[FILE] }
actor.spawn = function spawn(script, config, actor_context) {
if (this[DEAD]) throw new Error("Attempting to spawn on a dead actor")
var prog
if (!script) {
prog = {}
prog.module_ret = {}
prog.prog_fn = function() {}
} else {
prog = script_fn(script)
if (!prog.prog_fn) throw new Error(`Script ${script} is not an actor script or has no actor component`)
}
var underling
prog.module_ret.__proto__ = actor
underling = Object.create(prog.module_ret)
underling[OVERLING] = this
underling[FILE] = script
underling[TIMERS] = []
underling[UNDERLINGS] = new Set()
// Make $_ available to the actor (either passed context or the engine's $_)
var actor_dollar = actor_context || $_
Object.defineProperty(underling, '$_', {
value: actor_dollar,
writable:false,
enumerable:false,
configurable:false
})
Object.defineProperty(underling, 'overling', {
get() { return this[OVERLING] },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'underlings', {
get() { return new Set(this[UNDERLINGS]) },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'spawn', {
value: function(script, config) {
return actor.spawn.call(this, script, config, actor_dollar)
},
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'kill', {
value: actor.kill,
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'delay', {
value: actor.delay,
writable:false,
enumerable:true,
configurable:false
})
try {
// Pass $_ as a parameter to actor scripts
prog.prog_fn.call(underling, actor_dollar)
} catch(e) { throw e; }
if (underling[DEAD]) return undefined;
if (typeof config === 'object') Object.assign(underling, config)
if (!underling[REGGIES])
underling.__proto__[REGGIES] = Register.pull_registers(underling)
Register.check_registers(underling)
if (underling.awake) underling.awake()
this[UNDERLINGS].add(underling)
if (underling.tag) act.tag_add(underling.tag, underling)
underling[GARBAGE] = underling.garbage
return underling
}
actor.clear = function actor_clear() {
this[UNDERLINGS].forEach(p => {
p.kill()
})
this[UNDERLINGS].clear()
}
actor.kill = function kill() {
if (this[DEAD]) return
this[DEAD] = true
this[TIMERS].slice().forEach(t => t())
delete this[TIMERS]
input.do_uncontrol(this)
this.clear()
this[OVERLING][UNDERLINGS].delete(this)
delete this[UNDERLINGS]
if (typeof this.garbage === "function") this.garbage()
if (typeof this.then === "function") this.then()
act.tag_clear_guid(this)
}
actor.kill.doc = `Remove this actor and all its underlings from existence.`
actor.delay = function(fn, seconds) {
if (this[DEAD]) return
add_timer(this, fn, seconds)
}
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`
actor[UNDERLINGS] = new Set()
ex[prosperon.DOC] = `
A set of utilities for iterating over a hierarchy of actor-like objects, as well
as managing tag-based lookups. Objects are assumed to have a "objects" property,
@@ -75,4 +330,68 @@ ex.objects_with_tag[prosperon.DOC] = `
Retrieve all objects currently tagged with the specified tag.
`
function parse_file(content, file) {
if (!content) return {}
if (content.match()
if (!/^\s*---\s*$/m.test(content)) {
var part = content.trim()
if (part.match(/return\s+[^;]+;?\s*$/)) {
return { module: part }
}
return { program: part }
}
var parts = content.split(/\n\s*---\s*\n/)
var module = parts[0]
if (!/\breturn\b/.test(module))
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.`)
try {
new Function(module)()
} catch (e) {
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.\n` + e.message)
}
var pad = '\n'.repeat(module.split('\n').length + 4)
return {
module,
program: pad + parts[1]
}
}
// path is the path of a module or script to resolve
var script_fn = function script_fn(path, args) {
var parsed = {}
var file = resources.find_script(path)
if (!file) {
parsed.module_ret = bare_load(path)
if (!parsed.module_ret) throw new Error(`Module ${path} could not be created`)
return parsed
}
var content = io.slurp(file)
var parsed = parse_file(content, file)
var module_name = file.name()
parsed.module_ret = bare_load(path)
parsed.module_ret ??= {}
if (parsed.module) {
// Create a context object with args
var context = Object.create(parsed.module_ret)
context.__args__ = args || []
var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; var exports = {}; var module = {exports: exports}; var define = undefined; var arg = this.__args__; ${parsed.module}})`
var module_fn = js.eval(file, mod_script)
parsed.module_ret = module_fn.call(context)
if (parsed.module_ret === undefined || parsed.module_ret === null)
throw new Error(`Module ${module_name} must return a value`)
parsed.module_fn = module_fn
}
parsed.program ??= ""
var prog_script = `(function use_${module_name}($_) { var self = this; var $ = this.__proto__; ${parsed.program}})`
parsed.prog_fn = js.eval(file, prog_script)
return parsed
}.hashify()
return ex

View File

@@ -1906,9 +1906,7 @@ JSC_CCALL(os_guid,
return JS_NewString(js,guid_str);
)
JSC_SCALL(console_print,
printf("%s", str);
)
JSC_SCALL(console_print, printf("%s", str); )
static const JSCFunctionListEntry js_console_funcs[] = {
MIST_FUNC_DEF(console,print,1),
@@ -2762,9 +2760,6 @@ JSC_SCALL(os_use_embed,
break;
}
}
if (JS_IsUndefined(ret))
ret = JS_ThrowReferenceError(js,"Library %s could not be found embedded", str);
)
JSC_SCALL(os_use_dyn,