Here is the basic pseudo code of the program:
define array of lines
define dictionary of variables
define left variable
define right variable
define counter and set to 1
loop
write '> '
get line
append line to array of lines if line not empty
break loop if line is 'run'
end loop
loop for each line
split line by spaces
if first element is 'print' or 'write' then
if second element is single quote do
get second to last element
join with spaces
write string excluding first and last character
end
else do
find second element from dictionary of variables
get value associated with element
turn value to string
write value string
end
if first element is 'print' do
write '\n'
end
end
else if second element is '=' do
if third element is number do
set left to number
end
else do
get variable name
find value from variable dictionary
set left to value
end
if line is > 3 elements do
if fifth element is number do
set right to number
end
else do
get variable name
find value from variable dictionary
set right to value
end
if fourth element is '+' do
left = left + right
end
if fourth element is '-' do
left = left - right
end
if fourth element is '*' do
left = left * right
end
if fourth element is '/' do
left = left / right
end
end
set dictionary position of first element to value of left
end
else do
write 'Error on line ' + counter
break loop
end
counter = counter + 1
end loop
The syntax of this interpreted language is this:
Each operation is its own line.
The mathematical operations are limited to +, -, *, /
All numbers are integers and operations return integers.
Strings are only allowed in print/write statements.
Strings are enveloped in single quotes.
Variable names must be single letters.
All individual parts of a line must be separated by 1 space.
Write writes to screen without newline.
Print is like write but with a newline.
No direct string concatenation, use write statements for that.
Example program:
a = 5 write 'A is: ' print a b = a + 5 b = b / 7 write 'B is: ' print b
Example output:
A is: 5 B is: 1
To test its simple nature, I wrote the original version of the interpreter in Python 2.7 and was able to make it in 26 lines of code. Here is the source:
import sys
varis = {}
lines = []
write = sys.stdout.write
while 1: #get input
inp = raw_input("> ")
if inp == "run": break
lines.append(inp)
for y in range(len(lines)): #parse program
x = lines[y].split()
if x[0] == "print" or x[0] == "write":
if x[1][0] == "'": write(" ".join(x[1:])[1:-1])
else: write(str(varis[x[1]]))
if x[0] == "print": write("\n")
elif len(x) > 2 and x[1] == "=":
if ord(x[2][0]) > 96 and ord(x[2][0]) < 123: left = varis[x[2]]
else: left = int(x[2])
if len(x) > 3:
if ord(x[4][0]) > 96 and ord(x[4][0]) < 123: right = varis[x[4]]
else: right = int(x[4])
if x[3] == "+": left += right
elif x[3] == "-": left -= right
elif x[3] == "*": left *= right
elif x[3] == "/": left /= right
varis[x[0]] = left
else: print "Error: line "+str(y+1)
I then wrote a modified version of it in Axon (the main programming language I use at work) and I was able to make it in 31 lines of code. Here is the source:
(x) => do
vars: {}
x = x.replace("\n",";").split(";")
t: []
cou: 1
left: ""
right: ""
x.each y=> do
t = y.split(" ")
if(t[0] == "print") do
if(t[1][0..0] == "'") echo(t[1..-1].concat(" ")[1..-2])
else echo(vars.trap(t[1]))
end
else if(t[1] == "=") do
if(t[2][0] > 47 and t[2][0] < 58) left = parseInt(t[2])
else left = vars.trap(t[2])
if(t.size > 3) do
if(t[4][0] > 47 and t[4][0] < 58) right = parseInt(t[4])
else right = vars.trap(t[4])
if(t[3] == "+") left = left + right
else if(t[3] == "-") left = left - right
else if(t[3] == "*") left = left * right
else if(t[3] == "/") left = floor(left / right)
end
vars = vars.set(t[0], left)
end
else echo("Error: line "+cou)
cou = cou + 1
end
end
The differences in each of the implementations is that the Python one is more like a command line in which you type in your lines and then type in "run" when you want to execute the program, and it supports both "write" and "print". The Axon implementation only has "print" and is a function that takes in the whole program as a string parameter, so I made that to also work with semicolons between the statements.
No comments:
Post a Comment