Print, Increment, Decrement, Alias - Interpret Prindeal
Pyth, 162 136 bytes
JfTmchcd\#).zKHW<ZlJI!e=T@J~+Z1=@Tk)=k0 .x=J+]h=Nm.xL@Tskd@K=NhT+]+tN0>J~Z0,=Y.x@H=eT0?qN\pps[Td\=dYb)?xGN?qN\iXHThY?YXTH_1=k1XKT:JZ=+Z3
Demonstration.
Golfed out 26 characters by inlining variables and changing from I
and E
based control flow to ?
and .x
based control flow.
For the first time ever, I ran out of variables in Pyth. Every single variable in Pyth (bdkGHNTY
and JK
) was in use, and I wanted to use b
as a newline. Fortunaely, I was able to use N
to mean two completely different things in different parts of the program, and so it still works.
Ungolfed (run with -m):
JfTmchcd\#).z
KH
W<ZlJ
I!e=T@J~+Z1
=@Tk)
=k0
.x
=J+]h=Nm.xL@Tskd@K=NhT+]+tN0>J~Z0
,
=Y.x@H=eT0
?qN\p
ps[Td\=dYb)
?xGN
?qN\i
XHThY
?Y
XTH_1
=k1
XKT:JZ=+Z3
Python 2, 600 584 397 373 bytes
This is my own golfed reference solution. Anyone is welcome to improve it or follow its logic in their own answer as long as attribution is given.
The neat part about it is that no recursion is done, so it will never have problems with Python's recursion limit. For example, Sp's Countup Prindeal program can run indefinitely.
p=filter(len,[l.split('#')[0].split()for l in input().split('\n')]);m={};v={};i=0
while i<len(p):
s=p[i]
if'('in`s`:s=s[f]
n,f=s[0],0
if n in m:a,b,c=([s[int(g)]if g.isdigit()else g for g in t]for t in m[n]);p=[a,(b,c)]+p[i+1:];i=0;continue
s=s[1]
q=v.get(s,0)
if'd'>n:m[s]=p[i+1:i+4];i+=3
elif'i'<n:print s,'=',q
elif'd'<n:v[s]=q+1
elif q:v[s]-=1
else:f=1
i+=1
It's a program that takes in the quoted program string with newlines escaped, e.g.
'p _MyVariable_321\np screaming_hairy_armadillo'
.
I took various golfing cues from Sp's and Pietu's answers. Thanks guys :)
Python 3, 345 336 335 328 bytes
a=0
A={}
V={}
def f(l):
if l[0]in"d p i":c,u=l;U=V[u]=V.get(u,0)+"pi".find(c);S=U<0;V[u]+=S;c<"p"or print(u,"=",U)
else:d=lambda q:[w.isdigit()and l[int(w)]or w for w in A[l[0]][q]];S=f(d(1+f(d(0))))
return S
for z in open("P"):
l=z.split("#")[0].split()
if"a "==z[:2]:a,s,*x=3,l[1]
elif l*a:x+=l,;a-=1;A[s]=x
elif l:f(l)
(-6 bytes thanks to @orlp)
Still golfing. Assumes the program is stored in a file named P
.
Putting the calls to f
inside the lambda d
would save a few bytes, but it would make the last test case hit max recursion depth.
Some Prindeal programs
The useless subtraction program
Here is a useless subtraction program. It's useless because, even though it subtracts properly, it doesn't return success/failure accordingly.
The output should be:
a = 15
b = 6
__________ = 0
a = 9
b = 6
Countup
a helper
p 1
countup 1
i success
a countup
i 1
helper 1
d failure
countup n
Counts upwards and prints n
forever. Could possibly work as a test for interpreter speed (beware the long tracebacks on keyboard interrupt).