chore: rename AstGen methods, removed 'check' prefix
This commit is contained in:
parent
95d89b7bf9
commit
98f5215629
1 changed files with 117 additions and 117 deletions
234
src/AstGen.zig
234
src/AstGen.zig
|
|
@ -20,7 +20,7 @@ constants: std.ArrayListUnmanaged(CodeUnit.Constant) = .empty,
|
|||
knots: std.ArrayListUnmanaged(CodeUnit.Knot) = .empty,
|
||||
errors: std.ArrayListUnmanaged(Ast.Error) = .empty,
|
||||
|
||||
pub const CheckError = error{
|
||||
pub const InnerError = error{
|
||||
OutOfMemory,
|
||||
SemanticError,
|
||||
TooManyConstants,
|
||||
|
|
@ -305,39 +305,39 @@ fn createScope(astgen: *AstGen, parent_scope: ?*Scope) !*Scope {
|
|||
return child_scope;
|
||||
}
|
||||
|
||||
fn checkUnaryOp(
|
||||
fn unaryOp(
|
||||
gen: *CodeGen,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
op: Story.Opcode,
|
||||
) CheckError!void {
|
||||
try checkExpr(gen, scope, node.data.bin.lhs);
|
||||
) InnerError!void {
|
||||
try expr(gen, scope, node.data.bin.lhs);
|
||||
try gen.emitSimpleInst(op);
|
||||
}
|
||||
|
||||
fn checkBinaryOp(
|
||||
fn binaryOp(
|
||||
gen: *CodeGen,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
op: Story.Opcode,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
assert(data.lhs != null and data.rhs != null);
|
||||
|
||||
try checkExpr(gen, scope, data.lhs);
|
||||
try checkExpr(gen, scope, data.rhs);
|
||||
try expr(gen, scope, data.lhs);
|
||||
try expr(gen, scope, data.rhs);
|
||||
try gen.emitSimpleInst(op);
|
||||
}
|
||||
|
||||
fn checkLogicalOp(
|
||||
fn logicalOp(
|
||||
gen: *CodeGen,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
op: Story.Opcode,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
assert(data.lhs != null and data.rhs != null);
|
||||
try checkExpr(gen, scope, data.lhs);
|
||||
try expr(gen, scope, data.lhs);
|
||||
|
||||
const else_label = try gen.makeLabel();
|
||||
const fixup_offset = try gen.emitJumpInst(op);
|
||||
|
|
@ -351,19 +351,19 @@ fn checkLogicalOp(
|
|||
const rhs_label = try gen.makeLabel();
|
||||
gen.setLabel(rhs_label);
|
||||
|
||||
try checkExpr(gen, scope, data.rhs);
|
||||
try expr(gen, scope, data.rhs);
|
||||
gen.setLabel(else_label);
|
||||
}
|
||||
|
||||
fn checkTrueLiteral(gen: *CodeGen, _: *const Ast.Node) CheckError!void {
|
||||
fn trueLiteral(gen: *CodeGen, _: *const Ast.Node) InnerError!void {
|
||||
try gen.emitSimpleInst(.true);
|
||||
}
|
||||
|
||||
fn checkFalseLiteral(gen: *CodeGen, _: *const Ast.Node) CheckError!void {
|
||||
fn falseLiteral(gen: *CodeGen, _: *const Ast.Node) InnerError!void {
|
||||
try gen.emitSimpleInst(.false);
|
||||
}
|
||||
|
||||
fn checkNumberLiteral(gen: *CodeGen, node: *const Ast.Node) CheckError!void {
|
||||
fn numberLiteral(gen: *CodeGen, node: *const Ast.Node) InnerError!void {
|
||||
const lexeme = sliceFromNode(gen.astgen, node);
|
||||
const number_value = try std.fmt.parseUnsigned(i64, lexeme, 10);
|
||||
const constant_id = try gen.makeConstant(.{ .number = number_value });
|
||||
|
|
@ -371,20 +371,20 @@ fn checkNumberLiteral(gen: *CodeGen, node: *const Ast.Node) CheckError!void {
|
|||
try gen.emitConstInst(.load_const, constant_id);
|
||||
}
|
||||
|
||||
fn checkStringLiteral(gen: *CodeGen, node: *const Ast.Node) CheckError!void {
|
||||
fn stringLiteral(gen: *CodeGen, node: *const Ast.Node) InnerError!void {
|
||||
const string_ref = try gen.astgen.stringFromNode(node);
|
||||
const constant_id = try gen.makeConstant(.{ .string = string_ref });
|
||||
|
||||
try gen.emitConstInst(.load_const, constant_id);
|
||||
}
|
||||
|
||||
fn checkStringExpr(gen: *CodeGen, node: *const Ast.Node) CheckError!void {
|
||||
fn stringExpr(gen: *CodeGen, node: *const Ast.Node) InnerError!void {
|
||||
assert(node.data.bin.lhs != null);
|
||||
const expr_node = node.data.bin.lhs orelse return;
|
||||
return checkStringLiteral(gen, expr_node);
|
||||
return stringLiteral(gen, expr_node);
|
||||
}
|
||||
|
||||
fn checkIdentifier(gen: *CodeGen, scope: *Scope, node: *const Ast.Node) CheckError!void {
|
||||
fn identifier(gen: *CodeGen, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
const name_ref = try gen.astgen.stringFromNode(node);
|
||||
|
||||
if (scope.lookup(name_ref)) |symbol| switch (symbol) {
|
||||
|
|
@ -402,47 +402,47 @@ fn checkIdentifier(gen: *CodeGen, scope: *Scope, node: *const Ast.Node) CheckErr
|
|||
return gen.fail(.unknown_identifier, node);
|
||||
}
|
||||
|
||||
fn checkExpr(gen: *CodeGen, scope: *Scope, expr: ?*const Ast.Node) CheckError!void {
|
||||
const expr_node = expr orelse return;
|
||||
fn expr(gen: *CodeGen, scope: *Scope, optional_expr: ?*const Ast.Node) InnerError!void {
|
||||
const expr_node = optional_expr orelse return;
|
||||
switch (expr_node.tag) {
|
||||
.true_literal => try checkTrueLiteral(gen, expr_node),
|
||||
.false_literal => try checkFalseLiteral(gen, expr_node),
|
||||
.number_literal => try checkNumberLiteral(gen, expr_node),
|
||||
.string_literal => try checkStringLiteral(gen, expr_node),
|
||||
.string_expr => try checkStringExpr(gen, expr_node),
|
||||
.identifier => try checkIdentifier(gen, scope, expr_node),
|
||||
.add_expr => try checkBinaryOp(gen, scope, expr_node, .add),
|
||||
.subtract_expr => try checkBinaryOp(gen, scope, expr_node, .sub),
|
||||
.multiply_expr => try checkBinaryOp(gen, scope, expr_node, .mul),
|
||||
.divide_expr => try checkBinaryOp(gen, scope, expr_node, .div),
|
||||
.mod_expr => try checkBinaryOp(gen, scope, expr_node, .mod),
|
||||
.negate_expr => try checkUnaryOp(gen, scope, expr_node, .neg),
|
||||
.logical_and_expr => try checkLogicalOp(gen, scope, expr_node, .jmp_f),
|
||||
.logical_or_expr => try checkLogicalOp(gen, scope, expr_node, .jmp_t),
|
||||
.logical_not_expr => try checkUnaryOp(gen, scope, expr_node, .not),
|
||||
.logical_equality_expr => try checkBinaryOp(gen, scope, expr_node, .cmp_eq),
|
||||
.true_literal => try trueLiteral(gen, expr_node),
|
||||
.false_literal => try falseLiteral(gen, expr_node),
|
||||
.number_literal => try numberLiteral(gen, expr_node),
|
||||
.string_literal => try stringLiteral(gen, expr_node),
|
||||
.string_expr => try stringExpr(gen, expr_node),
|
||||
.identifier => try identifier(gen, scope, expr_node),
|
||||
.add_expr => try binaryOp(gen, scope, expr_node, .add),
|
||||
.subtract_expr => try binaryOp(gen, scope, expr_node, .sub),
|
||||
.multiply_expr => try binaryOp(gen, scope, expr_node, .mul),
|
||||
.divide_expr => try binaryOp(gen, scope, expr_node, .div),
|
||||
.mod_expr => try binaryOp(gen, scope, expr_node, .mod),
|
||||
.negate_expr => try unaryOp(gen, scope, expr_node, .neg),
|
||||
.logical_and_expr => try logicalOp(gen, scope, expr_node, .jmp_f),
|
||||
.logical_or_expr => try logicalOp(gen, scope, expr_node, .jmp_t),
|
||||
.logical_not_expr => try unaryOp(gen, scope, expr_node, .not),
|
||||
.logical_equality_expr => try binaryOp(gen, scope, expr_node, .cmp_eq),
|
||||
.logical_inequality_expr => {
|
||||
try gen.emitSimpleInst(.not);
|
||||
try checkBinaryOp(gen, scope, expr_node, .cmp_eq);
|
||||
try binaryOp(gen, scope, expr_node, .cmp_eq);
|
||||
},
|
||||
.logical_greater_expr => try checkBinaryOp(gen, scope, expr_node, .cmp_gt),
|
||||
.logical_greater_or_equal_expr => try checkBinaryOp(gen, scope, expr_node, .cmp_gte),
|
||||
.logical_lesser_expr => try checkBinaryOp(gen, scope, expr_node, .cmp_lt),
|
||||
.logical_lesser_or_equal_expr => try checkBinaryOp(gen, scope, expr_node, .cmp_lte),
|
||||
.logical_greater_expr => try binaryOp(gen, scope, expr_node, .cmp_gt),
|
||||
.logical_greater_or_equal_expr => try binaryOp(gen, scope, expr_node, .cmp_gte),
|
||||
.logical_lesser_expr => try binaryOp(gen, scope, expr_node, .cmp_lt),
|
||||
.logical_lesser_or_equal_expr => try binaryOp(gen, scope, expr_node, .cmp_lte),
|
||||
else => return error.NotImplemented,
|
||||
}
|
||||
}
|
||||
|
||||
fn checkExprStmt(gen: *CodeGen, scope: *Scope, stmt: *const Ast.Node) CheckError!void {
|
||||
const expr_node = stmt.data.bin.lhs orelse return;
|
||||
try checkExpr(gen, scope, expr_node);
|
||||
fn exprStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
const expr_node = stmt_node.data.bin.lhs orelse return;
|
||||
try expr(gen, scope, expr_node);
|
||||
try gen.emitSimpleInst(.pop);
|
||||
}
|
||||
|
||||
fn validateSwitchProngs(gen: *CodeGen, stmt: *const Ast.Node) CheckError!void {
|
||||
fn validateSwitchProngs(gen: *CodeGen, stmt_node: *const Ast.Node) InnerError!void {
|
||||
var stmt_has_block: bool = false;
|
||||
var stmt_has_else: bool = false;
|
||||
const case_list = stmt.data.switch_stmt.cases;
|
||||
const case_list = stmt_node.data.switch_stmt.cases;
|
||||
const last_prong = case_list[case_list.len - 1];
|
||||
for (case_list) |case_stmt| {
|
||||
switch (case_stmt.tag) {
|
||||
|
|
@ -466,11 +466,11 @@ fn validateSwitchProngs(gen: *CodeGen, stmt: *const Ast.Node) CheckError!void {
|
|||
}
|
||||
}
|
||||
|
||||
fn checkIfStmt(gen: *CodeGen, parent_scope: *Scope, stmt: *const Ast.Node) CheckError!void {
|
||||
const case_list = stmt.data.switch_stmt.cases;
|
||||
const eval_expr = stmt.data.switch_stmt.condition_expr;
|
||||
fn ifStmt(gen: *CodeGen, parent_scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
const case_list = stmt_node.data.switch_stmt.cases;
|
||||
const eval_expr = stmt_node.data.switch_stmt.condition_expr;
|
||||
if (eval_expr) |expr_node| {
|
||||
try validateSwitchProngs(gen, stmt);
|
||||
try validateSwitchProngs(gen, stmt_node);
|
||||
|
||||
const first_prong = case_list[0];
|
||||
const last_prong = case_list[case_list.len - 1];
|
||||
|
|
@ -482,7 +482,7 @@ fn checkIfStmt(gen: *CodeGen, parent_scope: *Scope, stmt: *const Ast.Node) Check
|
|||
|
||||
var child_scope = try gen.astgen.createScope(parent_scope);
|
||||
defer child_scope.deinit();
|
||||
try checkExpr(gen, child_scope, expr_node);
|
||||
try expr(gen, child_scope, expr_node);
|
||||
|
||||
const else_label = try gen.makeLabel();
|
||||
const end_label = try gen.makeLabel();
|
||||
|
|
@ -493,7 +493,7 @@ fn checkIfStmt(gen: *CodeGen, parent_scope: *Scope, stmt: *const Ast.Node) Check
|
|||
.code_offset = then_br,
|
||||
});
|
||||
try gen.emitSimpleInst(.pop);
|
||||
try checkBlockStmt(gen, child_scope, then_stmt);
|
||||
try blockStmt(gen, child_scope, then_stmt);
|
||||
|
||||
const else_br = try gen.emitJumpInst(.jmp);
|
||||
_ = try gen.makeFixup(.{
|
||||
|
|
@ -506,19 +506,19 @@ fn checkIfStmt(gen: *CodeGen, parent_scope: *Scope, stmt: *const Ast.Node) Check
|
|||
|
||||
if (else_stmt) |else_node| {
|
||||
const block_stmt = else_node.data.bin.rhs;
|
||||
try checkBlockStmt(gen, child_scope, block_stmt);
|
||||
try blockStmt(gen, child_scope, block_stmt);
|
||||
}
|
||||
gen.setLabel(end_label);
|
||||
} else {
|
||||
return gen.fail(.expected_expression, stmt);
|
||||
return gen.fail(.expected_expression, stmt_node);
|
||||
}
|
||||
}
|
||||
|
||||
fn checkMultiIfStmt(
|
||||
fn multiIfStmt(
|
||||
gen: *CodeGen,
|
||||
parent_scope: *Scope,
|
||||
stmt_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const gpa = gen.astgen.gpa;
|
||||
try validateSwitchProngs(gen, stmt_node);
|
||||
const case_list = stmt_node.data.switch_stmt.cases;
|
||||
|
|
@ -539,7 +539,7 @@ fn checkMultiIfStmt(
|
|||
switch (case_stmt.tag) {
|
||||
.if_branch => {
|
||||
const lhs = case_stmt.data.bin.lhs orelse unreachable;
|
||||
try checkExpr(gen, child_scope, lhs);
|
||||
try expr(gen, child_scope, lhs);
|
||||
|
||||
const fixup_offset = try gen.emitJumpInst(.jmp_t);
|
||||
_ = try gen.makeFixup(.{
|
||||
|
|
@ -572,7 +572,7 @@ fn checkMultiIfStmt(
|
|||
},
|
||||
else => unreachable,
|
||||
}
|
||||
try checkBlockStmt(gen, child_scope, body_stmt);
|
||||
try blockStmt(gen, child_scope, body_stmt);
|
||||
|
||||
const fixup_inst = try gen.emitJumpInst(.jmp);
|
||||
_ = try gen.makeFixup(.{
|
||||
|
|
@ -585,11 +585,11 @@ fn checkMultiIfStmt(
|
|||
gen.setLabel(gen.exit_label);
|
||||
}
|
||||
|
||||
fn checkSwitchStmt(
|
||||
fn switchStmt(
|
||||
gen: *CodeGen,
|
||||
parent_scope: *Scope,
|
||||
stmt_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const gpa = gen.astgen.gpa;
|
||||
var child_scope = try gen.astgen.createScope(parent_scope);
|
||||
defer child_scope.deinit();
|
||||
|
|
@ -607,7 +607,7 @@ fn checkSwitchStmt(
|
|||
try label_list.ensureUnusedCapacity(gpa, case_list.len);
|
||||
|
||||
const stack_slot = try gen.makeStackSlot();
|
||||
try checkExpr(gen, child_scope, eval_expr);
|
||||
try expr(gen, child_scope, eval_expr);
|
||||
try gen.emitConstInst(.store, stack_slot);
|
||||
try gen.emitSimpleInst(.pop);
|
||||
|
||||
|
|
@ -624,7 +624,7 @@ fn checkSwitchStmt(
|
|||
}
|
||||
|
||||
try gen.emitConstInst(.load, stack_slot);
|
||||
try checkExpr(gen, child_scope, case_eval_expr);
|
||||
try expr(gen, child_scope, case_eval_expr);
|
||||
try gen.emitSimpleInst(.cmp_eq);
|
||||
|
||||
const fixup_offset = try gen.emitJumpInst(.jmp_t);
|
||||
|
|
@ -658,7 +658,7 @@ fn checkSwitchStmt(
|
|||
}
|
||||
|
||||
const block_stmt = case_stmt.data.bin.rhs;
|
||||
try checkBlockStmt(gen, child_scope, block_stmt);
|
||||
try blockStmt(gen, child_scope, block_stmt);
|
||||
const fixup_offset = try gen.emitJumpInst(.jmp);
|
||||
_ = try gen.makeFixup(.{
|
||||
.mode = .relative,
|
||||
|
|
@ -670,47 +670,47 @@ fn checkSwitchStmt(
|
|||
gen.setLabel(gen.exit_label);
|
||||
}
|
||||
|
||||
fn checkInlineLogicExpr(
|
||||
fn inlineLogicExpr(
|
||||
gen: *CodeGen,
|
||||
scope: *Scope,
|
||||
expr_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const main_node = expr_node.data.bin.lhs;
|
||||
assert(main_node != null);
|
||||
return checkExpr(gen, scope, main_node);
|
||||
return expr(gen, scope, main_node);
|
||||
}
|
||||
|
||||
fn checkContentExpr(
|
||||
fn contentExpr(
|
||||
gen: *CodeGen,
|
||||
scope: *Scope,
|
||||
expr_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const node_list = expr_node.data.list.items orelse return;
|
||||
for (node_list) |child_node| {
|
||||
switch (child_node.tag) {
|
||||
.string_literal => {
|
||||
try checkStringLiteral(gen, child_node);
|
||||
try stringLiteral(gen, child_node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
},
|
||||
.inline_logic_expr => {
|
||||
try checkInlineLogicExpr(gen, scope, child_node);
|
||||
try inlineLogicExpr(gen, scope, child_node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
},
|
||||
.if_stmt => try checkIfStmt(gen, scope, child_node),
|
||||
.multi_if_stmt => try checkMultiIfStmt(gen, scope, child_node),
|
||||
.switch_stmt => try checkSwitchStmt(gen, scope, child_node),
|
||||
.if_stmt => try ifStmt(gen, scope, child_node),
|
||||
.multi_if_stmt => try multiIfStmt(gen, scope, child_node),
|
||||
.switch_stmt => try switchStmt(gen, scope, child_node),
|
||||
else => return error.NotImplemented,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn checkContentStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) CheckError!void {
|
||||
fn contentStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
const expr_node = stmt_node.data.bin.lhs orelse return;
|
||||
try checkContentExpr(gen, scope, expr_node);
|
||||
try contentExpr(gen, scope, expr_node);
|
||||
try gen.emitSimpleInst(.stream_flush);
|
||||
}
|
||||
|
||||
fn checkAssignStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) CheckError!void {
|
||||
fn assignStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
const identifier_node = stmt_node.data.bin.lhs orelse unreachable;
|
||||
const expr_node = stmt_node.data.bin.rhs orelse unreachable;
|
||||
const name_ref = try gen.astgen.stringFromNode(identifier_node);
|
||||
|
|
@ -720,13 +720,13 @@ fn checkAssignStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) Che
|
|||
if (data.is_constant) {
|
||||
return gen.fail(.assignment_to_const, identifier_node);
|
||||
}
|
||||
try checkExpr(gen, scope, expr_node);
|
||||
try expr(gen, scope, expr_node);
|
||||
try gen.emitConstInst(.store_global, data.constant_slot);
|
||||
try gen.emitSimpleInst(.pop);
|
||||
return;
|
||||
},
|
||||
.local => |data| {
|
||||
try checkExpr(gen, scope, expr_node);
|
||||
try expr(gen, scope, expr_node);
|
||||
try gen.emitConstInst(.store, data.stack_slot);
|
||||
try gen.emitSimpleInst(.pop);
|
||||
return;
|
||||
|
|
@ -736,7 +736,7 @@ fn checkAssignStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) Che
|
|||
return gen.fail(.unknown_identifier, identifier_node);
|
||||
}
|
||||
|
||||
fn checkChoiceStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) CheckError!void {
|
||||
fn choiceStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
const Choice = struct {
|
||||
label_index: usize,
|
||||
start_expression: ?*const Ast.Node,
|
||||
|
|
@ -761,11 +761,11 @@ fn checkChoiceStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) Che
|
|||
const label_index = try gen.makeLabel();
|
||||
|
||||
if (branch_expr_data.start_expr) |node| {
|
||||
try checkStringLiteral(gen, node);
|
||||
try stringLiteral(gen, node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
}
|
||||
if (branch_expr_data.option_expr) |node| {
|
||||
try checkStringLiteral(gen, node);
|
||||
try stringLiteral(gen, node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
}
|
||||
|
||||
|
|
@ -793,24 +793,24 @@ fn checkChoiceStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) Che
|
|||
gen.setLabel(choice.label_index);
|
||||
|
||||
if (choice.start_expression) |expr_node| {
|
||||
try checkStringLiteral(gen, expr_node);
|
||||
try stringLiteral(gen, expr_node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
}
|
||||
if (choice.inner_expression) |expr_node| {
|
||||
try checkStringLiteral(gen, expr_node);
|
||||
try stringLiteral(gen, expr_node);
|
||||
try gen.emitSimpleInst(.stream_push);
|
||||
}
|
||||
|
||||
try gen.emitSimpleInst(.stream_flush);
|
||||
if (choice.block_stmt) |block| {
|
||||
try checkBlockStmt(gen, scope, block);
|
||||
try blockStmt(gen, scope, block);
|
||||
} else {
|
||||
try gen.emitSimpleInst(.exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn checkVarDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) !void {
|
||||
fn varDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) !void {
|
||||
const identifier_node = decl_node.data.bin.lhs orelse unreachable;
|
||||
const expr_node = decl_node.data.bin.rhs orelse unreachable;
|
||||
const name_ref = try gen.astgen.stringFromNode(identifier_node);
|
||||
|
|
@ -840,7 +840,7 @@ fn checkVarDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) !void
|
|||
};
|
||||
|
||||
try scope.insert(name_ref, decl_symbol);
|
||||
try checkExpr(gen, scope, expr_node);
|
||||
try expr(gen, scope, expr_node);
|
||||
|
||||
switch (decl_symbol) {
|
||||
.local => |data| {
|
||||
|
|
@ -854,28 +854,28 @@ fn checkVarDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) !void
|
|||
try gen.emitSimpleInst(.pop);
|
||||
}
|
||||
|
||||
fn checkStmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) CheckError!void {
|
||||
fn stmt(gen: *CodeGen, scope: *Scope, stmt_node: *const Ast.Node) InnerError!void {
|
||||
switch (stmt_node.tag) {
|
||||
.var_decl => try checkVarDecl(gen, scope, stmt_node),
|
||||
.const_decl => try checkVarDecl(gen, scope, stmt_node),
|
||||
.temp_decl => try checkVarDecl(gen, scope, stmt_node),
|
||||
.assign_stmt => try checkAssignStmt(gen, scope, stmt_node),
|
||||
.content_stmt => try checkContentStmt(gen, scope, stmt_node),
|
||||
.choice_stmt => try checkChoiceStmt(gen, scope, stmt_node),
|
||||
.expr_stmt => try checkExprStmt(gen, scope, stmt_node),
|
||||
.var_decl => try varDecl(gen, scope, stmt_node),
|
||||
.const_decl => try varDecl(gen, scope, stmt_node),
|
||||
.temp_decl => try varDecl(gen, scope, stmt_node),
|
||||
.assign_stmt => try assignStmt(gen, scope, stmt_node),
|
||||
.content_stmt => try contentStmt(gen, scope, stmt_node),
|
||||
.choice_stmt => try choiceStmt(gen, scope, stmt_node),
|
||||
.expr_stmt => try exprStmt(gen, scope, stmt_node),
|
||||
else => return error.NotImplemented,
|
||||
}
|
||||
}
|
||||
|
||||
fn checkBlockStmt(
|
||||
fn blockStmt(
|
||||
gen: *CodeGen,
|
||||
parent_scope: *Scope,
|
||||
block_stmt: ?*const Ast.Node,
|
||||
) CheckError!void {
|
||||
if (block_stmt) |stmt| {
|
||||
) InnerError!void {
|
||||
if (block_stmt) |stmt_node| {
|
||||
const block_scope = try gen.astgen.createScope(parent_scope);
|
||||
const children = stmt.data.list.items orelse return;
|
||||
for (children) |child_stmt| try checkStmt(gen, block_scope, child_stmt);
|
||||
const children = stmt_node.data.list.items orelse return;
|
||||
for (children) |child_stmt| try stmt(gen, block_scope, child_stmt);
|
||||
} else {
|
||||
const fixup_offset = try gen.emitJumpInst(.jmp);
|
||||
_ = try gen.makeFixup(.{
|
||||
|
|
@ -886,11 +886,11 @@ fn checkBlockStmt(
|
|||
}
|
||||
}
|
||||
|
||||
fn checkDefaultBlock(
|
||||
fn defaultBlock(
|
||||
gen: *CodeGen,
|
||||
parent_scope: *Scope,
|
||||
body_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const name_ref = try gen.astgen.stringFromBytes("$__main__$");
|
||||
const exit_label = try gen.makeLabel();
|
||||
defer gen.setExit(exit_label);
|
||||
|
|
@ -898,17 +898,17 @@ fn checkDefaultBlock(
|
|||
gen.chunk_name_ref = name_ref;
|
||||
|
||||
const block_scope = try gen.astgen.createScope(parent_scope);
|
||||
try checkBlockStmt(gen, block_scope, body_node);
|
||||
try blockStmt(gen, block_scope, body_node);
|
||||
gen.setLabel(exit_label);
|
||||
try gen.emitSimpleInst(.exit);
|
||||
try gen.finalize();
|
||||
}
|
||||
|
||||
fn checkStitchDecl(_: *CodeGen, _: *Scope, _: *const Ast.Node) CheckError!void {}
|
||||
fn stitchDecl(_: *CodeGen, _: *Scope, _: *const Ast.Node) InnerError!void {}
|
||||
|
||||
fn checkFunctionDecl(_: *CodeGen, _: *Scope, _: *const Ast.Node) CheckError!void {}
|
||||
fn functionDecl(_: *CodeGen, _: *Scope, _: *const Ast.Node) InnerError!void {}
|
||||
|
||||
fn checkKnotDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) CheckError!void {
|
||||
fn knotDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
||||
const prototype_node = decl_node.data.knot_decl.prototype;
|
||||
const nested_decls_list = decl_node.data.knot_decl.children orelse return;
|
||||
const identifier_node = prototype_node.data.bin.lhs orelse unreachable;
|
||||
|
|
@ -922,19 +922,19 @@ fn checkKnotDecl(gen: *CodeGen, scope: *Scope, decl_node: *const Ast.Node) Check
|
|||
var start_index: usize = 0;
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try checkBlockStmt(&block_gen, knot_scope, first_child);
|
||||
try blockStmt(&block_gen, knot_scope, first_child);
|
||||
if (nested_decls_list.len > 1) start_index += 1 else return;
|
||||
}
|
||||
for (nested_decls_list[start_index..]) |nested_decl_node| {
|
||||
switch (decl_node.tag) {
|
||||
.stitch_decl => try checkStitchDecl(gen, knot_scope, nested_decl_node),
|
||||
.function_decl => try checkFunctionDecl(gen, knot_scope, nested_decl_node),
|
||||
.stitch_decl => try stitchDecl(gen, knot_scope, nested_decl_node),
|
||||
.function_decl => try functionDecl(gen, knot_scope, nested_decl_node),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn checkFile(astgen: *AstGen, scope: *Scope, file_node: *const Ast.Node) CheckError!void {
|
||||
fn file(astgen: *AstGen, scope: *Scope, file_node: *const Ast.Node) InnerError!void {
|
||||
const nested_decls_list = file_node.data.list.items orelse return;
|
||||
if (nested_decls_list.len == 0) return;
|
||||
|
||||
|
|
@ -954,20 +954,20 @@ fn checkFile(astgen: *AstGen, scope: *Scope, file_node: *const Ast.Node) CheckEr
|
|||
var start_index: usize = 0;
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try checkDefaultBlock(&gen, scope, first_child);
|
||||
try defaultBlock(&gen, scope, first_child);
|
||||
if (nested_decls_list.len > 1) start_index += 1 else return;
|
||||
}
|
||||
for (nested_decls_list[start_index..]) |child_node| {
|
||||
switch (child_node.tag) {
|
||||
.knot_decl => try checkKnotDecl(&gen, scope, child_node),
|
||||
.stitch_decl => try checkStitchDecl(&gen, scope, child_node),
|
||||
.function_decl => try checkFunctionDecl(&gen, scope, child_node),
|
||||
.knot_decl => try knotDecl(&gen, scope, child_node),
|
||||
.stitch_decl => try stitchDecl(&gen, scope, child_node),
|
||||
.function_decl => try functionDecl(&gen, scope, child_node),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn insertDecl(astgen: *AstGen, parent_scope: *Scope, proto_node: *const Ast.Node) CheckError!void {
|
||||
fn insertDecl(astgen: *AstGen, parent_scope: *Scope, proto_node: *const Ast.Node) InnerError!void {
|
||||
const identifier_node = proto_node.data.bin.lhs orelse unreachable;
|
||||
const name_ref = try astgen.stringFromNode(identifier_node);
|
||||
|
||||
|
|
@ -1031,7 +1031,7 @@ fn collectRootDecls(
|
|||
astgen: *AstGen,
|
||||
parent_scope: *Scope,
|
||||
root_node: *const Ast.Node,
|
||||
) CheckError!void {
|
||||
) InnerError!void {
|
||||
const root_decl_list = root_node.data.list.items orelse return;
|
||||
for (root_decl_list) |root_decl_node| switch (root_decl_node.tag) {
|
||||
.knot_decl => {
|
||||
|
|
@ -1080,7 +1080,7 @@ pub fn generate(gpa: std.mem.Allocator, tree: *const Ast) !CodeUnit {
|
|||
|
||||
const root_node = tree.root orelse unreachable;
|
||||
try collectRootDecls(&astgen, file_scope, root_node);
|
||||
try checkFile(&astgen, file_scope, root_node);
|
||||
try file(&astgen, file_scope, root_node);
|
||||
|
||||
return .{
|
||||
.string_bytes = try astgen.string_bytes.toOwnedSlice(gpa),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue