v = {}

waiting = False

def replace_low_and_cap(text, splitBy, joinBy):
    text = text.split(splitBy.lower())
    text = joinBy.join(text)
    text = text.split(splitBy.title())
    text = joinBy.join(text)
    return text

def replace_all(text, replaceWith, *splitList):
    text = replace_low_and_cap(text, replaceWith, replaceWith)
    for splitBy in splitList:
        text = replace_low_and_cap(text, splitBy, replaceWith)
    return text

def replace_all_dash(text, replaceWith, *splitList):
    text = replace_all(text, replaceWith, replaceWith)
    for splitBy in splitList:
        text = replace_all(text, replaceWith, "-"+splitBy)
    return text

def replace_first(text, replaceWith, spl):
    text = text.split(spl)
    if len(text) >= 2:
        text[0] += replaceWith+text.pop(1)
    text = spl.join(text)
    return text

def echo(l=""):
    print(l, end="")
    return l
    
def println(l=""):
    print(l)
    return l

def compileCode(inp):
    storeIn = None
    shouldEcho = None
    shouldPrint = None
    inp = replace_first(inp, '-r"', '"')
    inp = replace_all_dash(inp, "-r", "raw")
    inp = replace_all_dash(inp, "-a", "alias", "v", "var")
    inp = replace_all_dash(inp, "-e", "echo")
    inp = replace_all_dash(inp, "-p", "print", "println")
    inp = replace_all_dash(inp, "True", "yes", "positive")
    inp = replace_all_dash(inp, "False", "no", "negative")
    inp = replace_all_dash(inp, "None", "nothing", "empty", "undefined", "null")
    spl = inp.split("-e")
    if len(spl) >= 2:
        i = len(spl)-1
        del spl[i]
        shouldEcho = True
    spl = "-e".join(spl)
    spl = spl.split("-p")
    if len(spl) >= 2:
        i = len(spl)-1
        del spl[i]
        shouldPrint = True
    spl = "-p".join(spl)
    spl = spl.split("-ifvar")
    if len(spl) >= 2:
        i = len(spl)-1
        words = spl[i].split()
        varTxt = 'var['+words.pop(i)+']'
        cond = varTxt+'words'
        t = test(cond)
        if t != True:
            return
    spl = "-ifvar".join(spl)
    spl = spl.split("-if")
    if len(spl) >= 2:
        i = len(spl)-1
        cond = eval(spl.pop(i))
        t = test(cond)
        if t != True:
            return
    spl = "if".join(spl)
    spl = spl.split("-store in ")
    if len(spl) >= 2:
        i = len(spl) - 1
        storeIn = eval(spl.pop(i))
    spl = "-store in ".join(spl)
    spl = spl.split("-r")
    if len(spl) >= 2:
        cmd = ".".join(spl.pop(0).split())
        args = "-r".join(spl).split("-a")
        for i in range(len(args)):
            if i > 0:
                a = "v["+args[i]+"]"
                args[i] = a
        args = "".join(args)
        if shouldEcho:
            code = "{0}({1}, shouldEcho=True)".format(cmd, args)
        elif shouldPrint:
            code = "{}({}, shouldPrint=True)".format(cmd, args)
        else:
            code = "{0}({1})".format(cmd, args)
    else:
        spl = "".join(spl)
        spl = spl.split("-a")
        if len(spl) >= 2:
            cmd = ".".join(spl[0].split())
            for i in range(len(spl)):
                if i > 0:
                    a = "v["+spl[i]+"]"
                    spl[i] = a
            spl.pop(0)
            spl = "".join(spl)
            if shouldEcho:
                code = "{}({}, shouldEcho=True)".format(cmd, spl)
            elif shouldPrint:
                code = "{}({}, shouldPrint=True)".format(cmd, spl)
            else:
                code = "{}({})".format(cmd, spl)
        else:
            spl = "".join(spl)
            spl = spl.split("-f")
            if len(spl) >= 2:
        	    cmd = spl.pop(0)
        	    arg = spl.pop(0)
        	    cmd = "".join(cmd)
        	    cmd = ".".join(cmd.split())
        	    if shouldEcho:
        	        code = "{}({}(), shouldEcho=True)".format(cmd, arg)
        	    elif shouldPrint:
        	        code = "{}({}(), shouldPrint=True)".format(cmd, arg)
        	    else:
        	        code = "{}({}())".format(cmd, arg)
            else:
                spl = "".join(spl)
                spl = ".".join(spl.split())
                
                if shouldEcho:
                    code = "{}(shouldEcho=True)".format(spl)
                elif shouldPrint:
                    code = "{}(shouldPrint=True)".format(spl)
                else:
                    code = "{}()".format(spl)
    if type(storeIn) == str: 
        code = """temp = {}
v["{}"] = temp""".format(code, storeIn)
    return code
def runCode(inp):
    code = compileCode(inp)
    eval(code)
waiting = False

def q(shouldPrint=False, shouldEcho=False):
    if shouldEcho:
        return echo("Quitting ...")
    if shouldPrint:
        return println("Quitting ...")
    exit()
    raise Exception("Error exiting app")

def printAliases():
    for var in v:
        val = v[var]
        if type(val) == str:
            val = "\""+val+"\""
        print(var+": "+str(val))

def getAliases():
    return v

def amountOfAliases():
    return len(v)

def alias(var, i=None, shouldPrint=False, shouleEcho=False):
    if i != None:
        v[var] = i
    if shouldEcho:
        echo(var+":",v[var])
    if shouldPrint:
        println(var+":",v[var])
    return v[var]
    
class error:
    def __init__(self, e="", fatal=False, shouldPrint=False, shouldEcho=False):
        if fatal == False:
            self.txt = "Error"
        else:
            self.txt = "Fatal error"
        if e != "":
            self.txt += ": "+e
        if shouldPrint:
            println(str(self))
        if shouldEcho:
            echo(str(self))
            
    @staticmethod
    def fatal(e="", shouldPrint=False, shouldEcho=False):
        err = error(e, True, shouldPrint=shouldPrint, shouldEcho=shouldEcho)
        q(shouldPrint, shouldEcho)
        return err
    
    @staticmethod
    def makeFatal(self, shouldPrint=False, sholdEcho=False):
        e = "".join(self.txt.split("Error: "))
        return type(self).fatal(e, shouldPrint, shouldEcho)
        
    def __str__(self):
        return self.txt

def python(c):
    eval(c)

class ui:
    @staticmethod
    def userinput(prompt):
        pauseLoop()
        inp = input(prompt)
        print()
        return(inp)
    
def test(cond, shouldEcho=False, shouldPrint=False):
    if type(cond) == bool:
        if shouldEcho:
            echo(cond)
        if shouldPrint:
            println(cond)
        return cond
    else:
        error.fatal("Condition is invalid.")

def testcond(cond):
    pauseLoop()
    quit = False
    cond = str(cond)
    while not quit:
        test = input("if the condition is:\n$ ")
        println(test)
        if test == "exit":
            quit = True
        ifTrue = input("Do:\n$ ")
        println(ifTrue)
        if test == "other":
            quit = True
            condtest = "True"
        else:
        	condtest = cond+test
        if eval(condtest):
            quit = True
            runCode(ifTrue)
    playLoop()

def mainLoop():
    print("Mainloop")
    while waiting == False:
        inp = input("\n$ ")
        println(inp)
        runCode(inp)
        for var in v:
            print(var)
        print("")

def pauseLoop():
    waiting = True

def playLoop():
    waiting = False
    mainLoop()

playLoop()