Lex a function call language

Viewed 19

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)))

0 Answers
Related