cmks
[dotfiles.git] / Scripts / cormackscript
1 #!/bin/sh
2
3 # CORMACKSCRIPT 
4 # written by daniel
5 #
6 # Usage: cormackscript [cmks file] [output file]
7 #
8 # IMPORTANT!
9 # Place the comments (important to get spaces right too):
10 # ; CMKS START
11 # ; CMKS END
12 # into your racket program, the 'assembled' code will be injected here.
13 #
14 # For extra niceness, if you have the racket program installed it will auto execute it your file.
15 #
16 # A CormackScript file contains 3 columns separated by whitespace in the format [opcode|target|source]  
17 # - The inc, print and read instructions read from the first column
18 # - The quit instruction can be standalone
19 # - you can comment with ;
20 # - extraneous whitespace is ignored
21 #
22 # Here's some sample code
23 # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 # ; setting up memory
25 # 6     ; [0]: first instruction
26 # 1     ; [1]: literal 1
27 # 2     ; [2]: literal 2
28 # 7     ; [3]: literal 7
29 # 0     ; [4]: n
30 # 0     ; [5]: acc
31 #
32 # ; actual instructions 
33 # read 4 ; input n
34 # addeq 00 4 ; skip next if n = 0
35 # add 00 2 ; skip next 2 instructions
36 # print 5 ; out acc
37 # quit
38 # add 05 04 ; acc = acc + n
39 # sub 04 01 ; n = n - 1
40 # sub 00 03 ; go back 7 (from next instr)
41 # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
42 #
43 # You can redefine these to whatever you want
44
45 inst0="inc"   # [tt] = [tt] + 1
46 inst1="add"   # [tt] = [tt] + [ss]
47 inst2="sub"   # [tt] = max([tt] - [ss], 0)
48 inst3="mov"   # [tt] = [ss]
49 inst4="addeq" # [tt] = [tt] + 1, if [ss] = 0
50 inst5="fetch" # [tt] = [[ss]]
51 inst6="store" # [[tt]] = [ss]
52 inst7="print" # display [ss]
53 inst8="read"  # read [tt]
54 inst9="quit"  # halt
55
56 # Config ends here =-=-=-=-=-=-=-=-=
57
58 [ "$#" -ne 2 ] && { echo "Usage: cormackscript [cmks file] [output file]" && exit 1; }
59 scriptfile="$1"; targetfile="$2"
60 [ -f "$scriptfile" ] && [ -f "$targetfile" ] || { echo "Either $scriptfile or $targetfile do not exist" && exit 1; }
61
62 tmp="$(mktemp 'tempXXX')"
63 cat "$scriptfile" |\
64     sed -r "s/\s*;.*//g; /^\s*$/ d; s/\s+/ /g; s/^\s+//" |\
65         awk "
66                 /^$inst0\s/ {printf \"0%02d00 ; [%02d] = [%02d] + 1\n\",\$2,\$2,\$2}
67                 /^$inst1\s/ {printf \"1%02d%02d ; [%02d] = [%02d] + [%02d]\n\",\$2,\$3,\$2,\$2,\$3}
68                 /^$inst2\s/ {printf \"2%02d%02d ; [%02d] = max([%02d] - [%02d], 0)\n\",\$2,\$3,\$2,\$2,\$3}
69                 /^$inst3\s/ {printf \"3%02d%02d ; [%02d] = [%02d]\n\",\$2,\$3,\$2,\$3}
70                 /^$inst4\s/ {printf \"4%02d%02d ; [%02d] = [%02d] + 1, if [%02d] = 0\n\",\$2,\$3,\$2,\$2,\$3}
71                 /^$inst5\s/ {printf \"5%02d%02d ; [%02d] = [[%02d]]\n\",\$2,\$3,\$2,\$3}
72                 /^$inst6\s/ {printf \"6%02d%02d ; [[%02d]] = [%02d]\n\",\$2,\$3,\$2,\$3}
73                 /^$inst7\s/ {printf \"700%02d ; display [%02d]\n\",\$2,\$2}
74                 /^$inst8\s/ {printf \"8%02d00 ; read [%02d]\n\",\$2,\$2}
75                 /^$inst9/ {print \"90000 ; halt\"}
76                 !/^$inst0\s|^$inst1\s|^$inst2\s|^$inst3\s|^$inst4\s|^$inst5\s|^$inst6\s|^$inst7\s|^$inst8\s|^$inst9/
77             " >> "$tmp"
78 sed -i "/\; CMKS START/,/\; CMKS END/{/\; CMKS START/!{/\; CMKS END/!d}}; /\; CMKS START/r $tmp" "$targetfile"
79 rm "$tmp"
80
81 # If racket is installed run it directly
82 [ ! -z "$(command -v racket)" ] && racket "$targetfile" && echo ""