250 lines
5.8 KiB
Plaintext
250 lines
5.8 KiB
Plaintext
// module_load.cm — Module loading simulation (macro benchmark)
|
|
// Simulates parsing many small modules, linking, and running.
|
|
// Tests the "build scenario" pattern.
|
|
|
|
var json = use('json')
|
|
|
|
// Simulate a small module: parse token stream + build AST + evaluate
|
|
function tokenize(src) {
|
|
var tokens = []
|
|
var i = 0
|
|
var ch = null
|
|
var chars = array(src)
|
|
var buf = ""
|
|
|
|
for (i = 0; i < length(chars); i++) {
|
|
ch = chars[i]
|
|
if (ch == " " || ch == "\n" || ch == "\t") {
|
|
if (length(buf) > 0) {
|
|
push(tokens, buf)
|
|
buf = ""
|
|
}
|
|
} else if (ch == "(" || ch == ")" || ch == "+" || ch == "-"
|
|
|| ch == "*" || ch == "=" || ch == ";" || ch == ",") {
|
|
if (length(buf) > 0) {
|
|
push(tokens, buf)
|
|
buf = ""
|
|
}
|
|
push(tokens, ch)
|
|
} else {
|
|
buf = buf + ch
|
|
}
|
|
}
|
|
if (length(buf) > 0) push(tokens, buf)
|
|
return tokens
|
|
}
|
|
|
|
// Build a simple AST from tokens
|
|
function parse_tokens(tokens) {
|
|
var ast = []
|
|
var i = 0
|
|
var tok = null
|
|
var node = null
|
|
for (i = 0; i < length(tokens); i++) {
|
|
tok = tokens[i]
|
|
if (tok == "var" || tok == "def") {
|
|
node = {type: "decl", kind: tok, name: null, value: null}
|
|
i++
|
|
if (i < length(tokens)) node.name = tokens[i]
|
|
i++ // skip =
|
|
i++
|
|
if (i < length(tokens)) node.value = tokens[i]
|
|
push(ast, node)
|
|
} else if (tok == "return") {
|
|
node = {type: "return", value: null}
|
|
i++
|
|
if (i < length(tokens)) node.value = tokens[i]
|
|
push(ast, node)
|
|
} else if (tok == "function") {
|
|
node = {type: "func", name: null, body: []}
|
|
i++
|
|
if (i < length(tokens)) node.name = tokens[i]
|
|
// Skip to matching )
|
|
while (i < length(tokens) && tokens[i] != ")") i++
|
|
push(ast, node)
|
|
} else {
|
|
push(ast, {type: "expr", value: tok})
|
|
}
|
|
}
|
|
return ast
|
|
}
|
|
|
|
// Evaluate: simple symbol table + resolution
|
|
function evaluate(ast, env) {
|
|
var result = null
|
|
var i = 0
|
|
var node = null
|
|
for (i = 0; i < length(ast); i++) {
|
|
node = ast[i]
|
|
if (node.type == "decl") {
|
|
env[node.name] = node.value
|
|
} else if (node.type == "return") {
|
|
result = node.value
|
|
if (env[result]) result = env[result]
|
|
} else if (node.type == "func") {
|
|
env[node.name] = node
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Generate fake module source code
|
|
function generate_module(id, dep_count) {
|
|
var src = ""
|
|
var i = 0
|
|
src = src + "var _id = " + text(id) + ";\n"
|
|
for (i = 0; i < dep_count; i++) {
|
|
src = src + "var dep" + text(i) + " = use(mod_" + text(i) + ");\n"
|
|
}
|
|
src = src + "var x = " + text(id * 17) + ";\n"
|
|
src = src + "var y = " + text(id * 31) + ";\n"
|
|
src = src + "function compute(a, b) { return a + b; }\n"
|
|
src = src + "var result = compute(x, y);\n"
|
|
src = src + "return result;\n"
|
|
return src
|
|
}
|
|
|
|
// Simulate loading N modules with dependency chains
|
|
function simulate_build(n_modules, deps_per_module) {
|
|
var modules = []
|
|
var loaded = {}
|
|
var i = 0
|
|
var j = 0
|
|
var src = null
|
|
var tokens = null
|
|
var ast = null
|
|
var env = null
|
|
var result = null
|
|
var total_tokens = 0
|
|
var total_nodes = 0
|
|
|
|
// Generate all module sources
|
|
for (i = 0; i < n_modules; i++) {
|
|
src = generate_module(i, deps_per_module)
|
|
push(modules, src)
|
|
}
|
|
|
|
// "Load" each module: tokenize → parse → evaluate
|
|
for (i = 0; i < n_modules; i++) {
|
|
tokens = tokenize(modules[i])
|
|
total_tokens += length(tokens)
|
|
|
|
ast = parse_tokens(tokens)
|
|
total_nodes += length(ast)
|
|
|
|
env = {}
|
|
// Resolve dependencies
|
|
for (j = 0; j < deps_per_module; j++) {
|
|
if (j < i) {
|
|
env["dep" + text(j)] = loaded["mod_" + text(j)]
|
|
}
|
|
}
|
|
|
|
result = evaluate(ast, env)
|
|
loaded["mod_" + text(i)] = result
|
|
}
|
|
|
|
return {
|
|
modules: n_modules,
|
|
total_tokens: total_tokens,
|
|
total_nodes: total_nodes,
|
|
last_result: result
|
|
}
|
|
}
|
|
|
|
// Dependency graph analysis (topological sort simulation)
|
|
function topo_sort(n_modules, deps_per_module) {
|
|
// Build adjacency list
|
|
var adj = {}
|
|
var in_degree = {}
|
|
var i = 0
|
|
var j = 0
|
|
var name = null
|
|
var dep = null
|
|
|
|
for (i = 0; i < n_modules; i++) {
|
|
name = "mod_" + text(i)
|
|
adj[name] = []
|
|
in_degree[name] = 0
|
|
}
|
|
|
|
for (i = 0; i < n_modules; i++) {
|
|
name = "mod_" + text(i)
|
|
for (j = 0; j < deps_per_module; j++) {
|
|
if (j < i) {
|
|
dep = "mod_" + text(j)
|
|
push(adj[dep], name)
|
|
in_degree[name] = in_degree[name] + 1
|
|
}
|
|
}
|
|
}
|
|
|
|
// Kahn's algorithm
|
|
var queue = []
|
|
var keys = array(in_degree)
|
|
for (i = 0; i < length(keys); i++) {
|
|
if (in_degree[keys[i]] == 0) push(queue, keys[i])
|
|
}
|
|
|
|
var order = []
|
|
var current = null
|
|
var neighbors = null
|
|
var qi = 0
|
|
while (qi < length(queue)) {
|
|
current = queue[qi]
|
|
qi++
|
|
push(order, current)
|
|
neighbors = adj[current]
|
|
if (neighbors) {
|
|
for (i = 0; i < length(neighbors); i++) {
|
|
in_degree[neighbors[i]] = in_degree[neighbors[i]] - 1
|
|
if (in_degree[neighbors[i]] == 0) push(queue, neighbors[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
return order
|
|
}
|
|
|
|
return {
|
|
// Small build: 50 modules, 3 deps each
|
|
build_50: function(n) {
|
|
var i = 0
|
|
var result = null
|
|
for (i = 0; i < n; i++) {
|
|
result = simulate_build(50, 3)
|
|
}
|
|
return result
|
|
},
|
|
|
|
// Medium build: 200 modules, 5 deps each
|
|
build_200: function(n) {
|
|
var i = 0
|
|
var result = null
|
|
for (i = 0; i < n; i++) {
|
|
result = simulate_build(200, 5)
|
|
}
|
|
return result
|
|
},
|
|
|
|
// Large build: 500 modules, 5 deps each
|
|
build_500: function(n) {
|
|
var i = 0
|
|
var result = null
|
|
for (i = 0; i < n; i++) {
|
|
result = simulate_build(500, 5)
|
|
}
|
|
return result
|
|
},
|
|
|
|
// Topo sort of 500 module dependency graph
|
|
topo_sort_500: function(n) {
|
|
var i = 0
|
|
var order = null
|
|
for (i = 0; i < n; i++) {
|
|
order = topo_sort(500, 5)
|
|
}
|
|
return order
|
|
}
|
|
}
|