lib/chant/src/parse/constexpr.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const ast = @import("../ast/root.zig");
2 const constant_mod = @import("constant.zig");
3 const expression = @import("expression.zig");
4 const state = @import("state/root.zig");
5 const Error = @import("error.zig").Error;
6
7 const diagnostic = state.diagnostic;
8 const object = state.object;
9 const Parser = state.Parser;
10
11 pub fn validateObject(parser: *Parser, c_type: *const ast.Type, initializer: ?*ast.Expr) Error!?i128 {
12 const expr = initializer orelse
13 return diagnostic.fail(parser, error.InvalidConstant, "constexpr object requires an initializer");
14 if (expression.evaluateIntegerConstant(parser, expr)) |value| return value;
15 const expression_type = (try expression.inferType(parser, expr)) orelse c_type;
16 if (ast.types.isInteger(expression_type)) {
17 return diagnostic.fail(parser, error.InvalidConstant, "constexpr integer initializer is not an integer constant expression");
18 }
19 if (try constant_mod.isScalar(parser, expr)) return null;
20 return diagnostic.fail(parser, error.InvalidConstant, "constexpr initializer is not a constant expression");
21 }
22
23 pub fn registerObject(parser: *Parser, name: []const u8, c_type: *const ast.Type, value: ?i128) Error!void {
24 if (value) |constant| {
25 try object.registerConstant(parser, name, c_type, constant);
26 } else {
27 try object.register(parser, name, c_type);
28 }
29 }