#!/usr/bin/awk -f # SQU.AWK --- a lisp in awk # (C) 2022 Case Duckworth ### Commentary: # Why am I doing this? ### Code: BEGIN { nested = 0 buffer = "" OFS = "\t" STDERR = "/dev/stderr" PRGN = "squawk" } { buffer = buffer $0 "\n" } END { read(buffer, ast) eval(ast) } function die(message, errcode) { eprint(PRGN " ERROR" (message ? ": " message : "")) exit (errcode ? errcode : 1) } function eprint(message) { # Print MESSAGE to STDERR. print(message) > STDERR } function eval(ast) { # Evaluate multi-dimensional array AST. for (w in ast) { print ast[w] } } function read(buf, ast) { # Read string BUF into multi-dimensional array AST. split(buf, b, "") w = 1 word = "" # Tokenize for (c in b) { # print c, b[c] if (b[c] == "\\") { word = word b[c++] } else if (b[c] == "(") { if (word) { ast[w++] = word word = "" } ast[w++] = "(" nested++ } else if (b[c] == ")") { if (word) { ast[w++] = word word = "" } ast[w++] = ")" --nested } else if (b[c] ~ /[ \t\r\n\f\v]/) { if (word) { ast[w++] = word word = "" } } else { word = word b[c] } if (nested < 0) { die("Unmatched paren at " c) } } }