mirror of
https://github.com/Open-Argon/Argon.git
synced 2026-10-28 09:43:38 +00:00
Initial commit
This commit is contained in:
commit
0172edc75b
10 files changed
+510
No files matched your search
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
+114
@@ -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/
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -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("> ")
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
import time
|
||||
start = time.time()
|
||||
for i in range(10000):
|
||||
print(i)
|
||||
print(time.time() - start)
|
||||
Reference in new issue
Block a user