tiny.chant.lower.local
Defined in lower.
API (1)
Actions
Public operations.
Source
Source: lib/chant/src/lower/local.zig
zig
const std = @import("std");const choir = @import("choir");const ast = @import("../ast/root.zig");const context = @import("context.zig");const convert = @import("convert.zig");const emit = @import("emit.zig");const expression = @import("expression/root.zig");const memory = @import("memory.zig");const scope = @import("scope.zig");const Error = @import("error.zig").Error;const ArithDialect = choir.dialects.ArithDialect;const Lowerer = context.Lowerer;pub fn declare(lowerer: *Lowerer, variable: ast.Variable) Error!void { if (variable.is_thread_local) return error.UnsupportedConstruct; if (variable.type.kind != .array and !ast.types.isArithmetic(variable.type) and variable.type.kind != .pointer) return error.UnsupportedType; if (variable.type.kind == .pointer) return error.UnsupportedConstruct; const slot = try memory.allocaObject(lowerer, variable.type, variable.alignment); try scope.bind(lowerer, variable.name, .{ .kind = .slot, .value = slot, .c_type = variable.type }); if (variable.initializer) |initializer| { if (initializer.* == .initializer_list) { try initializeList(lowerer, slot, variable.type, initializer); return; } if (initializer.* == .string_literal and variable.type.kind == .array) { try initializeString(lowerer, slot, variable.type, initializer.string_literal.text); return; } const value = try expression.lowerExpression(lowerer, initializer); const converted = try convert.convert(lowerer, value.value, value.c_type, variable.type); const zero = try emit.indexConstant(lowerer, 0); try memory.storeElement(lowerer, .{ .memref = slot, .index = zero, .c_type = variable.type }, converted); }}fn initializeList(lowerer: *Lowerer, slot: *choir.Value, c_type: *const ast.Type, initializer: *ast.Expr) Error!void { if (initializer.* != .initializer_list) return error.UnsupportedConstruct; const list = initializer.initializer_list; if (c_type.kind != .array or list.type != c_type) return error.UnsupportedConstruct; const element_type = try memory.scalarElement(c_type); const count = try memory.staticElementCount(c_type); var index: usize = 0; while (index < count) : (index += 1) { try storeAt(lowerer, slot, element_type, index, try zeroValue(lowerer, element_type)); } _ = try writeInitializer(lowerer, slot, c_type, initializer, 0);}fn initializeString(lowerer: *Lowerer, slot: *choir.Value, c_type: *const ast.Type, text: []const u8) Error!void { if (!isCharArray(c_type)) return error.UnsupportedConstruct; const count = try memory.staticElementCount(c_type); if (text.len > count) return error.UnsupportedConstruct; const element_type = try memory.scalarElement(c_type); var index: usize = 0; while (index < count) : (index += 1) { const byte: u8 = if (index < text.len) text[index] else 0; try storeAt(lowerer, slot, element_type, index, try intValue(lowerer, element_type, byte)); }}fn writeInitializer(lowerer: *Lowerer, slot: *choir.Value, c_type: *const ast.Type, value_expr: *ast.Expr, offset: usize) Error!usize { if (value_expr.* == .initializer_list) { const list = value_expr.initializer_list; const capacity = try memory.staticElementCount(list.type); var cursor: usize = 0; for (list.items) |item| { const relative_offset = if (item.designator.len == 0) cursor else try designatorOffset(list.type, item.designator); const target_type = try itemTargetType(list.type, item); const consumed = try writeInitializer(lowerer, slot, target_type, item.value, offset + relative_offset); if (relative_offset + consumed > capacity) return error.UnsupportedConstruct; cursor = relative_offset + consumed; } return capacity; } if (value_expr.* == .string_literal) { if (!isCharArray(c_type)) return error.UnsupportedConstruct; try initializeStringAt(lowerer, slot, c_type, value_expr.string_literal.text, offset); return try memory.staticElementCount(c_type); } const element_type = try memory.scalarElement(c_type); const value = try expression.lowerExpression(lowerer, value_expr); const converted = try convert.convert(lowerer, value.value, value.c_type, element_type); try storeAt(lowerer, slot, element_type, offset, converted); return 1;}fn initializeStringAt(lowerer: *Lowerer, slot: *choir.Value, c_type: *const ast.Type, text: []const u8, base: usize) Error!void { const count = try memory.staticElementCount(c_type); if (text.len > count) return error.UnsupportedConstruct; const element_type = try memory.scalarElement(c_type); var index: usize = 0; while (index < count) : (index += 1) { const byte: u8 = if (index < text.len) text[index] else 0; try storeAt(lowerer, slot, element_type, base + index, try intValue(lowerer, element_type, byte)); }}fn designatorOffset(c_type: *const ast.Type, designator: []const u64) Error!usize { var current = c_type; var offset: usize = 0; for (designator) |index| { if (current.kind != .array) return error.UnsupportedConstruct; if (current.array_len) |len| { if (index >= len) return error.UnsupportedConstruct; } const child = current.child orelse return error.UnsupportedType; const stride = try memory.staticElementCount(child); const scaled = std.math.mul(u64, index, stride) catch return error.UnsupportedConstruct; const scaled_usize: usize = std.math.cast(usize, scaled) orelse return error.UnsupportedConstruct; offset = std.math.add(usize, offset, scaled_usize) catch return error.UnsupportedConstruct; current = child; } return offset;}fn itemTargetType(c_type: *const ast.Type, item: ast.expr.InitializerItem) Error!*const ast.Type { if (item.designator.len != 0) return designatorType(c_type, item.designator); if (item.value.* == .initializer_list) return item.value.initializer_list.type; if (item.value.* == .string_literal and c_type.kind == .array) { if (c_type.child) |child| { if (child.kind == .array and isCharArray(child)) return child; } } return c_type;}fn designatorType(c_type: *const ast.Type, designator: []const u64) Error!*const ast.Type { var current = c_type; for (designator) |index| { if (current.kind != .array) return error.UnsupportedConstruct; if (current.array_len) |len| { if (index >= len) return error.UnsupportedConstruct; } current = current.child orelse return error.UnsupportedType; } return current;}fn storeAt(lowerer: *Lowerer, slot: *choir.Value, element_type: *const ast.Type, index: usize, value: *choir.Value) Error!void { const offset = try emit.indexConstant(lowerer, @intCast(index)); try memory.storeElement(lowerer, .{ .memref = slot, .index = offset, .c_type = element_type }, value);}fn zeroValue(lowerer: *Lowerer, c_type: *const ast.Type) Error!*choir.Value { const result_type = try convert.scalarType(lowerer, c_type); const op = switch (c_type.kind) { .float_type, .double_type, .decimal32_type, .decimal64_type => (ArithDialect.ConstantOp.createFloat(lowerer.ctx, lowerer.loc, result_type, 0.0) catch return error.OutOfMemory).op, else => (ArithDialect.ConstantOp.createInt(lowerer.ctx, lowerer.loc, result_type, 0) catch return error.OutOfMemory).op, }; try emit.append(lowerer, op); return op.getResult(0) orelse return error.UnsupportedConstruct;}fn intValue(lowerer: *Lowerer, c_type: *const ast.Type, value: u8) Error!*choir.Value { const result_type = try convert.scalarType(lowerer, c_type); const op = ArithDialect.ConstantOp.createInt(lowerer.ctx, lowerer.loc, result_type, value) catch return error.OutOfMemory; try emit.append(lowerer, op.op); var mutable = op; return mutable.getResult();}fn isCharArray(c_type: *const ast.Type) bool { if (c_type.kind != .array) return false; const element_type = memory.scalarElement(c_type) catch return false; return element_type.kind == .char_type;}Source: lib/chant/src/lower/root.zig:7
zig
pub const local = @import("local.zig");Complete call list for lower.local.declare
7 direct calls.
tiny.chant.lower.convert.convert[function] atlib/chant/src/lower/convert.zig:75tiny.chant.lower.emit.indexConstant[function] atlib/chant/src/lower/emit.zig:13lib.chant.src.lower.local.initializeList[function] — private source atlib/chant/src/lower/local.zig:39in nearest public ownertiny.chant.lower.locallib.chant.src.lower.local.initializeString[function] — private source atlib/chant/src/lower/local.zig:52in nearest public ownertiny.chant.lower.localtiny.chant.lower.memory.allocaObject[function] atlib/chant/src/lower/memory.zig:27tiny.chant.lower.memory.storeElement[function] atlib/chant/src/lower/memory.zig:59tiny.chant.lower.scope.bind[function] atlib/chant/src/lower/scope.zig:27
Audit
| Definitions | 2 |
|---|---|
| Public names | 2 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |