diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-07-30 14:38:30 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-07-30 14:38:30 +0200 |
| commit | 443ec4b0e051e9c1966afb5367a69ec89ba2b8c7 (patch) | |
| tree | ea5dee6905ce9982820ba13553ab53ba8f06f224 | |
| parent | 39b5ec2e0c34ecf86563cac4d920eacaca74fc79 (diff) | |
fixup
| -rwxr-xr-x | ev | 54 |
1 files changed, 31 insertions, 23 deletions
@@ -1,17 +1,19 @@ #!/usr/bin/env awk -f -# an evaluator of code +# an evaluator of code: scanner, parser and bytecode vm. BEGIN { - # prec array contains the precedence order of operators - prec["="] = 1 + # The prec array contains the precedence level of binary operators. + prec["="] = prec["=="] = prec["!="] = prec["<"] = prec["<="] = prec[">"] = prec[">="] = 1 + prec["+="] = prec["-="] = prec["*="] = prec["/="] = prec["%="] = prec["^="] = 1 prec["+"] = prec["-"] = 2 - prec["*"] = prec["/"] = 3 + prec["*"] = prec["/"] = prec["%"] = 3 prec["^"] = 4 - # rigth array contains operators which are right associative - right["="] = right["^"] = 1 + # The rigth array contains binary operators which are right associative. + right["="] = right["+="] = right["-="] = right["*="] = right["/="] = right["%="] = right["^="] = 1 + right["^"] = 1 - pc = 0 + ml = pc = 0 split("", code) split("", mem) split("", var) @@ -27,15 +29,17 @@ BEGIN { function scan() { ptok = tok sub(/^[ \t]+/, "", line) - if (match(line, /^[0-9]([.0-9]*(e[+-]*)*[0-9])*/)) { + if (match(line, /^[0-9]([.0-9]*(e[+-]*)*[0-9])*/)) { # Literal number tok = "d" substr(line, 1, RLENGTH) - } else if (match(line, /^([][}{)(,+-=?:]|[*\/÷\^])/)) { + } else if (match(line, /^([-=+|&]{2}|![=~]|[<>+-*\/^%]=)/)) { # Operator (2 chars) tok = substr(line, 1, RLENGTH) - } else if (match(line, /^[A-Za-z_][A-Za-z_0-9]*/)) { + } else if (match(line, /^([][}{)(,+-=?:]|[*\/÷\^])/)) { # Operator (1 char) + tok = substr(line, 1, RLENGTH) + } else if (match(line, /^[A-Za-z_][A-Za-z_0-9]*/)) { # Identifier tok = "v" substr(line, 1, RLENGTH) - } else if (match(line, /^"(\\.|[^\\"])*"/)) { + } else if (match(line, /^"(\\.|[^\\"])*"/)) { # Literal string tok = "s" substr(line, 2, RLENGTH-2) - } else { + } else { # Bad token tok = "b" substr(line, 1, 1) } line = substr(line, RLENGTH+1) @@ -43,8 +47,8 @@ function scan() { } # TODO: unary operators -function parse( stack, sl, i) { - i = length(code) +function parse( stack, sl, i, b) { + b = i = length(code) while (scan() > 0) { if (tok == "(") { stack[++sl] = tok @@ -52,7 +56,8 @@ function parse( stack, sl, i) { while (sl && stack[sl] != "(") code[i++] = stack[sl--] sl-- } else if (tok in prec) { - if (tok == "=" && ptok ~ /^v/) sub(/^v/, "p", code[i-1]) # mutate var to pointer for assign + # print "tok:" tok " ptok:" ptok + if (tok ~ /[+-*\/%^]?=/ && ptok ~ /^v/) sub(/^v/, "p", code[i-1]) # hack: mutate var to pointer for assign # 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--] @@ -63,13 +68,12 @@ function parse( stack, sl, i) { } } while (sl) code[i++] = stack[sl--] - # for (j = 0; j < i; j++) printf("%s ", code[j]); print "" + for (j = b; j < i; j++) printf("%s ", code[j]); print "" } # TODO: if, while, function function run( c, i, l, t) { cl = length(code) - ml = length(mem) while (pc < cl) { c = code[pc] if (c == "+") { @@ -83,20 +87,24 @@ function run( c, i, l, t) { } else if (c == "^") { mem[--ml] = mem[ml-1] ^ mem[ml] } else if (c == "=") { - var[substr(mem[ml-1], 2)] = mem[ml] - mem[--ml] = mem[ml] + mem[--ml] = var[substr(mem[ml-1], 2)] = mem[ml] + } else if (c == "+=") { + mem[--ml] = var[substr(mem[ml-1], 2)] += mem[ml] } else if (c ~ /^p/) { mem[++ml] = c } else if (c ~ /^v/) { mem[++ml] = var[substr(c, 2)] } else if (c ~ /^[d]/) { mem[++ml] = 0 + substr(c, 2) + } else { + print "run: invalid instruction " c + return } - printf "c" pc ": " c; for (i = 1; i <= ml; i++) printf ", " i ":" mem[i]; print "" - for (i in var) print "var[" i "]=" var[i] + # printf "c" pc ":%s", c; for (i = 1; i <= ml; i++) printf " " i ":" mem[i]; print "" + # for (i in var) print "var[" i "]=" var[i] pc++ } - print mem[ml] - var["_"] = mem[ml--] + print var["_"] = mem[ml--] + print "ml: " ml ", len(mem): " length(mem) # for (i = ml; j in mem; i++) delete mem[i] } |
