; A CSV reader written as a state machine over bytes: quoted fields, doubled ; quotes inside them, and a count of rows kept in globals. enum State start bare quoted quote-in-quoted once rows-seen: i32 def fields-seen: i32 = 0 const separator = \, ; Frame the body's output with a title line and a closing rule. defmacro(with-section, [title & body]): quote println("--", ~title, "--") ~@body println("-----") fn flush(field: Ptr(Vec(u8)), row: Ptr(Vec(str))) -> () push(deref(row), str(slice(deref(field)))) fields-seen += 1 deref(field) = vec-new(u8) fn parse-line(line: [const u8]) -> Vec(str) let row = vec-new(str) let field = vec-new(u8) let state = State.start for i in range(length(line)) let c = line[i] match state :start -> if c == \" state = :quoted elif c == separator flush(addr(field), addr(row)) else push(field, c) state = :bare State.bare -> if c == separator flush(addr(field), addr(row)) state = :start else push(field, c) :quoted -> if c == \" then state = :quote-in-quoted else push(field, c) :quote-in-quoted -> if c == \" push(field, c) state = :quoted else flush(addr(field), addr(row)) state = :start flush(addr(field), addr(row)) rows-seen += 1 row fn widest(rows: [Vec(str)]) -> i32 let best = 0 for r in range(length(rows)) for f in range(length(rows[r])) best = max(best, i32(length(rows[r][f]))) best fn pad(s: str, width: i32) -> () print(s) let n = width - i32(length(s)) until n <= 0 print(" ") n -= 1 fn main() -> i32 let text = "name,qty,note\npear,3,\"ripe, soft\"\nfig,12,\"said \"\"hi\"\"\"\n,0,none" let frame = arena-new(65536) defer arena-destroy(frame) with-allocator(frame): let lines = split(bytes-view(text), \newline) let rows = vec-new(Vec(str)) for i in range(length(lines)) push(rows, parse-line(lines[i])) let w = widest(slice(rows)) + 1 with-section("table"): for r in range(length(rows)) for f in range(length(rows[r])) let last = f + 1 == length(rows[r]) pad(rows[r][f], if last then 0 else w) println("") println("rows", rows-seen, "fields", fields-seen) comment: parse-line(bytes-view("a,\"b\",c")) 0