ast folding

This commit is contained in:
2026-02-09 20:04:40 -06:00
parent 66a44595c8
commit 4b76728230
4 changed files with 1002 additions and 59 deletions

View File

@@ -403,6 +403,7 @@ var parse = function(tokens, src, filename, tokenizer) {
if (tok.kind == ")") advance()
else if (tok.kind == "eof") parse_error(tok, "unterminated method parameter list")
if (length(params) > 4) parse_error(tok, "functions cannot have more than 4 parameters")
fn.arity = length(params)
if (tok.kind == "{") {
advance()
fn.statements = parse_block_statements()
@@ -843,6 +844,7 @@ var parse = function(tokens, src, filename, tokenizer) {
}
if (length(params) > 4) parse_error(tok, "functions cannot have more than 4 parameters")
node.arity = length(params)
if (tok.kind == "{") {
advance()
@@ -935,6 +937,7 @@ var parse = function(tokens, src, filename, tokenizer) {
}
if (length(params) > 4) parse_error(tok, "functions cannot have more than 4 parameters")
node.arity = length(params)
if (tok.kind != "=>") {
parse_error(tok, "expected '=>' in arrow function")
@@ -1274,7 +1277,6 @@ var parse = function(tokens, src, filename, tokenizer) {
var sem_errors = []
var scopes_array = []
var intrinsics = []
var block_var_counter = 0
var sem_error = function(node, msg) {
var err = {message: msg}
@@ -1289,15 +1291,13 @@ var parse = function(tokens, src, filename, tokenizer) {
vars: [],
in_loop: opts.in_loop == true,
function_nr: fn_nr,
is_function_scope: opts.is_func == true,
block_depth: opts.bdepth != null ? opts.bdepth : 0
is_function_scope: opts.is_func == true
}
}
var sem_add_var = function(scope, name, make_opts) {
push(scope.vars, {
name: name,
scope_name: null,
is_const: make_opts.is_const == true,
make: make_opts.make,
function_nr: make_opts.fn_nr,
@@ -1364,23 +1364,10 @@ var parse = function(tokens, src, filename, tokenizer) {
return functino_names[name] == true
}
var sem_propagate_block_vars = function(parent, block) {
var sem_propagate_vars = function(parent, child) {
var i = 0
var v = null
var sn = null
while (i < length(block.vars)) {
v = block.vars[i]
sn = v.scope_name
if (sn == null) sn = v.name
push(parent.vars, {
name: sn,
scope_name: null,
is_const: v.is_const,
make: v.make,
function_nr: v.function_nr,
nr_uses: v.nr_uses,
closure: v.closure
})
while (i < length(child.vars)) {
push(parent.vars, child.vars[i])
i = i + 1
}
}
@@ -1471,7 +1458,6 @@ var parse = function(tokens, src, filename, tokenizer) {
if (r.v != null) {
left_node.level = r.level
left_node.function_nr = r.def_function_nr
if (r.v.scope_name != null) left_node.scope_name = r.v.scope_name
} else {
left_node.level = -1
}
@@ -1525,7 +1511,6 @@ var parse = function(tokens, src, filename, tokenizer) {
if (r.v != null) {
operand.level = r.level
operand.function_nr = r.def_function_nr
if (r.v.scope_name != null) operand.scope_name = r.v.scope_name
} else {
operand.level = -1
}
@@ -1647,7 +1632,6 @@ var parse = function(tokens, src, filename, tokenizer) {
expr.function_nr = r.def_function_nr
r.v.nr_uses = r.v.nr_uses + 1
if (r.level > 0) r.v.closure = 1
if (r.v.scope_name != null) expr.scope_name = r.v.scope_name
} else {
expr.level = -1
sem_add_intrinsic(name)
@@ -1664,15 +1648,10 @@ var parse = function(tokens, src, filename, tokenizer) {
var name = null
var existing = null
var i = 0
var sn = null
var then_scope = null
var list_scope = null
var else_scope = null
var loop_scope = null
var do_scope = null
var for_scope = null
var init_kind = null
var blk_scope = null
var fn_nr_val = null
var fn_scope = null
var pname = null
@@ -1695,15 +1674,9 @@ var parse = function(tokens, src, filename, tokenizer) {
if (existing != null && existing.is_const) {
sem_error(stmt.left, "cannot redeclare constant '" + name + "'")
}
if (existing == null || existing.function_nr != scope.function_nr || scope.block_depth > 0) {
if (existing == null || existing.function_nr != scope.function_nr) {
sem_add_var(scope, name, {make: "var", fn_nr: scope.function_nr})
}
if (scope.block_depth > 0) {
sn = "_" + name + "_" + text(block_var_counter)
block_var_counter = block_var_counter + 1
scope.vars[length(scope.vars) - 1].scope_name = sn
stmt.left.scope_name = sn
}
}
sem_check_expr(scope, stmt.right)
return null
@@ -1720,12 +1693,6 @@ var parse = function(tokens, src, filename, tokenizer) {
existing.make = "def"
} else {
sem_add_var(scope, name, {is_const: true, make: "def", fn_nr: scope.function_nr})
if (scope.block_depth > 0) {
sn = "_" + name + "_" + text(block_var_counter)
block_var_counter = block_var_counter + 1
scope.vars[length(scope.vars) - 1].scope_name = sn
stmt.left.scope_name = sn
}
}
}
sem_check_expr(scope, stmt.right)
@@ -1739,58 +1706,52 @@ var parse = function(tokens, src, filename, tokenizer) {
if (kind == "if") {
sem_check_expr(scope, stmt.expression)
then_scope = make_scope(scope, scope.function_nr, {bdepth: scope.block_depth + 1})
i = 0
while (i < length(stmt.then)) {
sem_check_stmt(then_scope, stmt.then[i])
sem_check_stmt(scope, stmt.then[i])
i = i + 1
}
sem_propagate_block_vars(scope, then_scope)
list_scope = make_scope(scope, scope.function_nr, {bdepth: scope.block_depth + 1})
i = 0
while (i < length(stmt.list)) {
sem_check_stmt(list_scope, stmt.list[i])
sem_check_stmt(scope, stmt.list[i])
i = i + 1
}
sem_propagate_block_vars(scope, list_scope)
if (stmt.else != null) {
else_scope = make_scope(scope, scope.function_nr, {bdepth: scope.block_depth + 1})
i = 0
while (i < length(stmt.else)) {
sem_check_stmt(else_scope, stmt.else[i])
sem_check_stmt(scope, stmt.else[i])
i = i + 1
}
sem_propagate_block_vars(scope, else_scope)
}
return null
}
if (kind == "while") {
sem_check_expr(scope, stmt.expression)
loop_scope = make_scope(scope, scope.function_nr, {in_loop: true, bdepth: scope.block_depth + 1})
loop_scope = make_scope(scope, scope.function_nr, {in_loop: true})
i = 0
while (i < length(stmt.statements)) {
sem_check_stmt(loop_scope, stmt.statements[i])
i = i + 1
}
sem_propagate_block_vars(scope, loop_scope)
sem_propagate_vars(scope, loop_scope)
return null
}
if (kind == "do") {
do_scope = make_scope(scope, scope.function_nr, {in_loop: true, bdepth: scope.block_depth + 1})
do_scope = make_scope(scope, scope.function_nr, {in_loop: true})
i = 0
while (i < length(stmt.statements)) {
sem_check_stmt(do_scope, stmt.statements[i])
i = i + 1
}
sem_propagate_block_vars(scope, do_scope)
sem_propagate_vars(scope, do_scope)
sem_check_expr(scope, stmt.expression)
return null
}
if (kind == "for") {
for_scope = make_scope(scope, scope.function_nr, {in_loop: true, bdepth: scope.block_depth + 1})
for_scope = make_scope(scope, scope.function_nr, {in_loop: true})
if (stmt.init != null) {
init_kind = stmt.init.kind
if (init_kind == "var" || init_kind == "def") {
@@ -1806,7 +1767,7 @@ var parse = function(tokens, src, filename, tokenizer) {
sem_check_stmt(for_scope, stmt.statements[i])
i = i + 1
}
sem_propagate_block_vars(scope, for_scope)
sem_propagate_vars(scope, for_scope)
return null
}
@@ -1834,13 +1795,11 @@ var parse = function(tokens, src, filename, tokenizer) {
}
if (kind == "block") {
blk_scope = make_scope(scope, scope.function_nr, {bdepth: scope.block_depth + 1})
i = 0
while (i < length(stmt.statements)) {
sem_check_stmt(blk_scope, stmt.statements[i])
sem_check_stmt(scope, stmt.statements[i])
i = i + 1
}
sem_propagate_block_vars(scope, blk_scope)
return null
}