diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-07-25 23:45:39 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-07-25 23:45:39 +0200 |
| commit | b4eb1e9ae2fed94726699d5e0a47542dbce5fbc1 (patch) | |
| tree | 27f8562769a5a95ab9859262b4e123f57fdbe931 | |
| parent | b5d5888c59160f5ab30aaaf0288b6ad6d0a81bdd (diff) | |
ev: implement parse and run
| -rwxr-xr-x[-rw-r--r--] | ev | 78 |
1 files changed, 77 insertions, 1 deletions
@@ -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] } |
