bootstrap
This commit is contained in:
@@ -123,37 +123,51 @@ function use_fn(path) {
|
|||||||
// Helper to load engine.cm and run it with given env
|
// Helper to load engine.cm and run it with given env
|
||||||
function load_engine(env) {
|
function load_engine(env) {
|
||||||
var engine_path = core_path + '/internal/engine.mach'
|
var engine_path = core_path + '/internal/engine.mach'
|
||||||
|
var data = null
|
||||||
|
var engine_src = null
|
||||||
|
var engine_ast = null
|
||||||
if (fd.is_file(engine_path)) {
|
if (fd.is_file(engine_path)) {
|
||||||
var data = fd.slurp(engine_path)
|
data = fd.slurp(engine_path)
|
||||||
return mach_load(data, env)
|
return mach_load(data, env)
|
||||||
}
|
}
|
||||||
engine_path = core_path + '/internal/engine.cm'
|
engine_path = core_path + '/internal/engine.cm'
|
||||||
var engine_src = text(fd.slurp(engine_path))
|
engine_src = text(fd.slurp(engine_path))
|
||||||
var engine_ast = analyze(engine_src, engine_path)
|
engine_ast = analyze(engine_src, engine_path)
|
||||||
return run_ast('engine', engine_ast, env)
|
return run_ast('engine', engine_ast, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect mode and route
|
// Detect mode and route
|
||||||
// CLI mode has 'args'; actor spawn mode has 'init'
|
// CLI mode has 'args'; actor spawn mode has 'init'
|
||||||
|
var program = null
|
||||||
|
var user_args = []
|
||||||
|
var _j = 0
|
||||||
|
var script_file = null
|
||||||
|
var script = null
|
||||||
|
var ast = null
|
||||||
|
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
// CLI mode — run script directly
|
// CLI mode — run script directly
|
||||||
var program = args[0]
|
program = args[0]
|
||||||
var user_args = []
|
_j = 1
|
||||||
var _j = 1
|
|
||||||
while (_j < length(args)) {
|
while (_j < length(args)) {
|
||||||
push(user_args, args[_j])
|
push(user_args, args[_j])
|
||||||
_j = _j + 1
|
_j = _j + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var script_file = program
|
script_file = program
|
||||||
if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm'))
|
if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm'))
|
||||||
script_file = program + '.cm'
|
script_file = program + '.cm'
|
||||||
|
|
||||||
|
// Search CWD then core_path, trying .cm then .ce
|
||||||
if (!fd.is_file(script_file))
|
if (!fd.is_file(script_file))
|
||||||
script_file = core_path + '/' + program + '.cm'
|
script_file = core_path + '/' + program + '.cm'
|
||||||
|
if (!fd.is_file(script_file))
|
||||||
|
script_file = program + '.ce'
|
||||||
|
if (!fd.is_file(script_file))
|
||||||
|
script_file = core_path + '/' + program + '.ce'
|
||||||
|
|
||||||
var script = text(fd.slurp(script_file))
|
script = text(fd.slurp(script_file))
|
||||||
var ast = analyze(script, script_file)
|
ast = analyze(script, script_file)
|
||||||
run_ast(program, ast, {use: use_fn, args: user_args, json: json})
|
run_ast(program, ast, {use: use_fn, args: user_args, json: json})
|
||||||
} else {
|
} else {
|
||||||
// Actor spawn mode — load engine.cm with full actor env
|
// Actor spawn mode — load engine.cm with full actor env
|
||||||
|
|||||||
Binary file not shown.
@@ -6,17 +6,13 @@ var SYSYM = '__SYSTEM__'
|
|||||||
var _cell = {}
|
var _cell = {}
|
||||||
var need_stop = false
|
var need_stop = false
|
||||||
|
|
||||||
var dylib_ext
|
|
||||||
|
|
||||||
var cases = {
|
var cases = {
|
||||||
Windows: '.dll',
|
Windows: '.dll',
|
||||||
macOS: '.dylib',
|
macOS: '.dylib',
|
||||||
Linux: '.so'
|
Linux: '.so'
|
||||||
}
|
}
|
||||||
|
|
||||||
print(os.platform())
|
var dylib_ext = cases[os.platform()]
|
||||||
|
|
||||||
dylib_ext = cases[os.platform()]
|
|
||||||
|
|
||||||
var MOD_EXT = '.cm'
|
var MOD_EXT = '.cm'
|
||||||
var ACTOR_EXT = '.ce'
|
var ACTOR_EXT = '.ce'
|
||||||
@@ -67,11 +63,14 @@ function use_core(path) {
|
|||||||
return use_cache[cache_key]
|
return use_cache[cache_key]
|
||||||
|
|
||||||
var sym = use_embed(replace(path, '/', '_'))
|
var sym = use_embed(replace(path, '/', '_'))
|
||||||
|
var result = null
|
||||||
|
var script = null
|
||||||
|
var ast = null
|
||||||
|
|
||||||
// Check for pre-compiled .mach file first
|
// Check for pre-compiled .mach file first
|
||||||
var mach_path = core_path + '/' + path + '.mach'
|
var mach_path = core_path + '/' + path + '.mach'
|
||||||
if (fd.is_file(mach_path)) {
|
if (fd.is_file(mach_path)) {
|
||||||
var result = mach_load(fd.slurp(mach_path), {use: use_core})
|
result = mach_load(fd.slurp(mach_path), {use: use_core})
|
||||||
use_cache[cache_key] = result
|
use_cache[cache_key] = result
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -79,9 +78,9 @@ function use_core(path) {
|
|||||||
// Fall back to source .cm file — compile at runtime
|
// Fall back to source .cm file — compile at runtime
|
||||||
var file_path = core_path + '/' + path + MOD_EXT
|
var file_path = core_path + '/' + path + MOD_EXT
|
||||||
if (fd.is_file(file_path)) {
|
if (fd.is_file(file_path)) {
|
||||||
var script = text(fd.slurp(file_path))
|
script = text(fd.slurp(file_path))
|
||||||
var ast = analyze(script, file_path)
|
ast = analyze(script, file_path)
|
||||||
var result = run_ast_fn('core:' + path, ast, {use: use_core})
|
result = run_ast_fn('core:' + path, ast, {use: use_core})
|
||||||
use_cache[cache_key] = result
|
use_cache[cache_key] = result
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -108,21 +107,24 @@ function is_actor(value) {
|
|||||||
var ENETSERVICE = 0.1
|
var ENETSERVICE = 0.1
|
||||||
var REPLYTIMEOUT = 60 // seconds before replies are ignored
|
var REPLYTIMEOUT = 60 // seconds before replies are ignored
|
||||||
|
|
||||||
function caller_data(depth = 0)
|
function caller_data(depth)
|
||||||
{
|
{
|
||||||
|
var _depth = depth == null ? 0 : depth
|
||||||
var file = "nofile"
|
var file = "nofile"
|
||||||
var line = 0
|
var line = 0
|
||||||
|
var md = null
|
||||||
var caller = array(Error().stack, "\n")[1+depth]
|
var m = null
|
||||||
|
|
||||||
|
var caller = array(Error().stack, "\n")[1+_depth]
|
||||||
if (caller) {
|
if (caller) {
|
||||||
var md = extract(caller, /\((.*)\:/)
|
md = extract(caller, /\((.*)\:/)
|
||||||
var m = md ? md[1] : "SCRIPT"
|
m = md ? md[1] : "SCRIPT"
|
||||||
if (m) file = m
|
if (m) file = m
|
||||||
md = extract(caller, /\:(\d*)\)/)
|
md = extract(caller, /\:(\d*)\)/)
|
||||||
m = md ? md[1] : 0
|
m = md ? md[1] : 0
|
||||||
if (m) line = m
|
if (m) line = m
|
||||||
}
|
}
|
||||||
|
|
||||||
return {file,line}
|
return {file,line}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,6 +154,9 @@ function log(name, args) {
|
|||||||
|
|
||||||
function actor_die(err)
|
function actor_die(err)
|
||||||
{
|
{
|
||||||
|
var reason = null
|
||||||
|
var unders = null
|
||||||
|
|
||||||
if (err && is_function(err.toString)) {
|
if (err && is_function(err.toString)) {
|
||||||
os.print(err.toString())
|
os.print(err.toString())
|
||||||
os.print("\n")
|
os.print("\n")
|
||||||
@@ -161,14 +166,14 @@ function actor_die(err)
|
|||||||
if (overling) {
|
if (overling) {
|
||||||
if (err) {
|
if (err) {
|
||||||
// with an err, this is a forceful disrupt
|
// with an err, this is a forceful disrupt
|
||||||
var reason = (is_proto(err, Error)) ? err.stack : err
|
reason = (is_proto(err, Error)) ? err.stack : err
|
||||||
report_to_overling({type:'disrupt', reason})
|
report_to_overling({type:'disrupt', reason})
|
||||||
} else
|
} else
|
||||||
report_to_overling({type:'stop'})
|
report_to_overling({type:'stop'})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (underlings) {
|
if (underlings) {
|
||||||
var unders = array(underlings)
|
unders = array(underlings)
|
||||||
arrfor(unders, function(id, index) {
|
arrfor(unders, function(id, index) {
|
||||||
log.console(`calling on ${id} to disrupt too`)
|
log.console(`calling on ${id} to disrupt too`)
|
||||||
$_.stop(create_actor({id}))
|
$_.stop(create_actor({id}))
|
||||||
@@ -192,9 +197,10 @@ function actor_die(err)
|
|||||||
_cell.args = init != null ? init : {}
|
_cell.args = init != null ? init : {}
|
||||||
_cell.id = "newguy"
|
_cell.id = "newguy"
|
||||||
|
|
||||||
function create_actor(desc = {id:guid()}) {
|
function create_actor(desc) {
|
||||||
|
var _desc = desc == null ? {id:guid()} : desc
|
||||||
var actor = {}
|
var actor = {}
|
||||||
actor[ACTORDATA] = desc
|
actor[ACTORDATA] = _desc
|
||||||
return actor
|
return actor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,9 +349,10 @@ REPLYTIMEOUT = config.reply_timeout
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function guid(bits = 256)
|
function guid(bits)
|
||||||
{
|
{
|
||||||
var guid = blob(bits, os.random)
|
var _bits = bits == null ? 256 : bits
|
||||||
|
var guid = blob(_bits, os.random)
|
||||||
stone(guid)
|
stone(guid)
|
||||||
return text(guid,'h')
|
return text(guid,'h')
|
||||||
}
|
}
|
||||||
@@ -427,13 +434,16 @@ $_.portal = function(fn, port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handle_host(e) {
|
function handle_host(e) {
|
||||||
|
var queue = null
|
||||||
|
var data = null
|
||||||
|
|
||||||
if (e.type == "connect") {
|
if (e.type == "connect") {
|
||||||
log.system(`connected a new peer: ${e.peer.address}:${e.peer.port}`)
|
log.system(`connected a new peer: ${e.peer.address}:${e.peer.port}`)
|
||||||
peers[`${e.peer.address}:${e.peer.port}`] = e.peer
|
peers[`${e.peer.address}:${e.peer.port}`] = e.peer
|
||||||
var queue = peer_queue.get(e.peer)
|
queue = peer_queue.get(e.peer)
|
||||||
if (queue) {
|
if (queue) {
|
||||||
arrfor(queue, (msg, index) => e.peer.send(nota.encode(msg)))
|
arrfor(queue, (msg, index) => e.peer.send(nota.encode(msg)))
|
||||||
log.system(`sent ${msg} out of queue`)
|
log.system(`sent queue out of queue`)
|
||||||
peer_queue.delete(e.peer)
|
peer_queue.delete(e.peer)
|
||||||
}
|
}
|
||||||
} else if (e.type == "disconnect") {
|
} else if (e.type == "disconnect") {
|
||||||
@@ -443,27 +453,28 @@ function handle_host(e) {
|
|||||||
})
|
})
|
||||||
log.system('portal got disconnect from ' + e.peer.address + ":" + e.peer.port)
|
log.system('portal got disconnect from ' + e.peer.address + ":" + e.peer.port)
|
||||||
} else if (e.type == "receive") {
|
} else if (e.type == "receive") {
|
||||||
var data = nota.decode(e.data)
|
data = nota.decode(e.data)
|
||||||
if (data.replycc && !data.replycc.address) {
|
if (data.replycc && !data.replycc.address) {
|
||||||
data.replycc[ACTORDATA].address = e.peer.address
|
data.replycc[ACTORDATA].address = e.peer.address
|
||||||
data.replycc[ACTORDATA].port = e.peer.port
|
data.replycc[ACTORDATA].port = e.peer.port
|
||||||
}
|
}
|
||||||
function populate_actor_addresses(obj) {
|
if (data.data) populate_actor_addresses(data.data, e)
|
||||||
if (!is_object(obj)) return
|
|
||||||
if (obj[ACTORDATA] && !obj[ACTORDATA].address) {
|
|
||||||
obj[ACTORDATA].address = e.peer.address
|
|
||||||
obj[ACTORDATA].port = e.peer.port
|
|
||||||
}
|
|
||||||
arrfor(array(obj), function(key, index) {
|
|
||||||
if (key in obj)
|
|
||||||
populate_actor_addresses(obj[key])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (data.data) populate_actor_addresses(data.data)
|
|
||||||
turn(data)
|
turn(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function populate_actor_addresses(obj, e) {
|
||||||
|
if (!is_object(obj)) return
|
||||||
|
if (obj[ACTORDATA] && !obj[ACTORDATA].address) {
|
||||||
|
obj[ACTORDATA].address = e.peer.address
|
||||||
|
obj[ACTORDATA].port = e.peer.port
|
||||||
|
}
|
||||||
|
arrfor(array(obj), function(key, index) {
|
||||||
|
if (key in obj)
|
||||||
|
populate_actor_addresses(obj[key], e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// takes a callback function, an actor object, and a configuration record for getting information about the status of a connection to the actor. The configuration record is used to request the sort of information that needs to be communicated. This can include latency, bandwidth, activity, congestion, cost, partitions. The callback is given a record containing the requested information.
|
// takes a callback function, an actor object, and a configuration record for getting information about the status of a connection to the actor. The configuration record is used to request the sort of information that needs to be communicated. This can include latency, bandwidth, activity, congestion, cost, partitions. The callback is given a record containing the requested information.
|
||||||
$_.contact = function(callback, record) {
|
$_.contact = function(callback, record) {
|
||||||
send(create_actor(record), record, callback)
|
send(create_actor(record), record, callback)
|
||||||
@@ -512,12 +523,13 @@ $_.unneeded = function unneeded(fn, seconds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// schedules the invocation of a function after a specified amount of time.
|
// schedules the invocation of a function after a specified amount of time.
|
||||||
$_.delay = function delay(fn, seconds = 0) {
|
$_.delay = function delay(fn, seconds) {
|
||||||
|
var _seconds = seconds == null ? 0 : seconds
|
||||||
function delay_turn() {
|
function delay_turn() {
|
||||||
fn()
|
fn()
|
||||||
send_messages()
|
send_messages()
|
||||||
}
|
}
|
||||||
var id = actor_mod.delay(delay_turn, seconds)
|
var id = actor_mod.delay(delay_turn, _seconds)
|
||||||
return function() { actor_mod.removetimer(id) }
|
return function() { actor_mod.removetimer(id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,6 +554,9 @@ function actor_send_immediate(actor, send) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function actor_send(actor, message) {
|
function actor_send(actor, message) {
|
||||||
|
var wota_blob = null
|
||||||
|
var peer = null
|
||||||
|
|
||||||
if (actor[HEADER] && !actor[HEADER].replycc) // attempting to respond to a message but sender is not expecting; silently drop
|
if (actor[HEADER] && !actor[HEADER].replycc) // attempting to respond to a message but sender is not expecting; silently drop
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -560,22 +575,21 @@ function actor_send(actor, message) {
|
|||||||
if (receive_fn) receive_fn(message.data)
|
if (receive_fn) receive_fn(message.data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// message to actor in same flock
|
// message to actor in same flock
|
||||||
if (actor[ACTORDATA].id && actor_mod.mailbox_exist(actor[ACTORDATA].id)) {
|
if (actor[ACTORDATA].id && actor_mod.mailbox_exist(actor[ACTORDATA].id)) {
|
||||||
var wota_blob = wota.encode(message)
|
wota_blob = wota.encode(message)
|
||||||
// log.console(`sending wota blob of ${length(wota_blob)/8} bytes`)
|
|
||||||
actor_mod.mailbox_push(actor[ACTORDATA].id, wota_blob)
|
actor_mod.mailbox_push(actor[ACTORDATA].id, wota_blob)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor[ACTORDATA].address) {
|
if (actor[ACTORDATA].address) {
|
||||||
if (actor[ACTORDATA].id)
|
if (actor[ACTORDATA].id)
|
||||||
message.target = actor[ACTORDATA].id
|
message.target = actor[ACTORDATA].id
|
||||||
else
|
else
|
||||||
message.type = "contact"
|
message.type = "contact"
|
||||||
|
|
||||||
var peer = peers[actor[ACTORDATA].address + ":" + actor[ACTORDATA].port]
|
peer = peers[actor[ACTORDATA].address + ":" + actor[ACTORDATA].port]
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
if (!portal) {
|
if (!portal) {
|
||||||
log.system(`creating a contactor ...`)
|
log.system(`creating a contactor ...`)
|
||||||
@@ -619,6 +633,11 @@ function send_messages() {
|
|||||||
var replies = {}
|
var replies = {}
|
||||||
|
|
||||||
function send(actor, message, reply) {
|
function send(actor, message, reply) {
|
||||||
|
var send_msg = null
|
||||||
|
var target = null
|
||||||
|
var header = null
|
||||||
|
var id = null
|
||||||
|
|
||||||
if (!is_object(actor)) {
|
if (!is_object(actor)) {
|
||||||
log.error(`Must send to an actor object. Provided: ${actor}`)
|
log.error(`Must send to an actor object. Provided: ${actor}`)
|
||||||
disrupt
|
disrupt
|
||||||
@@ -628,11 +647,11 @@ function send(actor, message, reply) {
|
|||||||
log.error('Message must be an object')
|
log.error('Message must be an object')
|
||||||
disrupt
|
disrupt
|
||||||
}
|
}
|
||||||
var send_msg = {type:"user", data: message}
|
send_msg = {type:"user", data: message}
|
||||||
var target = actor
|
target = actor
|
||||||
|
|
||||||
if (actor[HEADER] && actor[HEADER].replycc) {
|
if (actor[HEADER] && actor[HEADER].replycc) {
|
||||||
var header = actor[HEADER]
|
header = actor[HEADER]
|
||||||
if (!header.replycc || !is_actor(header.replycc)) {
|
if (!header.replycc || !is_actor(header.replycc)) {
|
||||||
log.error(`Supplied actor had a return, but it's not a valid actor! ${actor[HEADER]}`)
|
log.error(`Supplied actor had a return, but it's not a valid actor! ${actor[HEADER]}`)
|
||||||
disrupt
|
disrupt
|
||||||
@@ -643,7 +662,7 @@ function send(actor, message, reply) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (reply) {
|
if (reply) {
|
||||||
var id = guid()
|
id = guid()
|
||||||
replies[id] = reply
|
replies[id] = reply
|
||||||
$_.delay(_ => {
|
$_.delay(_ => {
|
||||||
if (replies[id]) {
|
if (replies[id]) {
|
||||||
@@ -728,18 +747,21 @@ function handle_actor_disconnect(id) {
|
|||||||
|
|
||||||
function handle_sysym(msg)
|
function handle_sysym(msg)
|
||||||
{
|
{
|
||||||
var from
|
var from = null
|
||||||
|
var greeter = null
|
||||||
|
var letter2 = null
|
||||||
|
|
||||||
if (msg.kind == 'stop') {
|
if (msg.kind == 'stop') {
|
||||||
actor_die("got stop message")
|
actor_die("got stop message")
|
||||||
} else if (msg.kind == 'underling') {
|
} else if (msg.kind == 'underling') {
|
||||||
from = msg.from
|
from = msg.from
|
||||||
var greeter = greeters[from[ACTORDATA].id]
|
greeter = greeters[from[ACTORDATA].id]
|
||||||
if (greeter) greeter(msg.message)
|
if (greeter) greeter(msg.message)
|
||||||
if (msg.message.type == 'disrupt')
|
if (msg.message.type == 'disrupt')
|
||||||
delete underlings[from[ACTORDATA].id]
|
delete underlings[from[ACTORDATA].id]
|
||||||
} else if (msg.kind == 'contact') {
|
} else if (msg.kind == 'contact') {
|
||||||
if (portal_fn) {
|
if (portal_fn) {
|
||||||
var letter2 = msg.data
|
letter2 = msg.data
|
||||||
letter2[HEADER] = msg
|
letter2[HEADER] = msg
|
||||||
delete msg.data
|
delete msg.data
|
||||||
portal_fn(letter2)
|
portal_fn(letter2)
|
||||||
@@ -756,13 +778,16 @@ function handle_sysym(msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handle_message(msg) {
|
function handle_message(msg) {
|
||||||
|
var letter = null
|
||||||
|
var fn = null
|
||||||
|
|
||||||
if (msg[SYSYM]) {
|
if (msg[SYSYM]) {
|
||||||
handle_sysym(msg[SYSYM], msg.from)
|
handle_sysym(msg[SYSYM], msg.from)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type == "user") {
|
if (msg.type == "user") {
|
||||||
var letter = msg.data // what the sender really sent
|
letter = msg.data // what the sender really sent
|
||||||
_ObjectDefineProperty(letter, HEADER, {
|
_ObjectDefineProperty(letter, HEADER, {
|
||||||
value: msg, enumerable: false
|
value: msg, enumerable: false
|
||||||
})
|
})
|
||||||
@@ -771,7 +796,7 @@ function handle_message(msg) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (msg.return) {
|
if (msg.return) {
|
||||||
var fn = replies[msg.return]
|
fn = replies[msg.return]
|
||||||
if (fn) fn(letter)
|
if (fn) fn(letter)
|
||||||
delete replies[msg.return]
|
delete replies[msg.return]
|
||||||
return
|
return
|
||||||
@@ -801,14 +826,16 @@ var package = use_core('package')
|
|||||||
|
|
||||||
// Find the .ce file
|
// Find the .ce file
|
||||||
var prog_path = prog + ".ce"
|
var prog_path = prog + ".ce"
|
||||||
|
var pkg_dir = null
|
||||||
|
var core_dir = null
|
||||||
if (!fd.is_file(prog_path)) {
|
if (!fd.is_file(prog_path)) {
|
||||||
var pkg_dir = package.find_package_dir(prog_path)
|
pkg_dir = package.find_package_dir(prog_path)
|
||||||
if (pkg_dir)
|
if (pkg_dir)
|
||||||
prog_path = pkg_dir + '/' + prog + '.ce'
|
prog_path = pkg_dir + '/' + prog + '.ce'
|
||||||
}
|
}
|
||||||
if (!fd.is_file(prog_path)) {
|
if (!fd.is_file(prog_path)) {
|
||||||
// Check core packages
|
// Check core packages
|
||||||
var core_dir = core_path
|
core_dir = core_path
|
||||||
prog_path = core_dir + '/' + prog + '.ce'
|
prog_path = core_dir + '/' + prog + '.ce'
|
||||||
}
|
}
|
||||||
if (!fd.is_file(prog_path)) {
|
if (!fd.is_file(prog_path)) {
|
||||||
@@ -824,9 +851,11 @@ $_.clock(_ => {
|
|||||||
var env = {}
|
var env = {}
|
||||||
arrfor(array(runtime_env), function(k) { env[k] = runtime_env[k] })
|
arrfor(array(runtime_env), function(k) { env[k] = runtime_env[k] })
|
||||||
var _ki = 0
|
var _ki = 0
|
||||||
|
var inj = null
|
||||||
|
var key = null
|
||||||
while (_ki < length(inject)) {
|
while (_ki < length(inject)) {
|
||||||
var inj = inject[_ki]
|
inj = inject[_ki]
|
||||||
var key = inj
|
key = inj
|
||||||
if (key && key[0] == '$') key = text(key, 1)
|
if (key && key[0] == '$') key = text(key, 1)
|
||||||
if (key == 'fd') env['$fd'] = fd
|
if (key == 'fd') env['$fd'] = fd
|
||||||
else env['$' + key] = $_[key]
|
else env['$' + key] = $_[key]
|
||||||
|
|||||||
BIN
internal/engine.mach
Normal file
BIN
internal/engine.mach
Normal file
Binary file not shown.
42
regen.cm
Normal file
42
regen.cm
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// regen.cm — regenerate .mach bytecode files
|
||||||
|
// Run with: ./cell --core . regen.cm
|
||||||
|
|
||||||
|
var fd = use("fd")
|
||||||
|
var json = use("json")
|
||||||
|
var tokenize = use("tokenize")
|
||||||
|
var parse = use("parse")
|
||||||
|
var fold = use("fold")
|
||||||
|
|
||||||
|
var files = [
|
||||||
|
{src: "tokenize.cm", name: "tokenize", out: "tokenize.mach"},
|
||||||
|
{src: "parse.cm", name: "parse", out: "parse.mach"},
|
||||||
|
{src: "fold.cm", name: "fold", out: "fold.mach"},
|
||||||
|
{src: "mcode.cm", name: "mcode", out: "mcode.mach"},
|
||||||
|
{src: "internal/bootstrap.cm", name: "bootstrap", out: "internal/bootstrap.mach"},
|
||||||
|
{src: "internal/engine.cm", name: "engine", out: "internal/engine.mach"}
|
||||||
|
]
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
var entry = null
|
||||||
|
var src = null
|
||||||
|
var tok_result = null
|
||||||
|
var ast = null
|
||||||
|
var folded = null
|
||||||
|
var ast_json = null
|
||||||
|
var bytecode = null
|
||||||
|
var f = null
|
||||||
|
|
||||||
|
while (i < length(files)) {
|
||||||
|
entry = files[i]
|
||||||
|
src = text(fd.slurp(entry.src))
|
||||||
|
tok_result = tokenize(src, entry.src)
|
||||||
|
ast = parse(tok_result.tokens, src, entry.src, tokenize)
|
||||||
|
folded = fold(ast)
|
||||||
|
ast_json = json.encode(folded)
|
||||||
|
bytecode = mach_compile_ast(entry.name, ast_json)
|
||||||
|
f = fd.open(entry.out, "w")
|
||||||
|
fd.write(f, bytecode)
|
||||||
|
fd.close(f)
|
||||||
|
print(`wrote ${entry.out}`)
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
@@ -217,8 +217,8 @@ void script_startup(cell_rt *prt)
|
|||||||
|
|
||||||
if (core_path)
|
if (core_path)
|
||||||
JS_SetPropertyStr(js, hidden_env, "core_path", JS_NewString(js, core_path));
|
JS_SetPropertyStr(js, hidden_env, "core_path", JS_NewString(js, core_path));
|
||||||
if (shop_path)
|
JS_SetPropertyStr(js, hidden_env, "shop_path",
|
||||||
JS_SetPropertyStr(js, hidden_env, "shop_path", JS_NewString(js, shop_path));
|
shop_path ? JS_NewString(js, shop_path) : JS_NULL);
|
||||||
|
|
||||||
// Stone the environment
|
// Stone the environment
|
||||||
hidden_env = JS_Stone(js, hidden_env);
|
hidden_env = JS_Stone(js, hidden_env);
|
||||||
@@ -413,8 +413,8 @@ int cell_init(int argc, char **argv)
|
|||||||
JSValue hidden_env = JS_NewObject(ctx);
|
JSValue hidden_env = JS_NewObject(ctx);
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
||||||
if (shop_path)
|
JS_SetPropertyStr(ctx, hidden_env, "shop_path",
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "shop_path", JS_NewString(ctx, shop_path));
|
shop_path ? JS_NewString(ctx, shop_path) : JS_NULL);
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "use_mcode", JS_NewBool(ctx, use_mcode));
|
JS_SetPropertyStr(ctx, hidden_env, "use_mcode", JS_NewBool(ctx, use_mcode));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
|
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
|
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
|
||||||
|
|||||||
Reference in New Issue
Block a user