module generator
import (
std.alloc
std.collections
std.strings
)
let Value = type union(@auto) {
String(str),
Number(i64),
Boolean(bool),
}
let Field = type struct {
key: str,
value: Value,
}
let Document = type struct {
fields: std.collections.DynamicArray(Field),
body: str,
}
let Context = type struct {
fields: std.collections.DynamicArray(Field),
}
let Engine = type struct {
allocator: *mut dyn std.alloc.Allocator,
root: str,
output: str,
error: *mut std.strings.StringBuilder,
}
let Stop = type enum {
Eof,
Else,
EndIf,
Error,
}
let append_text(builder: *mut std.strings.StringBuilder, value: str): bool =
builder.append(value.([]u8))
let fail(engine: *mut Engine, message: str): bool {
if engine.error.count == 0 {
_ = append_text(engine.error, message)
}
return false
}
let fail_path(engine: *mut Engine, message: str, path: str): bool {
if engine.error.count == 0 {
_ = append_text(engine.error, message)
_ = append_text(engine.error, path)
}
return false
}
let find_field(fields: []Field, key: str): (Value, bool) {
for field in fields @reversed {
if field.key.eq(key) { return field.value, true }
}
return .String(""), false
}
let set_field(context: *mut Context, field: Field): bool {
for existing.&mut in context.fields.as_mut_slice() {
if existing.key.eq(field.key) {
existing.* = field
return true
}
}
return context.fields.append(field)
}
let copy_context(
allocator: *mut dyn std.alloc.Allocator,
source: *Context,
): (Context, bool) {
let fields, ok = source.fields.duplicate()
if !ok {
return .{ fields=std.collections.DynamicArray(Field).init(allocator) }, false
}
return .{ fields=fields }, true
}