tiny.chant.parse.auto
Defined in parse.
API (2)
Actions
Public operations.
Source
Source: lib/chant/src/parse/auto.zig
zig
const std = @import("std");const ast = @import("../ast/root.zig");const expression = @import("expression.zig");const state = @import("state/root.zig");const diagnostic = state.diagnostic;const memory = state.memory;const Error = @import("error.zig").Error;const Parser = state.Parser;pub fn resolve(parser: *Parser, declared: *const ast.Type, initializer: ?*ast.Expr) Error!*const ast.Type { if (!contains(declared)) return declared; const value = initializer orelse return diagnostic.fail(parser, error.ExpectedType, "auto declarations require an initializer"); const inferred = (try expression.inferType(parser, value)) orelse return diagnostic.fail(parser, error.UnsupportedConstruct, "auto initializer type cannot be inferred"); const resolved = (try replace(parser, declared, inferred)) orelse return diagnostic.fail(parser, error.UnsupportedConstruct, "auto declarator shape does not match initializer"); return resolved;}pub fn contains(c_type: *const ast.Type) bool { if (c_type.kind == .auto_type) return true; if (c_type.child) |child| return contains(child); return false;}fn replace(parser: *Parser, declared: *const ast.Type, inferred: *const ast.Type) Error!?*const ast.Type { if (declared.kind == .auto_type) return inferred; if (!contains(declared)) return declared; if (declared.kind != inferred.kind) return null; const type_origin = parser.nodes.typeOrigin(declared) orelse unreachable; const node = try memory.createType( parser, declared.*, memory.derivedType(type_origin, false), ); if (declared.child) |declared_child| { const inferred_child = inferred.child orelse return null; node.child = (try replace(parser, declared_child, inferred_child)) orelse return null; } node.is_unsigned = inferred.is_unsigned; node.array_len = inferred.array_len; node.vla_len = inferred.vla_len; node.params = inferred.params; node.variadic = inferred.variadic; return node;}test "auto resolves simple and pointer declarations" { const lexer = @import("../lexer/root.zig"); var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const arena = arena_state.allocator(); const source = "1 + 0"; const token_survey = try lexer.survey(source, "auto.c"); const capacity = try lexer.Capacity.derive(token_survey.limits); const bytes = try arena.alignedAlloc( u8, .fromByteUnits(lexer.Storage.storage_alignment), capacity.storage_bytes, ); var storage = try lexer.Storage.init(bytes, token_survey.limits); storage.activate(); defer _ = storage.deinit(); const tokens = try storage.fill(token_survey, source, "auto.c"); var parser = try @import("state/test.zig").initParser(arena, tokens); const expr = try expression.parseExpression(&parser); const scalar = try resolve(&parser, &ast.types.auto_type, expr); try std.testing.expectEqual(ast.types.Kind.int_type, scalar.kind); const pointer = try memory.createType( &parser, .{ .kind = .pointer, .child = &ast.types.auto_type }, memory.directType(0, null), ); const inferred = try memory.createType( &parser, .{ .kind = .pointer, .child = &ast.types.double_type }, memory.directType(1, null), ); const resolved = (try replace(&parser, pointer, inferred)).?; try std.testing.expectEqual(ast.types.Kind.double_type, resolved.child.?.kind);}Source: lib/chant/src/parse/root.zig:10
zig
pub const auto = @import("auto.zig");Audit
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |