summaryrefslogtreecommitdiff
path: root/data.lp
diff options
context:
space:
mode:
Diffstat (limited to 'data.lp')
-rw-r--r--data.lp108
1 files changed, 73 insertions, 35 deletions
diff --git a/data.lp b/data.lp
index 329cd14..ee40f5d 100644
--- a/data.lp
+++ b/data.lp
@@ -19,6 +19,8 @@ This file contains the various data processing-related constants and functions r
@= Section searching function
+@= Command type detection function
+
@= Parsing functions
@= Code generation functions
@@ -111,7 +113,7 @@ We also define the set of errors which may be encountered by the various process
- References to nonexistent section names or configuration commands.
@: Error set
-pub const Errors = error{
+pub const Errors = error {
UnexpectedStart,
UnexpectedEnd,
DereferenceLimit,
@@ -198,6 +200,26 @@ fn search(list: []Section, name: []const u8) !usize {
## Parsing
+We first define a function which, for a given line, determines whether it consists of a formatting command, and which type of command it contains. This is done in order to enable the use of switch statements in later functions using this routine.
+
+@: Command type detection function
+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;
+ }
+}
+@.
+
We then define the parsing functions, consisting of the main `parse` function which builds the list of `Section`s, and its auxiliary `parse_code` subroutine which builds the contents of each `CodeSection`.
@: Parsing functions
@@ -235,15 +257,20 @@ The main parsing routine iterates over the list of lines, adding code sections w
var i: u32 = 0;
while (i < lines.len) {
const line = lines[i];
- if (std.mem.startsWith(u8, line, k_start)) {
- @= Add new section
- } else if (std.mem.startsWith(u8, line, k_add)) {
- @= Append to section
- } 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 => {
+ @= Add new section
+ },
+ .add => {
+ @= Append to section
+ },
+ .end => {
+ log(.err, "line {d}: unexpected section end", .{i + 1});
+ return error.UnexpectedEnd;
+ },
+ else => {
+ i += 1;
+ },
}
}
@.
@@ -283,15 +310,20 @@ The code parsing subroutine iterates over the list of lines similarly to the mai
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)) {
- @= Add reference
- } else if (std.mem.eql(u8, line, k_end)) {
- break;
- } else {
- @= Add literal range
+ switch (command_type(line)) {
+ .start, .add => {
+ log(.err, "line {d}: unexpected section start", .{i + 1});
+ return error.UnexpectedStart;
+ },
+ .ref => {
+ @= Add reference
+ },
+ .end => {
+ break;
+ },
+ else => {
+ @= Add literal range
+ },
}
}
@.
@@ -392,16 +424,22 @@ pub fn textgen(lines: [][]const u8, alloc: Allocator) ![][]const u8 {
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)) {
- @= Format starting command
- } else if (std.mem.startsWith(u8, line, k_add)) {
- @= Format appending command
- } else if (std.mem.startsWith(u8, line, k_end)) {
- @= Format ending command
- } else if (std.mem.startsWith(u8, std.mem.trimLeft(u8, line, " \t"), k_ref)) {
- @= Format reference command
- } else {
- try buffer.append(line);
+ } else switch (command_type(line)) {
+ .start => {
+ @= Format starting command
+ },
+ .add => {
+ @= Format appending command
+ },
+ .ref => {
+ @= Format reference command
+ },
+ .end => {
+ @= Format ending command
+ },
+ else => {
+ try buffer.append(line);
+ },
}
}
@@ -432,12 +470,6 @@ current_name = line[(k_add.len)..];
try buffer.append(try std.mem.join(alloc, current_name, conf_add));
@.
-Processing a section ending command, however, does not require updating the current section name.
-
-@: Format ending command
-try buffer.append(try std.mem.join(alloc, current_name, conf_end));
-@.
-
To process a reference command, the index of the reference command keyword is first extracted. Then the formatted reference string is created, to which the reference command line's leading whitespace is prepended (to preserve indentation).
@: Format reference command
@@ -445,3 +477,9 @@ 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 }));
@.
+
+Processing a section ending command is performed similarly to the starting and appending commands, however it does not require updating the current section name.
+
+@: Format ending command
+try buffer.append(try std.mem.join(alloc, current_name, conf_end));
+@.