Reputation:
I am creating a language with regex this is my code so far:
import re
outputf=r'output (.*)'
inputf=r'(.*) = input (.*)'
intf=r'int (.*) = (\d)'
floatf=r'float (.*) = (\d\.\d)'
def check_line(line):
outputq=re.match(outputf, line)
if outputq:
exec ("print (%s)" % outputq.group(1))
inputq=re.match(inputf, line)
if inputq:
exec ("%s=raw_input(%s)"%(inputq.group(1), inputq.group(2)))
intq=re.match(intf, line)
if intq:
exec ("%s = %s"%(intq.group(1), intq.group(2)))
print x
floatq=re.match(floatf, line)
if floatq:
exec ("%s = %s"%(floatq.group(1), floatq.group(2)))
code=open("code.psu", "r").readlines()
for line in code:
check_line(line)
So it works great but in my file, here is my code:
int x = 1
output "hi"
float y = 1.3
output x
But when i read line 4, it says the variable x is not defined. How can I set it up so it can also print variables?
Upvotes: 2
Views: 56
Reputation: 2242
When exec() is called it optionally can be passed the global and local dictionaries of variables that it will use. By default, it uses globals()
and locals()
.
The problem is, you are using exec()
to set a variable like x = 1
in your example. That does get set, and you can will see it in locals()
. But after you leave the function, that variable is gone.
So, you'll need to save the locals()
after each exec()
call.
EDIT:
I was writing this addendum as you answered it yourself, so I figured I post it anyway...
Here's a simple example that fails (same error as your example):
def locals_not_saved(firsttime):
if firsttime:
exec("x = 1")
else:
exec("print(x)")
locals_not_saved(True)
locals_not_saved(False)
And here's a modified version that saves and reuses the locals()
by saving them as an attribute to the the function - that's just one way to do it, YMMV.
def locals_saved(firsttime):
if not hasattr(locals_saved, "locals"):
locals_saved.locals = locals()
if firsttime:
exec("x = 1", globals(), locals_saved.locals)
else:
exec("print(x)", globals(), locals_saved.locals)
locals_saved(True)
locals_saved(False)
Upvotes: 2