update json tree api (#89)

* update json tree api

* sneak in namespacing of types into peripherals, registers, etc

* fix cache api usage, later try cache invalidation
wch-ch32v003
Matt Knight 2 years ago committed by Matt Knight
parent f174713fd3
commit 060b6fbd5a

@ -73,8 +73,7 @@ pub const Regz = struct {
// TODO: improve collision resistance // TODO: improve collision resistance
const basename = std.fs.path.basename(schema_path); const basename = std.fs.path.basename(schema_path);
const extension = std.fs.path.extension(basename); const extension = std.fs.path.extension(basename);
const destination_path = std.fs.path.join(regz.builder.allocator, &.{ const destination_path = regz.builder.cache_root.join(regz.builder.allocator, &.{
regz.builder.cache_root,
"regz", "regz",
std.mem.join(regz.builder.allocator, "", &.{ std.mem.join(regz.builder.allocator, "", &.{
basename[0 .. basename.len - extension.len], basename[0 .. basename.len - extension.len],

@ -180,7 +180,11 @@ fn typesReference(db: Database, type_id: EntityId) ![]const u8 {
defer full_name_components.deinit(); defer full_name_components.deinit();
var id = type_id; var id = type_id;
while (true) {
// hard limit for walking up the tree, if we hit it there's a bug
const count_max: u32 = 8;
var count: u32 = 0;
while (count < count_max) : (count += 1) {
if (db.attrs.name.get(id)) |next_name| if (db.attrs.name.get(id)) |next_name|
try full_name_components.insert(0, next_name) try full_name_components.insert(0, next_name)
else else
@ -190,7 +194,7 @@ fn typesReference(db: Database, type_id: EntityId) ![]const u8 {
id = parent_id id = parent_id
else else
break; break;
} } else @panic("hit limit for reference length");
if (full_name_components.items.len == 0) if (full_name_components.items.len == 0)
return error.CantReference; return error.CantReference;
@ -198,6 +202,16 @@ fn typesReference(db: Database, type_id: EntityId) ![]const u8 {
var full_name = std.ArrayList(u8).init(db.arena.allocator()); var full_name = std.ArrayList(u8).init(db.arena.allocator());
const writer = full_name.writer(); const writer = full_name.writer();
try writer.writeAll("types"); try writer.writeAll("types");
// determine the namespace under 'types' the reference is under
const root_parent_entity_type = db.getEntityType(id).?;
inline for (@typeInfo(Database.EntityType).Enum.fields) |field| {
if (root_parent_entity_type == @field(Database.EntityType, field.name)) {
try writer.print(".{s}s", .{field.name});
break;
}
}
for (full_name_components.items) |component| for (full_name_components.items) |component|
try writer.print(".{s}", .{ try writer.print(".{s}", .{
std.zig.fmtId(component), std.zig.fmtId(component),
@ -290,6 +304,9 @@ fn writeTypes(db: Database, writer: anytype) !void {
\\ \\
); );
if (db.types.peripherals.count() > 0) {
try writer.writeAll("pub const peripherals = struct {\n");
// TODO: order the peripherals alphabetically? // TODO: order the peripherals alphabetically?
var it = db.types.peripherals.iterator(); var it = db.types.peripherals.iterator();
while (it.next()) |entry| { while (it.next()) |entry| {
@ -302,6 +319,9 @@ fn writeTypes(db: Database, writer: anytype) !void {
}; };
} }
try writer.writeAll("};\n");
}
try writer.writeAll("};\n"); try writer.writeAll("};\n");
} }
@ -892,12 +912,14 @@ test "gen.peripheral type with register and field" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ TEST_REGISTER: mmio.Mmio(packed struct(u32) { \\ TEST_REGISTER: mmio.Mmio(packed struct(u32) {
\\ TEST_FIELD: u1, \\ TEST_FIELD: u1,
\\ padding: u31, \\ padding: u31,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -918,18 +940,20 @@ test "gen.peripheral instantiation" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const TEST_DEVICE = struct { \\ pub const TEST_DEVICE = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const TEST0 = @intToPtr(*volatile types.TEST_PERIPHERAL, 0x1000); \\ pub const TEST0 = @intToPtr(*volatile types.peripherals.TEST_PERIPHERAL, 0x1000);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ TEST_REGISTER: mmio.Mmio(packed struct(u32) { \\ TEST_REGISTER: mmio.Mmio(packed struct(u32) {
\\ TEST_FIELD: u1, \\ TEST_FIELD: u1,
\\ padding: u31, \\ padding: u31,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -950,19 +974,21 @@ test "gen.peripherals with a shared type" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const TEST_DEVICE = struct { \\ pub const TEST_DEVICE = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const TEST0 = @intToPtr(*volatile types.TEST_PERIPHERAL, 0x1000); \\ pub const TEST0 = @intToPtr(*volatile types.peripherals.TEST_PERIPHERAL, 0x1000);
\\ pub const TEST1 = @intToPtr(*volatile types.TEST_PERIPHERAL, 0x2000); \\ pub const TEST1 = @intToPtr(*volatile types.peripherals.TEST_PERIPHERAL, 0x2000);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ TEST_REGISTER: mmio.Mmio(packed struct(u32) { \\ TEST_REGISTER: mmio.Mmio(packed struct(u32) {
\\ TEST_FIELD: u1, \\ TEST_FIELD: u1,
\\ padding: u31, \\ padding: u31,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -981,6 +1007,7 @@ test "gen.peripheral with modes" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern union { \\ pub const TEST_PERIPHERAL = extern union {
\\ pub const Mode = enum { \\ pub const Mode = enum {
\\ TEST_MODE1, \\ TEST_MODE1,
@ -1021,6 +1048,7 @@ test "gen.peripheral with modes" {
\\ }), \\ }),
\\ }, \\ },
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1039,6 +1067,7 @@ test "gen.peripheral with enum" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ pub const TEST_ENUM = enum(u4) { \\ pub const TEST_ENUM = enum(u4) {
\\ TEST_ENUM_FIELD1 = 0x0, \\ TEST_ENUM_FIELD1 = 0x0,
@ -1048,6 +1077,7 @@ test "gen.peripheral with enum" {
\\ \\
\\ TEST_REGISTER: u8, \\ TEST_REGISTER: u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1066,6 +1096,7 @@ test "gen.peripheral with enum, enum is exhausted of values" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ pub const TEST_ENUM = enum(u1) { \\ pub const TEST_ENUM = enum(u1) {
\\ TEST_ENUM_FIELD1 = 0x0, \\ TEST_ENUM_FIELD1 = 0x0,
@ -1074,6 +1105,7 @@ test "gen.peripheral with enum, enum is exhausted of values" {
\\ \\
\\ TEST_REGISTER: u8, \\ TEST_REGISTER: u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1092,6 +1124,7 @@ test "gen.field with named enum" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ pub const TEST_ENUM = enum(u4) { \\ pub const TEST_ENUM = enum(u4) {
\\ TEST_ENUM_FIELD1 = 0x0, \\ TEST_ENUM_FIELD1 = 0x0,
@ -1107,6 +1140,7 @@ test "gen.field with named enum" {
\\ padding: u4, \\ padding: u4,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1125,6 +1159,7 @@ test "gen.field with anonymous enum" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const TEST_PERIPHERAL = extern struct { \\ pub const TEST_PERIPHERAL = extern struct {
\\ TEST_REGISTER: mmio.Mmio(packed struct(u8) { \\ TEST_REGISTER: mmio.Mmio(packed struct(u8) {
\\ TEST_FIELD: packed union { \\ TEST_FIELD: packed union {
@ -1138,6 +1173,7 @@ test "gen.field with anonymous enum" {
\\ padding: u4, \\ padding: u4,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1158,13 +1194,14 @@ test "gen.namespaced register groups" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile types.PORT.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile types.peripherals.PORT.PORTB, 0x23);
\\ pub const PORTC = @intToPtr(*volatile types.PORT.PORTC, 0x26); \\ pub const PORTC = @intToPtr(*volatile types.peripherals.PORT.PORTC, 0x26);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORT = struct { \\ pub const PORT = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: u8, \\ PORTB: u8,
@ -1178,6 +1215,7 @@ test "gen.namespaced register groups" {
\\ PINC: u8, \\ PINC: u8,
\\ }; \\ };
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1198,17 +1236,19 @@ test "gen.peripheral with reserved register" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile types.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile types.peripherals.PORTB, 0x23);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: u32, \\ PORTB: u32,
\\ reserved8: [4]u8, \\ reserved8: [4]u8,
\\ PINB: u32, \\ PINB: u32,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1229,17 +1269,19 @@ test "gen.peripheral with count" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile [4]types.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile [4]types.peripherals.PORTB, 0x23);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: u8, \\ PORTB: u8,
\\ DDRB: u8, \\ DDRB: u8,
\\ PINB: u8, \\ PINB: u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1260,18 +1302,20 @@ test "gen.peripheral with count, padding required" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile [4]types.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile [4]types.peripherals.PORTB, 0x23);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: u8, \\ PORTB: u8,
\\ DDRB: u8, \\ DDRB: u8,
\\ PINB: u8, \\ PINB: u8,
\\ padding: [1]u8, \\ padding: [1]u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1292,17 +1336,19 @@ test "gen.register with count" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile types.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile types.peripherals.PORTB, 0x23);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: [4]u8, \\ PORTB: [4]u8,
\\ DDRB: u8, \\ DDRB: u8,
\\ PINB: u8, \\ PINB: u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1323,12 +1369,13 @@ test "gen.register with count and fields" {
\\pub const devices = struct { \\pub const devices = struct {
\\ pub const ATmega328P = struct { \\ pub const ATmega328P = struct {
\\ pub const peripherals = struct { \\ pub const peripherals = struct {
\\ pub const PORTB = @intToPtr(*volatile types.PORTB, 0x23); \\ pub const PORTB = @intToPtr(*volatile types.peripherals.PORTB, 0x23);
\\ }; \\ };
\\ }; \\ };
\\}; \\};
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: [4]mmio.Mmio(packed struct(u8) { \\ PORTB: [4]mmio.Mmio(packed struct(u8) {
\\ TEST_FIELD: u4, \\ TEST_FIELD: u4,
@ -1337,6 +1384,7 @@ test "gen.register with count and fields" {
\\ DDRB: u8, \\ DDRB: u8,
\\ PINB: u8, \\ PINB: u8,
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1355,6 +1403,7 @@ test "gen.field with count, width of one, offset, and padding" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: mmio.Mmio(packed struct(u8) { \\ PORTB: mmio.Mmio(packed struct(u8) {
\\ reserved2: u2, \\ reserved2: u2,
@ -1362,6 +1411,7 @@ test "gen.field with count, width of one, offset, and padding" {
\\ padding: u1, \\ padding: u1,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);
@ -1380,6 +1430,7 @@ test "gen.field with count, multi-bit width, offset, and padding" {
\\const mmio = micro.mmio; \\const mmio = micro.mmio;
\\ \\
\\pub const types = struct { \\pub const types = struct {
\\ pub const peripherals = struct {
\\ pub const PORTB = extern struct { \\ pub const PORTB = extern struct {
\\ PORTB: mmio.Mmio(packed struct(u8) { \\ PORTB: mmio.Mmio(packed struct(u8) {
\\ reserved2: u2, \\ reserved2: u2,
@ -1387,6 +1438,7 @@ test "gen.field with count, multi-bit width, offset, and padding" {
\\ padding: u2, \\ padding: u2,
\\ }), \\ }),
\\ }; \\ };
\\ };
\\}; \\};
\\ \\
, buffer.items); , buffer.items);

@ -602,7 +602,10 @@ fn loadPeripheralInstance(
} }
pub fn toJson(db: Database) !json.ValueTree { pub fn toJson(db: Database) !json.ValueTree {
var arena = ArenaAllocator.init(db.gpa); const arena = try db.gpa.create(ArenaAllocator);
errdefer db.gpa.destroy(arena);
arena.* = ArenaAllocator.init(db.gpa);
errdefer arena.deinit(); errdefer arena.deinit();
const allocator = arena.allocator(); const allocator = arena.allocator();
@ -614,13 +617,13 @@ pub fn toJson(db: Database) !json.ValueTree {
while (device_it.next()) |entry| while (device_it.next()) |entry|
try populateDevice( try populateDevice(
db, db,
&arena, arena,
&devices, &devices,
entry.key_ptr.*, entry.key_ptr.*,
); );
try root.put("version", .{ .String = schema_version }); try root.put("version", .{ .String = schema_version });
try populateTypes(db, &arena, &types); try populateTypes(db, arena, &types);
if (types.count() > 0) if (types.count() > 0)
try root.put("types", .{ .Object = types }); try root.put("types", .{ .Object = types });

Loading…
Cancel
Save