I am currently in the process of creating a programming language and I need help to lex a function call. So what I mean by lex is basically to see if what the user enters is a variable assignment, function call, or something like that. You can see in my code in the lexer function I have lexed a var use, var assign, and num. I tried to do function call but whenever I do it it prints variable not assigned and also I need help with the if statement because I want the user to be able to add a expression to it also.
Code:
import os
# Open the file that we will write all of the lines of code to
out = open("out.py","w")
# Open the file with all of the built in functions
functions = open("functions.py","r").read()
# Add built in functions to out so that the user can use them
out.write(functions)
out.write("\n")
out.flush()
os.fsync(out.fileno())
operators = ['+', '-', '*', '/']
var_assign = '='
variables = {}
# Lexer
def lex(line):
idx = 0
line = line.replace(" ", "")
num = ""
tok = ""
isNum = False
tokens = []
for char in line:
if char.isdigit():
isNum = True
num+=char
elif char in operators:
if isNum:
tokens.append(f"NUM:{num}")
num=""
isNum = False
tokens.append(f"OP:{char}")
elif char == "=":
try:
if line[:idx].isdigit():
return None
else:
tokens.append(f"VAR_ASSIGN:{line[:idx]}={line[idx+1:]}")
except:
return ""
elif char.isalpha() and "=" not in line:
try:
#################################
if "(" in line and ")" in line and '-' not in line and '+' not in line and '*' not in line and '/' not in line:
tokens.append(f"FUNC_CALL{line}")
#################################
if '-' in line or '+' in line or '*' in line or '/' in line:
tokens.append(f"VAR_USE:{char}")
else:
tokens.append(f"VAR_CALL:{line}")
except:
return ""
idx+=1
if isNum:
tokens.append(f"NUM:{num}")
return tokens
# Parser
def parse(tokens):
equation = ""
if not tokens:
return "Syntax error"
for tok in tokens:
if "NUM" in tok:
equation+=tok[4:]
elif "OP" in tok:
equation+=tok[3:]
elif "VAR_ASSIGN" in tok:
tok = tok[11:]
variables[tok[:tok.index('=')]] = tok[tok.index('=')+1:]
out.write(str(tok[:tok.index('=')]) + str('=') + str(tok[tok.index('=')+1:]))
out.write("\n")
out.flush()
os.fsync(out.fileno())
return variables[tok[:tok.index('=')]]
elif "VAR_CALL" in tok:
try:
return variables[tok[9:]]
except:
return "Variable not defined"
elif "VAR_USE" in tok:
try:
equation += variables[tok[8:]]
except:
return "Variable not defined"
elif "FUNC_CALL" in tok:
print("FUNCTION CALL")
try:
out.write(equation)
out.write("\n")
out.flush()
os.fsync(out.fileno())
return eval(equation)
except:
return f"Invalid equation {equation}"
while True:
data = input("KPP>")
print(parse(lex(data)))