1

I'm creating my own programming language. The interpreter is written in Python.

I'm trying to add an 'if/else' command. The syntax is:

if "hello" == $myString |> goto somewhere
else |> goto somewhere_else

Instead of implementing the operator logic on my own, I decided to just use the Python exec() command. This is what I am doing (simplified):

task = task.split(' |> ', 1)  # Split on first occurence of "|> "
clause = task[0]
operation = task[1]

clauseCheck = False
clause = clause + ": clauseCheck = True" # So we can run it as python code to eval
eval(clause)  # if the clause evals to true, clauseCheck will be True

if clauseCheck:
    parse(operation)

And here's the error I'm getting (using if 7 != 2 |> ...):

Traceback (most recent call last):

...

  File "interpret.py", line 139, in parse
    eval(clause)  # if the clause evals to true, clauseCheck will be True
  File "<string>", line 1
    if 7 != 2: print('True') ^ SyntaxError: invalid syntax

I've tried everything I can think of - I've added a newline to the string given to eval() with and without indentation, I've tried just printing 'true' instead of setting a variable and I've tried with a different if statement.

How can I get my code to properly evaluate the if statements?

Ma0
  • 15,057
  • 4
  • 35
  • 65
  • what is the question and where's the error ? – coder Aug 11 '17 at 10:38
  • @coder submitted too early, adding now –  Aug 11 '17 at 10:39
  • @TheoC I still do not see an error raised.. That being said, `eval` is not only tricky but dangerous too. I would propose `literal_eval` from `ast`. – Ma0 Aug 11 '17 at 10:43
  • @Ev.Kounis I have added the error I'm getting, do you mean you aren't getting an error when you run the code I provided? –  Aug 11 '17 at 10:46
  • 4
    `eval` is for evaluating expressions, not executing statements. Since the `if-statement` is a statement, you'd need to use `exec`. But `exec` in Python3 never modifies locals. Instead, you need to pass a local namespace (dict) to `exec` and then access the result from the local namespace dict. See https://stackoverflow.com/a/1463370/190597. – unutbu Aug 11 '17 at 10:46
  • @unutbu Do you mean I could pass `eval` something like `7 == 7` or `7 != 2` and it'd return `True` for both? That could be just what I need. –  Aug 11 '17 at 10:48
  • @TheoC No, I mean that the traceback you posted seems to be missing something. – Ma0 Aug 11 '17 at 10:49
  • 1
    @TheoC: Sure you could. (Try it out in the interpreter!) But to execute the `clause`, you'd need `ns = dict(); exec(clause, globals(), ns)`. Followed by `if ns['clauseCheck']: ...`. – unutbu Aug 11 '17 at 10:50
  • @Ev.Kounis Full traceback: ```Traceback (most recent call last): File "interpret.py", line 150, in parse(tasks[currentLine]) # parse the task at the current line in tasks File "interpret.py", line 139, in parse eval(clause) # if the clause evals to true, clauseCheck will be True File "", line 1 if 7 != 2: print('True') ^ SyntaxError: invalid syntax ``` –  Aug 11 '17 at 10:51
  • @unutbu **THANK YOU!** That is just what I wanted and actually means I can use a much more elegant solution. –  Aug 11 '17 at 10:52
  • You know that that `task.split("|> ")` will fail if there is a string like `if "foo |> bar" |> ...` in the condition, making programs written in that language vulnerable to all sorts of "code injection", right? – tobias_k Aug 11 '17 at 10:56
  • @tobias_k I'm aware of that and working on a way to fix it. –  Aug 11 '17 at 13:40

0 Answers0