Write an interpreter for simplified 33

5

1

33 is a simple esolang I created. You may have seen me use it in a few questions. You're not going to be writing a full interpreter. The interpreter you will be writing is for a simplified version of 33.

This simplified 33 has two numeric registers: the accumulator and the counter. The accumulator holds all the post-arithmetic values, the counter is where numbers in the program come from. Both registers are initialized to 0.

0-9 | Appends the digit to the counter
a   | Adds the counter to the accumulator
m   | Subtracts the counter from the accumulator
x   | Multiplies the accumulator by the counter
d   | Divides the accumulator by the counter
r   | Divides the accumulator by the counter, but stores the remainder in the accumulator
z   | Sets the counter to 0
c   | Swaps the accumulator and counter
-----
p   | Outputs the current value of the accumulator as an ASCII character
o   | Outputs the current value of the accumulator as a formatted decimal number
i   | Outputs a newline character (0x0a)
-----
P   | Stores the ASCII value of the next character read in the accumulator
O   | Stores the next integer read into the accumulator
-----
n   | Skips the next instruction if the accumulator is not 0
N   | Skips the next instruction if the accumulator is 0
g   | Skips the next instruction if the accumulator is less than or equal to 0
G   | Skips the next instruction if the accumulator is greater than 0
h   | Skips the next instruction if the accumulator is greater than or equal to 0
H   | Skips the next instruction if the accumulator is less than 0

Test cases

Program / Input -> Output
2o          -> 0
25co        -> 25
1a0aoi      -> 11 (trailing newline)
Oo / 42     -> 42
Op / 42     -> *
1cNoo       -> 11
no          -> 0
Ogo / 2     -> 2
Ogoi / -4   -> (newline)
50a         -> (no output)
On12co / 12 -> 2

Clarifications

  • The input to your interpreter will be a valid simplified 33 program.
  • The input may be given in any acceptable format.
  • The output may be given in any acceptable format.
  • When dividing, truncate any decimal places.
  • A trailing newline is acceptable, but it must be consistent; as in, if there's an i at the end of the program, it should have two trailing newlines.
  • The accumulator and counter must be able to hold at least a signed byte (-128 to 127)
  • You may assume that the p instruction will never be given when the accumulator has an invalid ASCII character in it.
  • You may assume the O instruction will never be given unless there is a valid integer string (such as 3, -54, +23) left in the input.

TheOnlyMrCat

Posted 2019-09-10T10:49:58.937

Reputation: 1 079

How does O work? – Erik the Outgolfer – 2019-09-10T10:57:55.020

@tsh Yes. I'll update that. – TheOnlyMrCat – 2019-09-10T10:59:10.720

@EriktheOutgolfer It reads the integer in the same format that o outputs it – TheOnlyMrCat – 2019-09-10T11:01:36.843

@TheOnlyMrCat If the remaining input is x-13, will O skip the x and read the -13? Or can we assume that there will always be an integer right where the O reads the input? – Erik the Outgolfer – 2019-09-10T11:02:43.610

What is acceptable format for an integer input the interpreter must handle? Will +03 be valid input for integer? – tsh – 2019-09-10T11:21:22.257

+ and - are not valid commands in 33, and 33 only handles positive integers. – None – 2019-09-10T11:36:35.610

@A_ The accumulator and counter must be able to hold at least a signed byte (-128 to 127) – tsh – 2019-09-10T11:38:05.033

I believe that is internally, not externally. – None – 2019-09-10T11:38:38.757

N12 should skip the 1 command, since 1 and 2 are separate commands. – None – 2019-09-10T11:39:31.623

Let us continue this discussion in chat.

– tsh – 2019-09-10T11:46:16.567

@TheOnlyMrCat In the official 33 interpreter, trying to read an integer containing letters is invalid. You need to make the challenge self-contained and explain what an interpreter should do with this input. – None – 2019-09-10T11:49:38.293

How does p behave if the accumulator is negative? – ar4093 – 2019-09-10T12:03:23.080

the example 1Noo should output 0 not 11. – tsh – 2019-09-10T12:05:44.953

Answers

1

JavaScript (Node.js), 264 bytes

S=>I=>[...S].map(s=>K?K=0:1/s?C=+(C+s):eval("A*=C;[A,C]=[C,A];K=!A;;K=A;K=A>0;A%=C;K=A<=0;A=A/C|0;I=I.replace(/-?\\d+/,n=>(A=+n,''));K=A>=0;O+=A;K=A<0;A+=C;C=0;;[A]=B(I[0]),I=I.slice(1);O+=`\n`;O+=B([A]);A-=C".split`;`[B(s)[0]*73%378%22]),A=C=K=0,O='',B=Buffer)&&O

Try it online!

Saved ~20 bytes, thanks to Arnauld's magic integer modulus.

tsh

Posted 2019-09-10T10:49:58.937

Reputation: 13 072

253 bytes by converting the input to a buffer right away, re-using S as the result of the previous instruction and using a strict comparison with true. – Arnauld – 2019-09-11T07:22:23.970

0

Lua 5.3, 342 bytes

Code is provided as a cmdline argument, input is provided via stdin.

H=string.char R=io.read A=0 C=0 i=1 s=...while i<=#s do
b=s:byte(i)d=H(b)i=i+(({H=A<0,G=A>0,N=A==0,g=A<=0,h=A>=0,n=A~=0})[d]and 2or
1)io.write(({i='\n',o=A|0,p=H(A%255)})[d]or'')A,C=d=='O'and R'n'or d=='P'and
R(1):byte()or d=='d'and A//C or d=='r'and A%C or({a=A+C,c=C,m=A-C,x=A*C})[d]or
A,b>=48 and b<58 and b-48+C*10or({c=A,z=0})[d]or C end

thenumbernine

Posted 2019-09-10T10:49:58.937

Reputation: 341

0

Julia 1.0, 355 bytes

p=print
function f(s,a=0,c=0,i=1)
for x=s
z=findfirst(==(x),"amxdrzcpoiPOnNgGhH0123456789")
y=z-9
i<1&&(i=1;continue)
z<6 ? a=(+,-,*,÷,%)[z](a,c) :
z<7 ? c=0 :
z<8 ? ((a,c)=(c,a)) :
z<9 ? p(Char(a)) :
y<1 ? p(a) :
y<2 ? p("\n") :
y<3 ? a=0+read(stdin,UInt8) :
y<4 ? a=parse(Int,readline()) :
y<10 ? (!=,==,<=,>,>=,<)[y-3](a,0)&&(i=0) :
c=10c+y-10
end
end

Program provided as an argument, eg f("2o"), input taken from stdin.

Try it online!

gggg

Posted 2019-09-10T10:49:58.937

Reputation: 1 715