#!/bin/sh # CORMACKSCRIPT # written by daniel # # Usage: cormackscript [cmks file] [output file] # # IMPORTANT! # Place the comments (important to get spaces right too): # ; CMKS START # ; CMKS END # into your racket program, the 'assembled' code will be injected here. # # For extra niceness, if you have the racket program installed it will auto execute it your file. # # A CormackScript file contains 3 columns separated by whitespace in the format [opcode|target|source] # - The inc, print and read instructions read from the first column # - The quit instruction can be standalone # - you can comment with ; # - extraneous whitespace is ignored # # Here's some sample code # =-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ; setting up memory # 6 ; [0]: first instruction # 1 ; [1]: literal 1 # 2 ; [2]: literal 2 # 7 ; [3]: literal 7 # 0 ; [4]: n # 0 ; [5]: acc # # ; actual instructions # read 4 ; input n # addeq 00 4 ; skip next if n = 0 # add 00 2 ; skip next 2 instructions # print 5 ; out acc # quit # add 05 04 ; acc = acc + n # sub 04 01 ; n = n - 1 # sub 00 03 ; go back 7 (from next instr) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-= # # You can redefine these to whatever you want inst0="inc" # [tt] = [tt] + 1 inst1="add" # [tt] = [tt] + [ss] inst2="sub" # [tt] = max([tt] - [ss], 0) inst3="mov" # [tt] = [ss] inst4="addeq" # [tt] = [tt] + 1, if [ss] = 0 inst5="fetch" # [tt] = [[ss]] inst6="store" # [[tt]] = [ss] inst7="print" # display [ss] inst8="read" # read [tt] inst9="quit" # halt # Config ends here =-=-=-=-=-=-=-=-= [ "$#" -ne 2 ] && { echo "Usage: cormackscript [cmks file] [output file]" && exit 1; } scriptfile="$1"; targetfile="$2" [ -f "$scriptfile" ] && [ -f "$targetfile" ] || { echo "Either $scriptfile or $targetfile do not exist" && exit 1; } tmp="$(mktemp 'tempXXX')" cat "$scriptfile" |\ sed -r "s/\s*;.*//g; /^\s*$/ d; s/\s+/ /g; s/^\s+//" |\ awk " /^$inst0\s/ {printf \"0%02d00 ; [%02d] = [%02d] + 1\n\",\$2,\$2,\$2} /^$inst1\s/ {printf \"1%02d%02d ; [%02d] = [%02d] + [%02d]\n\",\$2,\$3,\$2,\$2,\$3} /^$inst2\s/ {printf \"2%02d%02d ; [%02d] = max([%02d] - [%02d], 0)\n\",\$2,\$3,\$2,\$2,\$3} /^$inst3\s/ {printf \"3%02d%02d ; [%02d] = [%02d]\n\",\$2,\$3,\$2,\$3} /^$inst4\s/ {printf \"4%02d%02d ; [%02d] = [%02d] + 1, if [%02d] = 0\n\",\$2,\$3,\$2,\$2,\$3} /^$inst5\s/ {printf \"5%02d%02d ; [%02d] = [[%02d]]\n\",\$2,\$3,\$2,\$3} /^$inst6\s/ {printf \"6%02d%02d ; [[%02d]] = [%02d]\n\",\$2,\$3,\$2,\$3} /^$inst7\s/ {printf \"700%02d ; display [%02d]\n\",\$2,\$2} /^$inst8\s/ {printf \"8%02d00 ; read [%02d]\n\",\$2,\$2} /^$inst9/ {print \"90000 ; halt\"} !/^$inst0\s|^$inst1\s|^$inst2\s|^$inst3\s|^$inst4\s|^$inst5\s|^$inst6\s|^$inst7\s|^$inst8\s|^$inst9/ " >> "$tmp" sed -i "/\; CMKS START/,/\; CMKS END/{/\; CMKS START/!{/\; CMKS END/!d}}; /\; CMKS START/r $tmp" "$targetfile" rm "$tmp" # If racket is installed run it directly [ ! -z "$(command -v racket)" ] && racket "$targetfile" && echo ""