# asm - assembler and interpreter for simple computer # usage: awk -f asm program-file data-files... BEGIN { srcfile = ARGV[1] ARGV[1] = "" # remaining files are data tempfile = "/tmp/asm.temp" n = split("const get put ld st add sub jpos jz j halt", x) for (i = 1; i <= n; i++) # create table of op codes op[x[i]] = i-1 # ASSEMBLER PASS 1 FS = "[ \t]+" while (getline 0) { sub(/#.*/, "") # strip comments symtab[$1] = nextmem # remember label location if ($2 != "") { # save op, addr if present print $2 "\t" $3 >tempfile nextmem++ } } close(tempfile) # ASSEMBLER PASS 2 nextmem = 0 while (getline 0) { if ($2 !~ /^[0-9]*$/) # if symbolic addr, $2 = symtab[$2] # replace by numeric value mem[nextmem++] = 1000 * op[$1] + $2 # pack into word } # INTERPRETER for (pc = 0; pc >= 0; ) { addr = mem[pc] % 1000 code = int(mem[pc++] / 1000) if (code == op["get"]) { getline acc } else if (code == op["put"]) { print acc } else if (code == op["st"]) { mem[addr] = acc } else if (code == op["ld"]) { acc = mem[addr] } else if (code == op["add"]) { acc += mem[addr] } else if (code == op["sub"]) { acc -= mem[addr] } else if (code == op["jpos"]) { if (acc > 0) pc = addr } else if (code == op["jz"]) { if (acc == 0) pc = addr } else if (code == op["j"]) { pc = addr } else if (code == op["halt"]) { pc = -1 } else { pc = -1 } } }