From a7fc04bfbf08921f084ef2f3ceaeee4da8cd95ce Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sun, 19 Nov 2023 13:10:14 +0200 Subject: [preproc.awk] Added a more or less working preprocessor for CSMA, written in AWK --- example.csma | 42 +++++++++++++ preproc.awk | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 example.csma create mode 100644 preproc.awk diff --git a/example.csma b/example.csma new file mode 100644 index 0000000..bc78e34 --- /dev/null +++ b/example.csma @@ -0,0 +1,42 @@ + { + { + { red } + } +} + { +
{ + margin-left: auto; + margin-right: auto; + } +} + +#b { + color: ; +} + + { + #a { + abc: a; + color: ; + margin: 2em; + } + +} + + + + +// This is an example object +{ + .b { + margin: 0.2em; + padding: 0.5em; + } + { + a { + display: table; + + } + } +} + diff --git a/preproc.awk b/preproc.awk new file mode 100644 index 0000000..50f6660 --- /dev/null +++ b/preproc.awk @@ -0,0 +1,188 @@ +BEGIN { + stage1 = 1 + depth = 0 + nql = 0 +} + +function nameQueuePush(name) { + prename = "" + if (nql > 0) { + name = nameQueue[nql-1] "/" name + } + nameQueue[nql++] = name + nameClose[name] = depth +} + +function nameQueueTop() { + return "<" nameQueue[nql - 1] ">" +} + +function nameQueueGet(ind) { + return "<" nameQueue[ind] ">" +} + +function nameCloseTop() { + return nameClose[nameQueue[nql - 1]] +} + +function nameQueuePop() { + delete nameClose[nameQueue[nql - 1]] + delete nameQueue[--nql] +} + +# Comments +/^\/\/.*$/ { + next +} + +# +# Stage 1 +# Gather definitions +# + +# function printNQ() { +# print "All in nameQueue:" +# for (ind in nameQueue) { +# print "[" ind "] " nameQueue[ind] " | " nameClose[nameQueue[ind]] +# } +# } +# +# stage1 { +# print "" +# print $0 +# print "Depth: " depth +# printNQ() +# } + +stage1 && gotNameOnly { + if ($0 ~ /^[[:blank:]]*$/) { + next + } + + gotNameOnly = 0 + if ($0 ~ /^[[:blank:]]*\{/) { + depth++ + next + } + else { + nameQueuePop() + for (ind in nameQueue) { + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS nameOnly + } + } +} + +stage1 && /<[^>]*>[[:blank:]]*\{/ { + match($0, /<[^>]*>/) + nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) + sub(/^[^{]*{[[:blank:]]*/, "") + depth++ + if ($0 == "") next +} + +# Macro placement +stage1 && /<[^>]*>/ { + for (i = 0; i < length(nameQueue); i++) { + sub(/^ /, "") + } + nameOnly = $0 + match($0, /<[^>]*>/); + nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) + gotNameOnly = 1 + next +} + +stage1 && depth >= 1 { + depth += gsub("{", "{") - gsub("}", "}") + + for (i = 0; i < length(nameQueue); i++) { + sub(/^ /, "") + } + + skipORS = 0 + if (depth <= nameCloseTop()) { + sub(/[[:blank:]]*}[[:blank:]]*$/, "") + skipORS = 1 + } + + for (ind in nameQueue) { + if (length(macros[nameQueueGet(ind)]) != 0 && !skipORS) { + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS + } + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] $0 + } + + if (depth <= nameCloseTop()) { + nameQueuePop() + } + next +} + +ENDFILE { + if (stage1) { + stage1 = 0 + stage2 = 1 + depth = 0 + gotNameOnly = 0 + + for (name in macros) { + for (subname in macros) { + gsub(subname, macros[subname], macros[name]) + } + } + } +} + +# +# Stage 2 +# Do placements +# + +stage2 && depth >= 1 { + depth += gsub("{", "{") - gsub("}", "}") + next +} + +stage2 && gotNameOnly { + if ($0 ~ /^[[:blank:]]*$/) { + next + } + + gotNameOnly = 0 + # If is definition + if ($0 ~ /^[[:blank:]]*\{/) { + depth = 1 + macroName = "" + next + } + else { + print macros[macroName] + macroName = "" + } +} + +stage2 && /^[[:blank:]]*<[^>]*>/ { + match($0, /<[^>]*>/) + macroName = substr($0, RSTART, RLENGTH) + if ($0 ~ "{") depth = 1 + else gotNameOnly = 1 + next +} + +stage2 && depth == 0 { + while(match($0, /<[^>]*>/)) { + macroName = substr($0, RSTART, RLENGTH) + sub(macroName, macros[macroName]) + } + print +} + +END { + if (macroName != "") + print macros[macroName] + + # print "All macros:" + # for (macroName in macros) { + # print macroName ORS macros[macroName] + # } +} -- cgit v1.2.3