5
\$\begingroup\$

I decided to write my own programming language, of sorts. Essentially, you write code into a text file and the program will run the code inside the text file. The file is provided through a script argument.

# Basic programming language
from operator import eq, ne, lt, gt, le, ge
from random import random
from sys import exit, argv
# Specify file to be run
code = argv([1])
"""
>> - Specify to the user that something will be outputted.
<< - Specify to the user that something will be inputted.
"""
# Dict storing operators
OPERATORS = {
 "==": eq,
 "!=": ne,
 "<=": le,
 ">=": ge,
 "<": lt,
 ">": gt
}
# Dict storing program data
data = {
 "vars": [0] * 100000,
 "rand": random()
}
# Interpret the code
def interpreter(separator):
 for line in open(code, "r").readlines():
 # Split each line
 s_command = line.split(separator)
 # Basic input and output
 if s_command[0] == "$out" and s_command[1] == ">>":
 if s_command[2] in data:
 print data[s_command[2]]
 if s_command[2] not in data:
 print s_command[2]
 if s_command[0] == "$inp" and s_command[1] == "<<":
 inp = raw_input(s_command[2])
 # Assign integer variables
 if s_command[0] == "$assignint" and s_command[1] == "<<":
 data["vars"][int(s_command[2])] = int(s_command[3])
 # Assign string variables
 if s_command[0] == "$assignstr" and s_command[1] == "<<":
 data["vars"][int(s_command[2])] = s_command[3]
 # Return variable values
 if s_command[0] == "$return" and s_command[1] == ">>":
 print data["vars"][int(s_command[2])]
 # Test integer values
 if s_command[0] == "$testint" and s_command[1] == ">>":
 if s_command[3] in OPERATORS:
 print OPERATORS[s_command[3]](
 int(s_command[2]),
 int(s_command[4]))
 # Test string values
 if s_command[0] == "$teststr" and s_command[1] == ">>":
 if s_command[3] in OPERATORS:
 print OPERATORS[s_command[3]](
 s_command[2],
 s_command[4])
 # Test variable values
 if s_command[0] == "$testvar" and s_command[1] == ">>":
 if s_command[3] in OPERATORS:
 print OPERATORS[s_command[3]](
 data["vars"][int(s_command[2])],
 data["vars"][int(s_command[4])])
 # Terminate the program
 if s_command[0] == "$exit" and s_command[1] == ">>":
 exit(int(s_command[2]))
# Run the interpreter
if __name__ == "__main__":
 while True:
 interpreter(":")

Here's an example of a code file:

$out:>>:Hello world.
$inp:<<:[input]>
$assignint:<<:0:10
$assignint:<<:1:11
$return:>>:0
$return:>>:1
$testvar:>>:0:==:1
$testvar:>>:0:!=:1
$exit:>>:0

All I'm really looking for is a way to turn that ugly if/else chain into something prettier without changing the original syntax.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 11, 2014 at 22:59
\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

It looks like all your tests follow the pattern

if s_command[0] == "$xxxxx" and s_command[1] == "yyyyy":

So what you can do is create a tuple of the first two elements of s_command:

instr = tuple(s_command[:2])

Then, you can do

if instr == ("$xxxxx", "yyyyy"):

Next, you can use a dictionary to collect all your instructions in one place:

Instructions = {
 ("$out", ">>"): do_out,
 ("$inp", "<<"): do_inp,
 ("$assignint", "<<"): do_assignint,
 ...
}

Then you would define a number of functions, one for each instruction, such as

def do_inp(s_command):
 inp = raw_input(s_command[2])

and call your methods with

Instructions[instr](s_command)
answered Aug 11, 2014 at 23:28
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.