m654
m654

Reputation: 158

Python: interpreter says "None" after parsing file

I've written a simple interpreter with Python for a programming language I've created. I have a little problem though: when I try to read a file, so the code can be interpreted, Python says None.

Here's the interpreter code:

import sys

class Interpret:
    def read(self, cmd):
        tokens = cmd.split("\n")
        for i in range(0, len(tokens)):
            self.parse(tokens[i])

    def parse(self, cmd):
        if cmd.startswith("print(") and cmd.endswith(")"):
            cmd = cmd[6:]
            cmd = cmd[:-1]
            return(cmd)

interpret = Interpret()

code = open(sys.argv[1], 'r')
print(interpret.read(str(code)))

Here's the code in the file I want to read: print(Hi)\n (Yes, there's a newline there, not the characters \n)

So, here's what happened in CMD:

> python interpreter.py test.tl

None

It should output Hi, but it doesn't work properly. I think it has something to do with the last two lines of the interpreter code, but I'm not completely sure.

Upvotes: 3

Views: 661

Answers (2)

L3viathan
L3viathan

Reputation: 27283

One of your problems is this line:

code = open(sys.argv[1], 'r')

open returns a file object, not the content of the file. Instead, do:

with open(sys.argv[1], 'r') as f:
    code = f.read()

On to the next issue:

for i in range(0, len(tokens)):
    self.parse(tokens[i])

There is no reason to iterate over the range of a len, ever. Just iterate over the tokens:

for token in tokens:
    self.parse(token)

That your code prints None is (as ForceBru has written already) due to the fact that you're printing the return value of a method that returns nothing. Just call interpret.read(str(code)) directly, without wrapping print around it.


After applying all these fixes, to make your code work either do what ForceBru says and yield self.parse(token), or, for testing purposes just print inside of parse:

def parse(self, cmd):
    if cmd.startswith("print(") and cmd.endswith(")"):
        cmd = cmd[6:]
        cmd = cmd[:-1]
        print(cmd)

Then, your code works for me with print(Hi)\n in the test.tl file.

Upvotes: 1

ForceBru
ForceBru

Reputation: 44838

You're just calling self.parse and not using its return value and, given that self.parse doesn't output anything and read returns nothing (None), you're getting None as a result.

You may want your read to yield self.parse(tokens[i]) on each iteration, thus making it a generator, and then do something like this:

for data in interpret.read(str(code)):
    print(data)

Upvotes: 3

Related Questions