Execute Computer/Zero: Difference between revisions
Content added Content deleted
No edit summary |
|||
Line 1,785: | Line 1,785: | ||
1 |
1 |
||
255 |
255 |
||
0 |
|||
</pre> |
|||
=={{header|jq}}== |
|||
'''Adapted from [[#Wren|Wren]]''' |
|||
{{works with|jq}} |
|||
'''Also works with gojq, the Go implementation of jq''' |
|||
This entry assumes all the programs have been placed in a text file |
|||
in which each program takes the form of a header followed |
|||
by the instructions, one per line. |
|||
The header is assumed to have the form: |
|||
<pre> |
|||
; title |
|||
</pre> |
|||
<syntaxhighlight lang="jq"> |
|||
### Utility |
|||
def trim: sub("^ +";"") | sub(" +$";""); |
|||
### Computer/Zero |
|||
def NOP: 0; |
|||
def LDA: 1; |
|||
def STA: 2; |
|||
def ADD: 3; |
|||
def SUB: 4; |
|||
def BRZ: 5; |
|||
def JMP: 6; |
|||
def STP: 7; |
|||
def ops: {"NOP": NOP, "LDA": LDA, "STA": STA, "ADD": ADD, |
|||
"SUB": SUB, "BRZ": BRZ, "JMP": JMP, "STP": STP}; |
|||
# Input: the program in the form of an array of strings, |
|||
# each string corresponding to an input line of the form |
|||
# "INSTR N" or "N" |
|||
# Output: an array of integers |
|||
def load: |
|||
map([splits(" *")] as $split |
|||
| $split[0] as $instr |
|||
| (if ($split|length == 2) then $split[1]|tonumber |
|||
else 0 |
|||
end) as $addr |
|||
| if ops[$instr] |
|||
then ops[$instr] * 32 + $addr |
|||
else try ($instr|tonumber) catch 0 |
|||
end ); |
|||
# input: an array as produced by `load` |
|||
def interp: |
|||
{ acc: 0, pc: 0, mem: .} |
|||
| until(.break; |
|||
(.mem[.pc] % 32) as $addr |
|||
| ((.mem[.pc] - $addr) / 32) as $instr |
|||
| .pc += 1 |
|||
| if $instr == LDA then .acc = .mem[$addr] |
|||
elif $instr == STA then .mem[$addr] = .acc |
|||
elif $instr == ADD then .acc += .mem[$addr] |
|||
| if .acc > 255 then .acc += -256 else . end |
|||
elif $instr == SUB then .acc += (- .mem[$addr]) |
|||
| if .acc < 0 then .acc += 256 else . end |
|||
elif $instr == BRZ |
|||
then if .acc == 0 then .pc = $addr else . end |
|||
elif $instr == JMP then .pc = $addr |
|||
else . |
|||
end |
|||
| .break = $instr == STP or .pc > 31 ) |
|||
| .acc; |
|||
# Assume the input file consists of several programs, each structured as: |
|||
# ; program name |
|||
# one instruction per line |
|||
# |
|||
def task: |
|||
def init: map_values(null); |
|||
foreach (inputs, null) as $line ({}; |
|||
if $line == null then .program = .buffer |
|||
elif $line[0:1] == ";" then init | .title = $line |
|||
else ($line|trim) as $line |
|||
| if $line == "" then .program = .buffer | .buffer = [] |
|||
else .buffer += [$line] |
|||
end |
|||
end) |
|||
| .title as $title |
|||
| .program |
|||
| if length == 0 then empty |
|||
else |
|||
$title, (load|interp) |
|||
end ; |
|||
task |
|||
</syntaxhighlight> |
|||
'''Program file - scrollable window''' (programs.txt) |
|||
<div style="overflow:scroll; height:400px;"> |
|||
<pre> |
|||
; 2+2 |
|||
LDA 3 |
|||
ADD 4 |
|||
STP |
|||
2 |
|||
2 |
|||
; 7 * 8 |
|||
LDA 12 |
|||
ADD 10 |
|||
STA 12 |
|||
LDA 11 |
|||
SUB 13 |
|||
STA 11 |
|||
BRZ 8 |
|||
JMP 0 |
|||
LDA 12 |
|||
STP |
|||
8 |
|||
7 |
|||
0 |
|||
1 |
|||
; finonacci |
|||
LDA 14 |
|||
STA 15 |
|||
ADD 13 |
|||
STA 14 |
|||
LDA 15 |
|||
STA 13 |
|||
LDA 16 |
|||
SUB 17 |
|||
BRZ 11 |
|||
STA 16 |
|||
JMP 0 |
|||
LDA 14 |
|||
STP |
|||
1 |
|||
1 |
|||
0 |
|||
8 |
|||
1 |
|||
; linkedList |
|||
LDA 13 |
|||
ADD 15 |
|||
STA 5 |
|||
ADD 16 |
|||
STA 7 |
|||
NOP |
|||
STA 14 |
|||
NOP |
|||
BRZ 11 |
|||
STA 15 |
|||
JMP 0 |
|||
LDA 14 |
|||
STP |
|||
LDA 0 |
|||
0 |
|||
28 |
|||
1 |
|||
0 |
|||
0 |
|||
0 |
|||
6 |
|||
0 |
|||
2 |
|||
26 |
|||
5 |
|||
20 |
|||
3 |
|||
30 |
|||
1 |
|||
22 |
|||
4 |
|||
24 |
|||
; prisoner |
|||
0 |
|||
0 |
|||
STP |
|||
NOP |
|||
LDA 3 |
|||
SUB 29 |
|||
BRZ 18 |
|||
LDA 3 |
|||
STA 29 |
|||
BRZ 14 |
|||
LDA 1 |
|||
ADD 31 |
|||
STA 1 |
|||
JMP 2 |
|||
LDA 0 |
|||
ADD 31 |
|||
STA 0 |
|||
JMP 2 |
|||
LDA 3 |
|||
STA 29 |
|||
LDA 0 |
|||
ADD 30 |
|||
ADD 3 |
|||
STA 0 |
|||
LDA 1 |
|||
ADD 30 |
|||
ADD 3 |
|||
STA 1 |
|||
JMP 2 |
|||
0 |
|||
1 |
|||
3 |
|||
</pre> |
|||
</div> |
|||
{{output}} |
|||
'''Invocation:''' jq -nR -f execute-computer-zero.jq programs.txt |
|||
<pre> |
|||
"; 2+2" |
|||
4 |
|||
"; 7 * 8" |
|||
56 |
|||
"; finonacci" |
|||
55 |
|||
"; linkedList" |
|||
6 |
|||
"; prisoner" |
|||
0 |
0 |
||
</pre> |
</pre> |