A Lisp implemented in AWK
# SPDX-License-Identifier: BSD-2-Clause

# debugging print
function logg_setup(       log_ats, i) {
    # default LOG_LEVEL if not specified using awk's -v switch
    if(LOG_LEVEL == 0) LOG_LEVEL = 1
    delete CUSTOM_LEVEL[1]
    delete log_ats
    if(LOG_AT_ERR) {
        split(LOG_AT_ERR, log_ats, ",")
        for(i in log_ats) CUSTOM_LEVEL[log_ats[i]] = 1;
    }
    delete log_ats
    if(LOG_AT_INF) {
        split(LOG_AT_INF, log_ats, ",")
        for(i in log_ats) CUSTOM_LEVEL[log_ats[i]] = 2;
    }
    delete log_ats
    if(LOG_AT_DBG) {
        split(LOG_AT_DBG, log_ats, ",")
        for(i in log_ats) CUSTOM_LEVEL[log_ats[i]] = 3;
    }
    for(i in CUSTOM_LEVEL) {
        print "custom log level " CUSTOM_LEVEL[i] " for " i
}
}


function repeat_string(s, times,      q, r, tmp) {
    if(times==0) return ""
    else if(times==1) return s
    else {
        q = int(times / 2)
        r = times % 2
        tmp = repeat_string(s, q)
        if(r) return (tmp tmp s)
        else  return (tmp tmp)
    }
}

function sp(n) {
    return repeat_string(" ", n)
}

function binary_ticks(n,      r, s) {
    s=""
    for(d=0; d < depth_binary_digits; d++) {
        r = n%2
        if(r) s = "'" s
        else  s = " " s
        n = int(n/2)
    }
    if(n) return repeat_string("#", depth_binary_digits)
    else  return s
}

function represent_depth(d,    to_rep) {
    # memoize
    to_rep = d
    if(to_rep in depth_representations) {
        return depth_representations[to_rep]
    } else {
        # ("[" binary_ticks(d) "]")
        return (depth_representations[to_rep] = sp(to_rep))
    }
}

function logg_dbg(where, x, d,     lev) {
    lev = LOG_LEVEL
    if(where in CUSTOM_LEVEL)
        lev = CUSTOM_LEVEL[where]
    if(lev >= 3)
            print "DBG" represent_depth(d) where ": " x >"/dev/stderr"
}

function logg_inf(where, x, d,     lev) {
    lev = LOG_LEVEL
    if(where in CUSTOM_LEVEL)
        lev = CUSTOM_LEVEL[where]
    if(lev >= 2)
        if(!(where in NO_LOG))
            print "INF" represent_depth(d) where ": " x >"/dev/stderr"
}

function logg_err(where, x, d,     lev) {
    lev = LOG_LEVEL
    if(where in CUSTOM_LEVEL)
        lev = CUSTOM_LEVEL[where]
    if(lev >= 1)
        print "ERR" represent_depth(d) where ": " x >"/dev/stderr"
}

BEGIN {
    depth_binary_digits = 8
    logg_setup()
}