diff --git a/lib/rivet/src/ast/comptime.ri b/lib/rivet/src/ast/comptime.ri index ed83422ff..06aa85422 100644 --- a/lib/rivet/src/ast/comptime.ri +++ b/lib/rivet/src/ast/comptime.ri @@ -9,10 +9,10 @@ import ../report; pub struct ComptimeIf { mut branches: []mut ComptimeIfBranch; - mut branch_idx: ?uint; - has_else: bool; - pos: token.Pos; - mut type: Type; + pub mut branch_idx: ?uint; + pub has_else: bool; + pub pos: token.Pos; + pub mut type: Type; pub func nodes(self) -> ?[]Node { if branch_idx := self.branch_idx { @@ -33,6 +33,9 @@ pub struct ComptimeIfBranch { extend Env { pub func evalue_comptime_if(self, mut comptime_if: ComptimeIf) -> []mut Node { + if branch_idx := comptime_if.branch_idx { + return comptime_if.branches[branch_idx].nodes; + } for i, branch in comptime_if.branches { if branch.is_else && comptime_if.branch_idx == none { comptime_if.branch_idx = i; diff --git a/lib/rivet/src/checker/decls.ri b/lib/rivet/src/checker/decls.ri index 0e9e085c0..27f47a1f6 100644 --- a/lib/rivet/src/checker/decls.ri +++ b/lib/rivet/src/checker/decls.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; @@ -30,6 +30,12 @@ extend Checker { old_sym := self.sym; defer self.sym = old_sym; match decl { + .ComptimeIf(mut comptime_if) -> { + mut decls := ast.nodes_to_decls( + self.env.evalue_comptime_if(comptime_if) + ); + self.check_decls(decls); + }, .Import(import_decl) -> if import_decl.import_list.is_empty() && !import_decl.glob { if import_decl.has_custom_alias { self.check_name_case( diff --git a/lib/rivet/src/checker/exprs.ri b/lib/rivet/src/checker/exprs.ri index f4605c8b1..63dd2f11d 100644 --- a/lib/rivet/src/checker/exprs.ri +++ b/lib/rivet/src/checker/exprs.ri @@ -10,6 +10,13 @@ extend Checker { return match expr { .Empty, .Comment -> .Void, .Type(type) -> type, + .ComptimeIf(mut comptime_if) -> { + mut exprs := ast.nodes_to_exprs( + self.env.evalue_comptime_if(comptime_if) + ); + comptime_if.type = self.check_expr(exprs[0]); + comptime_if.type + }, .LoopControl(loop_control) -> { self.scope_returns = true; if self.loop_control_tracker != .AnyLoop { diff --git a/lib/rivet/src/checker/stmts.ri b/lib/rivet/src/checker/stmts.ri index b99809429..71c561be7 100644 --- a/lib/rivet/src/checker/stmts.ri +++ b/lib/rivet/src/checker/stmts.ri @@ -23,6 +23,12 @@ extend Checker { func check_stmt(mut self, mut stmt: ast.Stmt) { match stmt { + .ComptimeIf(mut comptime_if) -> { + mut stmts := ast.nodes_to_stmts( + self.env.evalue_comptime_if(comptime_if) + ); + self.check_stmts(stmts); + }, .VarDecl(mut var_decl) -> self.check_var_decl( var_decl.lefts, var_decl.right, var_decl.scope, var_decl.pos ), diff --git a/lib/rivet/src/resolver/decls.ri b/lib/rivet/src/resolver/decls.ri index 63f51d081..436623933 100644 --- a/lib/rivet/src/resolver/decls.ri +++ b/lib/rivet/src/resolver/decls.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; @@ -13,6 +13,12 @@ extend Resolver { old_self_sym_is_set := self.self_sym_is_set; match decl { .Empty(empty_pos) -> report.error("BUG: empty declaration found", empty_pos), + .ComptimeIf(mut comptime_if) -> { + mut ct_decls := ast.nodes_to_decls( + self.env.evalue_comptime_if(comptime_if) + ); + self.resolve_decls(ct_decls); + }, .Extern(mut extern_decl) -> self.resolve_decls(extern_decl.decls), .Alias(mut alias_decl) -> if alias_decl.is_typealias { _ = self.resolve_type(alias_decl.parent_type); @@ -168,7 +174,7 @@ extend Resolver { report.error( "{} `{}` has field and {} named `{}`".fmt( self.self_sym.type_of(), self.self_sym.name, sym.type_of(), field_decl.name - ), + ), field_decl.pos ); } diff --git a/lib/rivet/src/resolver/exprs.ri b/lib/rivet/src/resolver/exprs.ri index b230232e1..c3e4a885e 100644 --- a/lib/rivet/src/resolver/exprs.ri +++ b/lib/rivet/src/resolver/exprs.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; @@ -10,6 +10,12 @@ extend Resolver { func resolve_expr(mut self, mut expr: ast.Expr) { match expr { .Empty(empty_pos) -> report.error("bug: unexpected empty expression found", empty_pos), + .ComptimeIf(mut comptime_if) -> { + mut exprs := ast.nodes_to_exprs( + self.env.evalue_comptime_if(comptime_if) + ); + self.resolve_expr(exprs[0]); + }, .Paren(mut paren) -> self.resolve_expr(paren.expr), .Type(mut type) -> _ = self.resolve_type(type), .Ident(mut ident) -> self.resolve_ident(ident), diff --git a/lib/rivet/src/resolver/stmts.ri b/lib/rivet/src/resolver/stmts.ri index 513c6a796..c12ef0b0e 100644 --- a/lib/rivet/src/resolver/stmts.ri +++ b/lib/rivet/src/resolver/stmts.ri @@ -1,15 +1,27 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; import ../report; extend Resolver { + func resolve_stmts(mut self, mut stmts: []mut ast.Stmt) { + for mut stmt in stmts { + self.resolve_stmt(stmt); + } + } + func resolve_stmt(mut self, mut stmt: ast.Stmt) { match stmt { .Comment -> {}, .Empty(empty_pos) -> report.error("bug: unexpected empty statement found", empty_pos), + .ComptimeIf(mut comptime_if) -> { + mut stmts := ast.nodes_to_stmts( + self.env.evalue_comptime_if(comptime_if) + ); + self.resolve_stmts(stmts); + }, .Expr(mut expr) -> self.resolve_expr(expr), .VarDecl(mut var_stmt) -> { for mut left in var_stmt.lefts {