aboutsummaryrefslogtreecommitdiff
path: root/preproc.awk
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2023-11-19 13:10:14 +0200
committerSyndamia <kamen@syndamia.com>2023-11-19 13:10:14 +0200
commita7fc04bfbf08921f084ef2f3ceaeee4da8cd95ce (patch)
treeadfe8a6ba5f78601d27f2393d97d0555bb14db57 /preproc.awk
parent23feb41a42e580f8e842dd99e8950785a0324bfa (diff)
downloadcsma-a7fc04bfbf08921f084ef2f3ceaeee4da8cd95ce.tar
csma-a7fc04bfbf08921f084ef2f3ceaeee4da8cd95ce.tar.gz
csma-a7fc04bfbf08921f084ef2f3ceaeee4da8cd95ce.zip
[preproc.awk] Added a more or less working preprocessor for CSMA, written in AWK
Diffstat (limited to 'preproc.awk')
-rw-r--r--preproc.awk188
1 files changed, 188 insertions, 0 deletions
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]
+ # }
+}