diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-07-17 14:27:18 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-07-17 14:27:18 +0200 |
| commit | 3c7bc23285157858b3dc7468e5abbb16e05f31f7 (patch) | |
| tree | 0f06e777692839af9563229df3a2e4f5f3670280 | |
| parent | 23e204ff6544021efbbe4afed13e1680872ec275 (diff) | |
improve naming
| -rwxr-xr-x | mp | 108 | ||||
| -rwxr-xr-x | tests | 33 |
2 files changed, 74 insertions, 67 deletions
@@ -41,8 +41,11 @@ BEGIN { } else if ($1 == "parse") { delete v parse($2, v) - } else if (NF) { + } else if (filename && NF) { error("invalid command: " $1) + } else { + parse("", v, "", $0) + print format(v) } prompt() } @@ -55,13 +58,13 @@ function prompt(s) { if (tty) printf "%s> ", s > "/dev/stderr" } -function scan(name, line, r) { +function scan(infile, line, r) { TOKEN = "" sub(/^[[:space:]]+/, "", line) - if (name) { + if (infile) { while (line == "") { - if ((r = getline line < name) == 0) return - if (r == -1) return error("error read " name) + if ((r = getline line < infile) == 0) return + if (r == -1) return error("error read " infile) sub(/^[[:space:]]+/, "", line) } } @@ -78,47 +81,49 @@ function scan(name, line, r) { return substr(line, RLENGTH+1) } -function parse(name, mem, key, line, id, ids, i, k) { - line = scan(name, line) +function parse(infile, values, key, line, id, ids, i, k) { + line = scan(infile, line) if (TOKEN == "[") { for (i = 0; TOKEN != "]"; i++) { if (i > 0 && TOKEN != ",") return error("not a ','", line) - line = parse(name, mem, key SUBSEP i, line) + line = parse(infile, values, key SUBSEP i, line) if (ERROR) { if (i == 0 && TOKEN == "]") ERROR = "" break } - line = scan(name, line) + line = scan(infile, line) } - mem[key] = "a" + values[key] = "a" } else if (TOKEN == "{") { for (i = 0; TOKEN != "}"; i++) { if (i > 0 && TOKEN != ",") return error("not a ','", line) - line = scan(name, line) + line = scan(infile, line) if (i == 0 && TOKEN == "}") break if (TOKEN !~ /^s/) return error("not a string", line) k = substr(TOKEN, 2) ids = ids (i ? SUBSEP : "") substr(TOKEN, 2) - line = scan(name, line) + line = scan(infile, line) if (TOKEN != ":") return error("not a ':'", line) - line = parse(name, mem, key SUBSEP i, line) + line = parse(infile, values, key SUBSEP i, line) if (ERROR) return line - line = scan(name, line) + line = scan(infile, line) } - mem[key] = "o" ids + values[key] = "o" ids } else if (TOKEN ~ /^[ntfsd]/) { - mem[key] = TOKEN + values[key] = TOKEN } else if (TOKEN) ERROR = "invalid token '" TOKEN "'" return line } -function format(mem, key, indent, id, c, i, s, v, pre, post, ksep) { - if (! (key in mem)) return - pre = indent ? space(indent * 2) : "" - post = indent ? "\n" : "" - ksep = indent ? ": " : ":" - if (id) id = "\"" id "\":" (indent ? " " : "") - v = mem[key] +function format(values, key, indent, id, c, i, s, v, pre, post, sp) { + if (! (key in values)) return + if (indent) { + pre = space(indent * 2) + post = "\n" + sp = " " + } + if (id) id = "\"" id "\":" sp + v = values[key] c = substr(v, 1, 1) if (c == "n") return id "null" if (c == "t") return id "true" @@ -127,19 +132,19 @@ function format(mem, key, indent, id, c, i, s, v, pre, post, ksep) { if (c == "s") return id "\"" substr(v, 2) "\"" if (c == "a") { s = "[" post - for (i = 0; ((key, i) in mem); i++) { + for (i = 0; ((key, i) in values); i++) { if (i) s = s "," post - s = s pre format(mem, key SUBSEP i, indent ? indent+1 : 0) + s = s pre format(values, key SUBSEP i, indent ? indent+1 : 0) } return id s post substr(pre, 3) "]" } if (c == "o") { s = "{" post v = substr(v, 2) - for (i = 0; ((key, i) in mem); i++) { + for (i = 0; ((key, i) in values); i++) { if (i) s = s "," post v = tail(v, SUBSEP) - s = s pre "\"" HEAD "\"" ksep format(mem, key SUBSEP i, indent ? indent+1 : 0) + s = s pre "\"" HEAD "\":" sp format(values, key SUBSEP i, indent ? indent+1 : 0) } return id s post substr(pre, 3) "}" } @@ -157,56 +162,49 @@ function tail(str, sep, i) { } else HEAD = str } -function head(str, sep, i) { - if (i = index(str, sep)) { - TAIL = substr(str, i+1) - return substr(str, 1, i-1) - } - TAIL = "" - return str -} - function lindex(list, item, i, k) { for (i = 0; list; i++) { - if (head(list, SUBSEP) == item) return i - list = TAIL + list = tail(list, SUBSEP) + if (HEAD == item) return i } return -1 } # TODO: remove recursivity -function key(mem, pattern, k1, result, i, k, s, w) { - if (! (k1 in mem)) return +# TODO: handle spaces +function key(values, pattern, k1, result, i, k, s, w) { + if (! (k1 in values)) return gsub(/[.]/, SUBSEP, pattern) - k = head(pattern, SUBSEP) - pattern = TAIL + pattern = tail(pattern, SUBSEP) + k = HEAD if (k ~ /^[0-9]+$/) { result = result SUBSEP k } else { - s = substr(mem[k1], 2) + s = substr(values[k1], 2) if ((i = lindex(s, k)) >= 0) result = result SUBSEP i } - if (pattern) return key(mem, pattern, k1 SUBSEP i, result) + if (pattern) return key(values, pattern, k1 SUBSEP i, result) return result } -function filter(mem, key, sk, i, k, n, v) { - v = mem[key] +function filter(values, key, sk, i, k, n, v) { + v = values[key] if (v ~ /^o/) { v = substr(v, 2) - for (i = 0; v; i++) { - k = head(v, SUBSEP) - print sk "." k - v = TAIL - filter(mem, key SUBSEP i, sk "." k) + for (i = 0; ((key, i) in values); i++) { + v = tail(v, SUBSEP) + k = HEAD + sk = sk ? sk "." k : k + print sk + filter(values, key SUBSEP i, sk) } while (v) return } if (v ~ /^a/) { - n = substr(v, 2) - for (i = 0; i < n; i++) { - print sk "." i - filter(mem, key SUBSEP i, sk "." i) + for (i = 0; ((key, i) in values); i++) { + sk = sk ? sk "." i : i + print sk + filter(values, key SUBSEP i, sk) } } } @@ -3,9 +3,9 @@ run() { [ "$filter" ] && case $1 in ($filter) ;; (*) return; esac - out=$(echo "$2" | ./mp 2>&1) + out=$(printf %s "$2" | ./mp 2>&1) [ "$out" = "$3" ] && pass=$((pass + 1)) && return - printf "%s FAIL\nWant: \"%s\"\n Got: \"%s\"\n" "$1" "$3" "$out" + printf "%s FAIL\nWant: '%s'\n Got: '%s'\n" "$1" "$3" "$out" fail=$((fail + 1)) return 1 } @@ -14,13 +14,22 @@ run() { pass=0 fail=0 filter="$1" trap 'echo "$pass passed, $fail failed"; exit $((fail != 0))' EXIT -run basic_1 'parse_string\nformat' '' -run basic_2 'parse_string null\nformat' 'null' -run basic_3 'parse_string true\nformat' 'true' -run basic_4 'parse_string false\nformat' 'false' -run number_1 'parse_string 12\nformat' '12' -run string_1 'parse_string "hello"\nformat' '"hello"' -run array_1 'parse_string []\nformat' '[]' -run array_2 'parse_string [null]\nformat' '[null]' -run array_3 'parse_string [true,false]\nformat' '[true,false]' -run object_1 'parse_string {}\nformat' '{}' +run basic_1 '' '' +run basic_2 'null' 'null' +run basic_3 'true' 'true' +run basic_4 'false' 'false' +run number_1 '12' '12' +run string_1 '"hello"' '"hello"' +run string_2 '"hello \"world\""' '"hello \"world\""' +run string_3 '""' '""' +run array_1 '[]' '[]' +run array_2 '[null]' '[null]' +run array_3 '[true,false]' '[true,false]' +run object_1 '{}' '{}' +run object_2 '{"":false}' '{"":false}' +run object_3 '{"":false,"1": true}' '{"":false,"1":true}' +run object_4 '{ }' '{}' +run object_5 '{ +}' '{}' +run object_6 '{"id": +1}' '{"id":1}' |
