summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-07-30 14:38:30 +0200
committerMarc Vertes <mvertes@free.fr>2025-07-30 14:38:30 +0200
commit443ec4b0e051e9c1966afb5367a69ec89ba2b8c7 (patch)
treeea5dee6905ce9982820ba13553ab53ba8f06f224
parent39b5ec2e0c34ecf86563cac4d920eacaca74fc79 (diff)
fixup
-rwxr-xr-xev54
1 files changed, 31 insertions, 23 deletions
diff --git a/ev b/ev
index 9b35b50..c418ed5 100755
--- a/ev
+++ b/ev
@@ -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]
}