commit 0172edc75b06937b7ac7bdf248064ff83b934aaf Author: Ugric Date: Sun Nov 28 21:02:47 2021 +0000 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..510c73d --- /dev/null +++ b/.gitignore @@ -0,0 +1,114 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/512px-Argon_atom.svg.png b/512px-Argon_atom.svg.png new file mode 100644 index 0000000..fcfb7a4 Binary files /dev/null and b/512px-Argon_atom.svg.png differ diff --git a/Argon.py b/Argon.py new file mode 100644 index 0000000..2157060 --- /dev/null +++ b/Argon.py @@ -0,0 +1,359 @@ +import re +from typing import Tuple +import sys +import time + +# make a function that takes in a param of any type and returns it as a number + + +def number(value): + try: + inted = int(value) + floated = float(value) + if inted == floated: + return inted + return floated + except: + return float(value) + + +def log(*args): + newargs = [] + for i in range(len(args)): + newargs.append(valToArgonString(args[i])) + print(*newargs) + + +def valToArgonString(value): + if type(value) == int or type(value) == float: + return str(value) + elif value == None: + return "unknown" + elif value == True: + return "yes" + elif value == False: + return "no" + return value + + +vars = {'log': {'type': 'init', 'py': log}, 'input': {'type': 'init', 'py': input}, 'PYeval': {'type': 'init', 'py': eval}, 'PYexec': {'type': 'init', 'py': exec}, 'abs': {'type': 'init', 'py': abs}, 'round': {'type': 'init', 'py': round}, 'length': {'type': 'init', 'py': len}, 'number': {'type': 'init', + 'py': number}, 'string': {'type': 'init', 'py': str}, 'bool': {'type': 'init', 'py': bool}, 'yes': {'type': 'init', 'value': True}, 'no': {'type': 'init', 'value': False}, 'unknown': {'type': 'init', 'value': None}, 'snooze': {'type': 'init', 'py': time.sleep}, 'time': {'type': 'init', 'py': time.time}} + +stringTextREGEX = r"( *)((((\')((\\([a-z]|\\|\"))|[^\\])*(\'))|((\")((\\([a-z]|\\|\"))|[^\\])*(\"))))( *)" +numberTextREGEX = r"( *)([0-9]*(\.[0-9]*)?(e[0-9]+)?)( *)" +varTextREGEX = r"( *)([a-z]|[A-Z])([a-zA-Z0-9]*)( *)" +bracketsTextREGEX = r"\(.*\)" +functionTextREGEX = r"( *)(([a-z]|[A-Z])([a-zA-Z0-9]*))\(.*\)( *)" +cobined = fr"{stringTextREGEX}|{numberTextREGEX}|{varTextREGEX}|{functionTextREGEX}|bracketsTextREGEX" +cobinedcompiled = re.compile(cobined) +bracketsTest = re.compile(bracketsTextREGEX) +stringTest = re.compile(stringTextREGEX) +functionTest = re.compile(functionTextREGEX) +numberTest = re.compile(numberTextREGEX) +setVarREGEX = fr"( *)(((const|var) ({varTextREGEX})(( *)=( *).+)?)|(([a-z]|[A-Z])+)(( *)(\+|\-|\*|\/)?=( *).+))( *)" +setVar = re.compile( + setVarREGEX +) +cobinedevalcompiled = re.compile(fr"{cobined}|{setVar}") +varTest = re.compile(varTextREGEX) + +# make a function that takes an input of a string that represents a string and convert all the \ commands to their actual character +# make is decode unicode encoding (eg '\u0041' to A) + + +def convert_backslash(string): + string = string.strip() + if string[0] == "'": + string = string[1:-1] + elif string[0] == '"': + string = string[1:-1] + string = re.sub(r"\\([a-z\"\'])", + lambda x: eval(f"'\\{x.group(1)}'"), string) + string = re.sub(r"\\u([a-fA-F0-9]{4})", + lambda x: chr(int(x.group(1), 16)), string) + return string + + +# make a function takes takes in 2 values, a mathermatical operator and 2 values and returns the result +# the mathermatical operators are +, -, *, /, %, **, //, and access boolian operators and their nots such as ==, !=, >, <, >=, <=, and in, not in +def math_exec(operator, value1, value2): + if operator == "+": + return value1 + value2 + elif operator == "-": + return value1 - value2 + elif operator == "*": + return value1 * value2 + elif operator == "/": + return value1 / value2 + elif operator == "%": + return value1 % value2 + elif operator == "**": + return value1 ** value2 + elif operator == "//": + return value1 // value2 + elif operator == "==": + return value1 == value2 + elif operator == "!=": + return value1 != value2 + elif operator == ">": + return value1 > value2 + elif operator == "<": + return value1 < value2 + elif operator == ">=": + return value1 >= value2 + elif operator == "<=": + return value1 <= value2 + elif operator == "in": + return value1 in value2 + elif operator == "not in": + return value1 not in value2 + elif operator == "or": + return value1 or value2 + elif operator == "and": + return value1 and value2 + else: + raise SyntaxError(f"invalid syntax") + + +def runSub(subname, args): + if len(vars[subname]['f']['prams']) != len(args): + raise SyntaxError( + f"{subname} requires {len(vars[subname]['f']['prams'])} arguments, but {len(args)} were given") + kwargs = vars + for i in range(len(args)): + if vars[subname]['f']['prams'][i] in kwargs and kwargs[vars[subname]['f']['prams'][i]]['type'] == 'init': + raise RuntimeError( + f"{vars[subname]['f']['prams'][i]} is an initialized variable / function") + kwargs[vars[subname]['f']['prams'][i]] = { + 'type': 'var', 'value': args[i]} + run(vars[subname]['f']['code'], kwargs) + + +def code_Aexec(string): + Aexec(string, False) + + +def code_Aeval(string): + return Aexec(string, True)[1] + + +vars['exec'] = {"type": "init", "py": code_Aexec} +vars['eval'] = {"type": "init", "py": code_Aeval} + +# value Argon executer + + +def val_Aexec(string, eval=False, vars=vars) -> Tuple[bool, any]: + didprocess = False + output = None + if not eval and setVar.fullmatch(string): + stringsplit = string.split("=") + if len(stringsplit) > 1: + val = Aexec("=".join(stringsplit[1:]).strip(), True, vars=vars) + if val[0]: + value = val[1] + else: + raise Exception(f"Error in assignment: {val[1]}") + else: + value = None + typeAndVar = re.split(r"( +)", stringsplit[0]) + varname = typeAndVar[2] + type = typeAndVar[0] + if varname == "" and type not in ["const", "var"]: + varname = type + type = "var" + if varname in vars and vars[varname]["type"] == "const": + raise Exception(f"Variable {varname} is already a constant") + vars[varname] = {"type": type, "value": value} + elif not eval and re.fullmatch(fr"rem( +)({varTextREGEX})", string): + varname = re.split(r"( +)", string)[2] + if varname in vars: + if vars[varname]["type"] == "init": + raise Exception(f'Cannot delete initialized variable') + del vars[varname] + else: + raise Exception(f"Variable {varname} does not exist") + elif bracketsTest.fullmatch(string): + output = Aexec(string.strip()[1:-1], True, vars=vars) + didprocess = True + elif stringTest.match(string): + didprocess = True + output = convert_backslash(string) + elif numberTest.fullmatch(string): + didprocess = True + try: + output = int(string) + except: + output = float(string) + elif varTest.fullmatch(string): + didprocess = True + var = string.strip() + if var in vars: + if 'f' in vars[var] or 'py' in vars[var]: + output = f'function({var})' + else: + output = vars[var]["value"] + else: + raise Exception(f"Variable {var} does not exist") + elif functionTest.fullmatch(string): + function = string.strip().split("(") + funcname = function[0] + funcpramsTEXT = "(".join(function[1:])[:-1] + funcprams = [] + process = [] + for i in range(len(funcpramsTEXT)): + process.append(funcpramsTEXT[i]) + if cobinedcompiled.fullmatch("".join(process)[:-1]) and funcpramsTEXT[i] == ",": + funcprams.append( + Aexec("".join(process)[:-1], True, vars=vars)[1]) + process = [] + if len(process) > 0: + funcprams.append(Aexec("".join(process), True, vars=vars)[1]) + + if funcname in vars: + if 'f' in vars[funcname] or 'py' in vars[funcname]: + if 'py' in vars[funcname]: + didprocess = True + output = vars[funcname]["py"](*funcprams) + else: + didprocess = False + output = runSub(funcname, funcprams) + else: + raise Exception(f"Variable {funcname} is not a function") + else: + raise Exception(f"Function {funcname} does not exist") + else: + raise SyntaxError(f"invalid syntax") + return didprocess, output + + +# bodmas stands for brackets, order of operations, division, multiplication, addition, subtraction +def Aexec(string, eval=False, vars=vars) -> Tuple[bool, str]: + string = string.strip() + brackets = 0 + if not (string.startswith("(") and string.endswith(")")): + return val_Aexec(string, eval, vars=vars) + else: + loopoutput = [] + process = [] + for i in range(len(string)): + if string[i] == "(": + brackets += 1 + if brackets > 1: + process.append(string[i]) + elif len(process) > 0: + loopoutput.append("".join(process).strip()) + process = [] + elif string[i] == ")": + brackets -= 1 + if brackets > 0: + process.append(string[i]) + elif brackets == 0: + didprocess, val = Aexec("".join(process), True, vars=vars) + if didprocess: + loopoutput.append(val) + else: + raise Exception(f"Error in brackets: {val}") + process = [] + elif brackets < 0: + raise SyntaxError(f"invalid syntax") + elif brackets == 0: + process.append(string[i]) + else: + process.append(string[i]) + if brackets != 0: + raise SyntaxError(f"invalid syntax") + if len(process) > 0: + loopoutput.append("".join(process).strip()) + process = [] + finaloutput = loopoutput[0] + for i in range(0, int(len(loopoutput) / 2)): + i = i * 2 + 2 + finaloutput = math_exec( + loopoutput[i - 1], finaloutput, loopoutput[i]) + return True, finaloutput + + +runnerREGEX = re.compile( + r"( *)(while( +)\(.*\)|if( +)\(.*\)|(sub)( +)([a-zA-Z]+)\((.*)\)( +))( *)\[( *)") + + +def run(code: list, vars=vars): + Runnertype = "" + Runnercheck = None + inRunner = 0 + Runnercode = [] + prams = [] + subname = "" + inElse = False + Elsecode = [] + for line in code: + if runnerREGEX.fullmatch(line): + inRunner += 1 + if inRunner == 1: + inElse = False + Runnertype = line.strip().split(' ')[0] + if Runnertype == 'sub': + subdata = "".join(line.strip().split(' ')[1:]).split('(') + subname = subdata[0] + prams = '('.join(subdata[1:]).split(')')[0].split(',') + else: + Runnercheck = ''.join(line.strip().split(' ')[1:])[ + :-1].strip()[1:-1] + else: + if inElse: + Elsecode.append(line) + else: + Runnercode.append(line) + elif inRunner > 0: + if re.fullmatch(r'( *)]( *)', line): + inRunner -= 1 + if inRunner == 0: + if Runnertype == "while": + while Aexec(Runnercheck, True, vars=vars)[1]: + run(Runnercode, vars) + elif Runnertype == "if": + if Aexec(Runnercheck, True, vars=vars)[1]: + run(Runnercode, vars) + else: + run(Elsecode, vars) + elif Runnertype == "sub": + vars[subname] = {"type": "const", 'f': { + 'prams': prams, 'code': Runnercode}} + Runnertype = "" + subname = "" + Runnercheck = None + Runnercode = [] + prams = [] + inElse = False + Elsecode = [] + else: + if inElse: + Elsecode.append(line) + else: + Runnercode.append(line) + elif re.fullmatch(r'( *)(\] else \[)( *)', line) and Runnertype == "if" and inRunner == 1 and not inElse: + inElse = True + else: + if inElse: + Elsecode.append(line) + else: + Runnercode.append(line) + elif line != "": + Aexec(line, vars=vars) + + +if __name__ == "__main__": + if len(sys.argv) > 1: + code = open(sys.argv[1], "r").read().split("\n") + run(code) + else: + code = input("> ") + while code != "exit": + try: + output = (Aexec(code)) + if output[0]: + log(output[1]) + except Exception as e: + print(e) + code = input("> ") diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..75fa044 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Ugric + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d03b972 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Argon + Argon ⚛🧪 diff --git a/app.ico b/app.ico new file mode 100644 index 0000000..adf6fb5 Binary files /dev/null and b/app.ico differ diff --git a/app.py b/app.py new file mode 100644 index 0000000..48fb79b --- /dev/null +++ b/app.py @@ -0,0 +1,5 @@ +import time +start = time.time() +for i in range(10000): + print(i) +print(time.time() - start) diff --git a/ar.exe b/ar.exe new file mode 100644 index 0000000..fd085df Binary files /dev/null and b/ar.exe differ diff --git a/test.ar b/test.ar new file mode 100644 index 0000000..7c4f85d --- /dev/null +++ b/test.ar @@ -0,0 +1,7 @@ +const start = time() +i = 0 +while ((i)<(10000)) [ + log(i) + i = (i) + (1) +] +log((time()) - (start)) \ No newline at end of file