Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,78 @@
|
|||
my @CODE = q:to/END/.lines;
|
||||
Datasize: 3 Strings: 2
|
||||
"count is: "
|
||||
"\n"
|
||||
0 push 1
|
||||
5 store [0]
|
||||
10 fetch [0]
|
||||
15 push 10
|
||||
20 lt
|
||||
21 jz (68) 65 # jump value adjusted
|
||||
26 push 0
|
||||
31 prts
|
||||
32 fetch [0]
|
||||
37 prti
|
||||
38 push 1
|
||||
43 prts
|
||||
44 fetch [0]
|
||||
49 push 1
|
||||
54 add
|
||||
55 store [0]
|
||||
60 jmp (-87) 10 # jump value adjusted
|
||||
65 halt
|
||||
END
|
||||
|
||||
my (@stack, @strings, @data, $memory);
|
||||
my $pc = 0;
|
||||
|
||||
(@CODE.shift) ~~ /'Datasize:' \s+ (\d+) \s+ 'Strings:' \s+ (\d+)/ or die "bad header";
|
||||
my $w = $0; # 'wordsize' of op-codes and 'width' of data values
|
||||
@strings.push: (my $s = @CODE.shift) eq '"\n"' ?? "\n" !! $s.subst(/'"'/, '', :g) for 1..$1;
|
||||
|
||||
sub value { substr($memory, ($pc += $w) - $w, $w).trim }
|
||||
|
||||
my %ops = (
|
||||
'no-op' => sub { },
|
||||
'add' => sub { @stack[*-2] += @stack.pop },
|
||||
'sub' => sub { @stack[*-2] -= @stack.pop },
|
||||
'mul' => sub { @stack[*-2] *= @stack.pop },
|
||||
'div' => sub { @stack[*-2] /= @stack.pop },
|
||||
'mod' => sub { @stack[*-2] %= @stack.pop },
|
||||
'neg' => sub { @stack[*-1] = - @stack[*-1] },
|
||||
'and' => sub { @stack[*-2] &&= @stack[*-1]; @stack.pop },
|
||||
'or' => sub { @stack[*-2] ||= @stack[*-1]; @stack.pop },
|
||||
'not' => sub { @stack[*-1] = @stack[*-1] ?? 0 !! 1 },
|
||||
'lt' => sub { @stack[*-1] = @stack[*-2] < @stack.pop ?? 1 !! 0 },
|
||||
'gt' => sub { @stack[*-1] = @stack[*-2] > @stack.pop ?? 1 !! 0 },
|
||||
'le' => sub { @stack[*-1] = @stack[*-2] <= @stack.pop ?? 1 !! 0 },
|
||||
'ge' => sub { @stack[*-1] = @stack[*-2] >= @stack.pop ?? 1 !! 0 },
|
||||
'ne' => sub { @stack[*-1] = @stack[*-2] != @stack.pop ?? 1 !! 0 },
|
||||
'eq' => sub { @stack[*-1] = @stack[*-2] == @stack.pop ?? 1 !! 0 },
|
||||
'store' => sub { @data[&value] = @stack.pop },
|
||||
'fetch' => sub { @stack.push: @data[&value] // 0 },
|
||||
'push' => sub { @stack.push: value() },
|
||||
'jmp' => sub { $pc += value() - $w },
|
||||
'jz' => sub { $pc += @stack.pop ?? $w !! value() - $w },
|
||||
'prts' => sub { print @strings[@stack.pop] },
|
||||
'prti' => sub { print @stack.pop },
|
||||
'prtc' => sub { print chr @stack.pop },
|
||||
'halt' => sub { exit }
|
||||
);
|
||||
|
||||
my %op2n = %ops.keys.sort Z=> 0..*;
|
||||
my %n2op = %op2n.invert;
|
||||
%n2op{''} = 'no-op';
|
||||
|
||||
for @CODE -> $_ {
|
||||
next unless /\w/;
|
||||
/^ \s* \d+ \s+ (\w+)/ or die "bad line $_";
|
||||
$memory ~= %op2n{$0}.fmt("%{$w}d");
|
||||
/'(' ('-'?\d+) ')' | (\d+) ']'? $/;
|
||||
$memory ~= $0 ?? $0.fmt("%{$w}d") !! ' ' x $w;
|
||||
}
|
||||
|
||||
loop {
|
||||
my $opcode = substr($memory, $pc, $w).trim;
|
||||
$pc += $w;
|
||||
%ops{%n2op{ $opcode }}();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue