summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-07-25 23:45:39 +0200
committerMarc Vertes <mvertes@free.fr>2025-07-25 23:45:39 +0200
commitb4eb1e9ae2fed94726699d5e0a47542dbce5fbc1 (patch)
tree27f8562769a5a95ab9859262b4e123f57fdbe931
parentb5d5888c59160f5ab30aaaf0288b6ad6d0a81bdd (diff)
ev: implement parse and run
-rwxr-xr-x[-rw-r--r--]ev78
1 files changed, 77 insertions, 1 deletions
diff --git a/ev b/ev
index b5f178c..fede0e3 100644..100755
--- a/ev
+++ b/ev
@@ -3,7 +3,83 @@
# an evaluator of code
BEGIN {
+ # prec array contains the precedence order of operators
+ prec["="] = 1
+ prec["+"] = prec["-"] = 2
+ prec["*"] = prec["/"] = 3
+ prec["^"] = 4
+ # rigth array contains operators which are right associative
+ right["="] = right["^"] = 1
+
+ split("", code)
+ split("", mem)
+ printf "> "
+}
+{ line = $0; parse(); run(); printf "> " }
+
+function scan() {
+ sub(/^[ \t]+/, "", line)
+ # print "# line: '" line "'"
+ if (match(line, /^[.0-9]+/)) {
+ tok = "d" substr(line, 1, RLENGTH)
+ } else if (match(line, /^([][}{)(,+-=?:]|[*\/รท\^])/)) {
+ tok = substr(line, 1, RLENGTH)
+ } else if (match(line, /^[A-Za-z_][A-Za-z_0-9]*/)) {
+ tok = "v" substr(line, 1, RLENGTH)
+ } else if (match(line, /^"(\\.|[^\\"])*"/)) {
+ tok = "s" substr(line, 2, RLENGTH-2)
+ } else {
+ tok = "b" substr(line, 1, 1)
+ }
+ # cnum += RLENGTH
+ line = substr(line, RLENGTH+1)
+ # print "# scan: RLENGTH=" RLENGTH
+ return RLENGTH
+}
+
+# TODO: unary operators
+function parse( stack, sl, i) {
+ i = length(code)
+ while (scan() > 0) {
+ if (tok == "(") {
+ stack[++sl] = tok
+ } else if (tok == ")") {
+ while (sl && stack[sl] != "(") code[i++] = stack[sl--]
+ sl--
+ } else if (tok in prec) {
+ # Test precedence against stack, or associativity if same precedence
+ while (sl && (prec[tok] < prec[stack[sl]] || prec[tok] == prec[stack[sl]] && !(stack[sl] in right))) {
+ code[i++] = stack[sl--]
+ }
+ stack[++sl] = tok
+ } else code[i++] = tok
+ }
+ while (sl) code[i++] = stack[sl--]
+ # for (j = 0; j < i; j++) printf("%s ", code[j]); print ""
}
-eval(mem, src) {
+# TODO: assign
+function run( c, i, l, t) {
+ cl = length(code)
+ ml = length(mem)
+ i = 0
+ while (i < cl) {
+ c = code[i]
+ if (c == "+") {
+ mem[--ml] = mem[ml-1] + mem[ml]
+ } else if (c == "-") {
+ mem[--ml] = mem[ml-1] - mem[ml]
+ } else if (c == "*") {
+ mem[--ml] = mem[ml-1] * mem[ml]
+ } else if (c == "/") {
+ mem[--ml] = mem[ml-1] / mem[ml]
+ } else if (c == "^") {
+ mem[--ml] = mem[ml-1] ^ mem[ml]
+ } else {
+ mem[++ml] = 0 + substr(c, 2)
+ }
+ i++
+ }
+ print mem[ml]
+ for (i = ml; i in mem; i++) delete mem[i]
}