diff options
Diffstat (limited to 'src/data.zig')
-rw-r--r-- | src/data.zig | 162 |
1 files changed, 97 insertions, 65 deletions
diff --git a/src/data.zig b/src/data.zig index f2ee9d9..824d36c 100644 --- a/src/data.zig +++ b/src/data.zig @@ -88,6 +88,22 @@ fn search(list: []Section, name: []const u8) !usize { } // TODO return last match instead? +const CommandType = enum { start, add, end, ref, none }; + +fn command_type(line: []const u8) CommandType { + if (std.mem.startsWith(u8, line, k_start)) { + return .start; + } else if (std.mem.startsWith(u8, line, k_add)) { + return .add; + } else if (std.mem.eql(u8, line, k_end)) { + return .end; + } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { + return .ref; + } else { + return .none; + } +} + pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section { var sections = std.ArrayList(Section).init(alloc); defer sections.deinit(); @@ -95,32 +111,37 @@ pub fn parse(lines: [][]const u8, alloc: Allocator) ![]Section { var i: u32 = 0; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start)) { - const name = line[(k_start.len)..]; - log(.debug, "({d}) starting section '{s}'", .{ i + 1, name }); - - const section = try parse_code(lines, i + 1, alloc); - try sections.append(.{ .name = name, .content = section.content }); - - log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); - i = section.index; - } else if (std.mem.startsWith(u8, line, k_add)) { - const name = line[(k_add.len)..]; - log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name }); - - const section = try parse_code(lines, i + 1, alloc); - const index = try search(sections.items, name); - const old = §ions.items[index]; - const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content }); - old.*.content = new; - - log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); - i = section.index; - } else if (std.mem.eql(u8, line, k_end)) { - log(.err, "line {d}: unexpected section end", .{i + 1}); - return error.UnexpectedEnd; - } else { - i += 1; + switch (command_type(line)) { + .start => { + const name = line[(k_start.len)..]; + log(.debug, "({d}) starting section '{s}'", .{ i + 1, name }); + + const section = try parse_code(lines, i + 1, alloc); + try sections.append(.{ .name = name, .content = section.content }); + + log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); + i = section.index; + }, + .add => { + const name = line[(k_add.len)..]; + log(.debug, "({d}) appending to section '{s}'", .{ i + 1, name }); + + const section = try parse_code(lines, i + 1, alloc); + const index = try search(sections.items, name); + const old = §ions.items[index]; + const new = try std.mem.concat(alloc, Content, &[_][]const Content{ old.*.content, section.content }); + old.*.content = new; + + log(.debug, "({d}) ending section '{s}'", .{ section.index, name }); + i = section.index; + }, + .end => { + log(.err, "line {d}: unexpected section end", .{i + 1}); + return error.UnexpectedEnd; + }, + else => { + i += 1; + }, } } @@ -134,32 +155,37 @@ fn parse_code(lines: [][]const u8, index: u32, alloc: Allocator) !CodeReturn { var i = index; while (i < lines.len) { const line = lines[i]; - if (std.mem.startsWith(u8, line, k_start) or std.mem.startsWith(u8, line, k_add)) { - log(.err, "line {d}: unexpected section start", .{i + 1}); - return error.UnexpectedStart; - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..]; - try content.append(.{ .reference = ref_name }); - log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name }); - i += 1; - } else if (std.mem.eql(u8, line, k_end)) { - break; - } else { - if (content.items.len > 0) { - switch (content.items[content.items.len - 1]) { - .literal => |*range| { - range.*.end = i; - }, - .reference => { - try content.append(.{ .literal = .{ .start = i, .end = i } }); - log(.debug, "({d}) \tappending literal", .{i + 1}); - }, + switch (command_type(line)) { + .start, .add => { + log(.err, "line {d}: unexpected section start", .{i + 1}); + return error.UnexpectedStart; + }, + .ref => { + const ref_name = std.mem.trimLeft(u8, line, " \t")[(k_ref.len)..]; + try content.append(.{ .reference = ref_name }); + log(.debug, "({d}) \tappended reference '{s}'", .{ i + 1, ref_name }); + i += 1; + }, + .end => { + break; + }, + else => { + if (content.items.len > 0) { + switch (content.items[content.items.len - 1]) { + .literal => |*range| { + range.*.end = i; + }, + .reference => { + try content.append(.{ .literal = .{ .start = i, .end = i } }); + log(.debug, "({d}) \tappending literal", .{i + 1}); + }, + } + } else { + try content.append(.{ .literal = .{ .start = i, .end = i } }); + log(.debug, "({d}) \tappending literal", .{i + 1}); } - } else { - try content.append(.{ .literal = .{ .start = i, .end = i } }); - log(.debug, "({d}) \tappending literal", .{i + 1}); - } - i += 1; + i += 1; + }, } } @@ -214,20 +240,26 @@ pub fn textgen(lines: [][]const u8, alloc: Allocator) ![][]const u8 { for (lines) |line| { if (std.mem.startsWith(u8, line, kc_start) or std.mem.startsWith(u8, line, kc_add) or std.mem.startsWith(u8, line, kc_end) or std.mem.startsWith(u8, line, kc_ref)) { continue; - } else if (std.mem.startsWith(u8, line, k_start)) { - current_name = line[(k_start.len)..]; - try buffer.append(try std.mem.join(alloc, current_name, conf_start)); - } else if (std.mem.startsWith(u8, line, k_add)) { - current_name = line[(k_add.len)..]; - try buffer.append(try std.mem.join(alloc, current_name, conf_add)); - } else if (std.mem.startsWith(u8, line, k_end)) { - try buffer.append(try std.mem.join(alloc, current_name, conf_end)); - } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) { - const start = std.mem.indexOf(u8, line, k_ref).?; - const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); - try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref })); - } else { - try buffer.append(line); + } else switch (command_type(line)) { + .start => { + current_name = line[(k_start.len)..]; + try buffer.append(try std.mem.join(alloc, current_name, conf_start)); + }, + .add => { + current_name = line[(k_add.len)..]; + try buffer.append(try std.mem.join(alloc, current_name, conf_add)); + }, + .ref => { + const start = std.mem.indexOf(u8, line, k_ref).?; + const ref = try std.mem.join(alloc, line[(start + k_ref.len)..], conf_ref); + try buffer.append(try std.mem.concat(alloc, u8, &[_][]const u8{ line[0..start], ref })); + }, + .end => { + try buffer.append(try std.mem.join(alloc, current_name, conf_end)); + }, + else => { + try buffer.append(line); + }, } } |