mirror of
https://gitlab.com/niansa/pilang.git
synced 2025-03-06 20:48:26 +01:00
Initial commit
This commit is contained in:
commit
f1f1743ddb
13 changed files with 385 additions and 0 deletions
BIN
__pycache__/errors.cpython-37.pyc
Normal file
BIN
__pycache__/errors.cpython-37.pyc
Normal file
Binary file not shown.
BIN
__pycache__/intern.cpython-37.pyc
Normal file
BIN
__pycache__/intern.cpython-37.pyc
Normal file
Binary file not shown.
BIN
__pycache__/rstrings.cpython-37.pyc
Normal file
BIN
__pycache__/rstrings.cpython-37.pyc
Normal file
Binary file not shown.
BIN
__pycache__/rtypes.cpython-37.pyc
Normal file
BIN
__pycache__/rtypes.cpython-37.pyc
Normal file
Binary file not shown.
25
cli.py
Executable file
25
cli.py
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
from intern import main_class
|
||||||
|
|
||||||
|
if len(sys.argv) == 1: # CLI loop
|
||||||
|
main = main_class()
|
||||||
|
while True:
|
||||||
|
print(">>> ", end="", flush=True)
|
||||||
|
commandstr = input()
|
||||||
|
res = main.get_rstring(main.run_command(commandstr), errorsonly=False)
|
||||||
|
if res != None:
|
||||||
|
print(res)
|
||||||
|
else: # File execution loop
|
||||||
|
main = main_class()
|
||||||
|
if sys.argv[1] == "-c":
|
||||||
|
del sys.argv[1]
|
||||||
|
if len(sys.argv[1]) == 1:
|
||||||
|
sys.exit(1)
|
||||||
|
with open(sys.argv[1], mode="r") as f:
|
||||||
|
for line in f:
|
||||||
|
if line[-1] == "\n":
|
||||||
|
line = line[:-1]
|
||||||
|
cmdres = main.get_rstring(main.run_command(line), errorsonly=True)
|
||||||
|
if cmdres:
|
||||||
|
print(cmdres)
|
4
errors.py
Normal file
4
errors.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
class nochsuchcmd: pass
|
||||||
|
class badarguments: pass
|
||||||
|
class nosuchmodule: pass
|
||||||
|
class nosuchvariable: pass
|
127
intern.py
Normal file
127
intern.py
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
import sys, os
|
||||||
|
from types import ModuleType
|
||||||
|
import errors
|
||||||
|
import rtypes
|
||||||
|
from rstrings import rstrings
|
||||||
|
|
||||||
|
|
||||||
|
class environment_class:
|
||||||
|
def __init__(self):
|
||||||
|
self.variables = {}
|
||||||
|
self.catch = False
|
||||||
|
environment = environment_class()
|
||||||
|
|
||||||
|
class main_class:
|
||||||
|
def __init__(self):
|
||||||
|
self.modules = {}
|
||||||
|
self.commands = {}
|
||||||
|
environment.evaluate = self.run_command
|
||||||
|
# Load and import modules
|
||||||
|
for module in os.listdir("modules"):
|
||||||
|
if module[-3:] == ".py" or module[-4:] == ".pyc":
|
||||||
|
self.import_module(f"modules/{module}")
|
||||||
|
|
||||||
|
def is_error(self, robj):
|
||||||
|
try:
|
||||||
|
return robj.__name__ in errors.__dict__.keys()
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_rstring(self, robj, errorsonly=True):
|
||||||
|
iserr = False
|
||||||
|
try:
|
||||||
|
if not "errorsonly" in self.__dict__.keys():
|
||||||
|
self.errorsonly = errorsonly
|
||||||
|
if isinstance(robj,type):
|
||||||
|
if self.is_error(robj):
|
||||||
|
iserr = True
|
||||||
|
if self.errorsonly and not self.is_error(robj):
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return rstrings[robj.__name__]
|
||||||
|
except KeyError:
|
||||||
|
return "py." + robj.__name__
|
||||||
|
else:
|
||||||
|
return robj
|
||||||
|
finally:
|
||||||
|
if environment.catch and iserr:
|
||||||
|
environment.catch = False
|
||||||
|
print("An exception was catched:", self.get_rstring(robj))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def import_module(self, path):
|
||||||
|
with open(path) as file:
|
||||||
|
modcode = file.read()
|
||||||
|
mod = ModuleType(path)
|
||||||
|
exec(modcode, mod.__dict__)
|
||||||
|
return mod.adder(self.add_module)
|
||||||
|
|
||||||
|
def add_module(self, module_class):
|
||||||
|
modulename = module_class.__name__
|
||||||
|
self.modules[modulename] = module_class(environment)
|
||||||
|
for command in self.modules[modulename].commands:
|
||||||
|
self.commands[command] = self.modules[modulename]
|
||||||
|
|
||||||
|
def run_command(self, commandstr):
|
||||||
|
try: commandstr, _ = commandstr.split("#", 1) # Split off comments
|
||||||
|
except ValueError: pass
|
||||||
|
commandstr = commandstr.lstrip()
|
||||||
|
if commandstr == "": # Empty command (does nothing)
|
||||||
|
return
|
||||||
|
elif commandstr.startswith("~"): # Variable
|
||||||
|
try:
|
||||||
|
return environment.variables[commandstr[1:]]
|
||||||
|
except KeyError:
|
||||||
|
return errors.nosuchvariable
|
||||||
|
else: # Actual command
|
||||||
|
try: command, argsstr = commandstr.split(" ", 1)
|
||||||
|
except ValueError: command, argsstr = (commandstr, "")
|
||||||
|
try: commandsplit = command.split(".", 1)
|
||||||
|
except ValueError: commandsplit = [command]
|
||||||
|
# Get module to parse command
|
||||||
|
if len(commandsplit) == 1: # Non-exact command
|
||||||
|
try:
|
||||||
|
module = self.commands[command]
|
||||||
|
except KeyError:
|
||||||
|
return errors.nochsuchcmd
|
||||||
|
else: # Exact command
|
||||||
|
try:
|
||||||
|
module = self.modules[commandsplit[0]]
|
||||||
|
except KeyError:
|
||||||
|
return errors.nosuchmodule
|
||||||
|
command = commandsplit[1]
|
||||||
|
if not command in self.commands.keys():
|
||||||
|
return errors.nochsuchcmd
|
||||||
|
# Split arguments if required
|
||||||
|
argsstr += ","
|
||||||
|
args = []
|
||||||
|
if argsstr != ",":
|
||||||
|
currarg = ""
|
||||||
|
instring = False
|
||||||
|
arginstring = False
|
||||||
|
charig = False
|
||||||
|
skipall = False
|
||||||
|
for char in argsstr:
|
||||||
|
if skipall:
|
||||||
|
continue
|
||||||
|
elif char == '"' and not charig:
|
||||||
|
instring = not instring
|
||||||
|
if currarg == "":
|
||||||
|
arginstring = True
|
||||||
|
elif char == "#" and not charig and not instring:
|
||||||
|
skipall = True
|
||||||
|
elif char == ',' and not charig and not instring:
|
||||||
|
if len(currarg) != 0 and currarg[0] == "$" and not arginstring:
|
||||||
|
currarg = self.get_rstring(self.run_command(currarg[1:]))
|
||||||
|
args.append(currarg)
|
||||||
|
currarg = ""
|
||||||
|
arginstring = False
|
||||||
|
elif char == "\\" and not charig:
|
||||||
|
charig = True
|
||||||
|
else:
|
||||||
|
currarg += char
|
||||||
|
charig = False
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
# Run command
|
||||||
|
return module.processor(command, args)
|
BIN
modules/__pycache__/builtin.cpython-37.pyc
Normal file
BIN
modules/__pycache__/builtin.cpython-37.pyc
Normal file
Binary file not shown.
122
modules/builtin.py
Normal file
122
modules/builtin.py
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
import sys
|
||||||
|
import errors
|
||||||
|
import rtypes
|
||||||
|
|
||||||
|
|
||||||
|
class builtin:
|
||||||
|
def __init__(self, environ):
|
||||||
|
self.commands = {
|
||||||
|
"ret": self.cmd_ret,
|
||||||
|
"catch": self.cmd_catch,
|
||||||
|
"exit": self.cmd_exit,
|
||||||
|
"print": self.cmd_print,
|
||||||
|
"input": self.cmd_input,
|
||||||
|
"set": self.cmd_set,
|
||||||
|
"del": self.cmd_del,
|
||||||
|
"eval": self.cmd_eval,
|
||||||
|
"cmp": self.cmd_cmp,
|
||||||
|
"lower": self.cmd_lower
|
||||||
|
}
|
||||||
|
self.environ = environ
|
||||||
|
|
||||||
|
def processor(self, command, args):
|
||||||
|
try:
|
||||||
|
return self.commands[command](args)
|
||||||
|
except KeyError:
|
||||||
|
return errors.nochsuchcmd
|
||||||
|
|
||||||
|
def cmd_ret(self, args):
|
||||||
|
return " ".join(args)
|
||||||
|
|
||||||
|
def cmd_catch(self, args):
|
||||||
|
if args == []:
|
||||||
|
self.environ.catch = not self.environ.catch
|
||||||
|
else:
|
||||||
|
if args[0].lower() == "true":
|
||||||
|
self.environ.catch = True
|
||||||
|
elif args[0].lower() == "false":
|
||||||
|
self.environ.catch = False
|
||||||
|
else:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def cmd_exit(self, args):
|
||||||
|
try:
|
||||||
|
sys.exit(int(args[0]))
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
except IndexError:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def cmd_print(self, args, nonline=False):
|
||||||
|
for arg in args:
|
||||||
|
print(arg, end="")
|
||||||
|
if not nonline:
|
||||||
|
print()
|
||||||
|
return rtypes.success
|
||||||
|
|
||||||
|
def cmd_input(self, args):
|
||||||
|
self.cmd_print(args, nonline=True)
|
||||||
|
return input()
|
||||||
|
|
||||||
|
def cmd_set(self, args):
|
||||||
|
if len(args) != 2:
|
||||||
|
return errors.badarguments
|
||||||
|
self.environ.variables[args[0]] = args[1]
|
||||||
|
return rtypes.success
|
||||||
|
|
||||||
|
def cmd_del(self, args):
|
||||||
|
# Check if variable exists
|
||||||
|
for arg in args:
|
||||||
|
if not arg in self.environ.variables.keys():
|
||||||
|
return errors.nosuchvariable
|
||||||
|
# Actually do that stuff
|
||||||
|
for arg in args:
|
||||||
|
del self.environ.variables[arg]
|
||||||
|
return rtypes.success
|
||||||
|
|
||||||
|
def cmd_lower(self, args):
|
||||||
|
return str(args[0].lower())
|
||||||
|
|
||||||
|
def cmd_cmp(self, args):
|
||||||
|
# Check
|
||||||
|
try:
|
||||||
|
action, var1, var2, *commands = args
|
||||||
|
if action == "equal":
|
||||||
|
matches = str(var1) == str(var2)
|
||||||
|
elif action == "nonequal":
|
||||||
|
matches = str(var1) != str(var2)
|
||||||
|
elif action == "bigger":
|
||||||
|
matches = float(var1) > float(var2)
|
||||||
|
elif action == "smaller":
|
||||||
|
matches = float(var1) < float(var2)
|
||||||
|
elif action in ["isnum", "isnotnum"]:
|
||||||
|
try:
|
||||||
|
float(var1)
|
||||||
|
float(var2)
|
||||||
|
matches = True
|
||||||
|
except ValueError:
|
||||||
|
matches = False
|
||||||
|
if action == "isnotnum":
|
||||||
|
matches = not matches
|
||||||
|
else:
|
||||||
|
return errors.badarguments
|
||||||
|
if commands == []:
|
||||||
|
return matches
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
# Evaluate list of commands
|
||||||
|
if matches:
|
||||||
|
for command in commands:
|
||||||
|
lastres = self.environ.evaluate(command)
|
||||||
|
return lastres
|
||||||
|
else:
|
||||||
|
return rtypes.fail
|
||||||
|
|
||||||
|
def cmd_eval(self, args):
|
||||||
|
for command in args:
|
||||||
|
lastres = self.environ.evaluate(command)
|
||||||
|
return lastres
|
||||||
|
|
||||||
|
|
||||||
|
def adder(registerer):
|
||||||
|
registerer(builtin)
|
81
modules/math.py
Normal file
81
modules/math.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import errors
|
||||||
|
import rtypes
|
||||||
|
|
||||||
|
|
||||||
|
class math:
|
||||||
|
def __init__(self, environ):
|
||||||
|
self.commands = {
|
||||||
|
"add": self.cmd_add,
|
||||||
|
"sub": self.cmd_sub,
|
||||||
|
"mul": self.cmd_mul,
|
||||||
|
"div": self.cmd_div
|
||||||
|
}
|
||||||
|
|
||||||
|
def processor(self, command, args):
|
||||||
|
try:
|
||||||
|
return self.commands[command](args)
|
||||||
|
except KeyError:
|
||||||
|
return errors.nochsuchcmd
|
||||||
|
|
||||||
|
def cmd_add(self, args):
|
||||||
|
try:
|
||||||
|
if args[0] == "asint":
|
||||||
|
asint = True
|
||||||
|
args = args[1:]
|
||||||
|
else:
|
||||||
|
asint = False
|
||||||
|
result = 0
|
||||||
|
for arg in args:
|
||||||
|
result += float(arg)
|
||||||
|
if asint: result = int(result)
|
||||||
|
return result
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def cmd_sub(self, args):
|
||||||
|
try:
|
||||||
|
if args[0] == "asint":
|
||||||
|
asint = True
|
||||||
|
args = args[1:]
|
||||||
|
else:
|
||||||
|
asint = False
|
||||||
|
result = float(args[0])
|
||||||
|
for arg in args[1:]:
|
||||||
|
result -= float(arg)
|
||||||
|
if asint: result = int(result)
|
||||||
|
return result
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def cmd_mul(self, args):
|
||||||
|
try:
|
||||||
|
if args[0] == "asint":
|
||||||
|
asint = True
|
||||||
|
args = args[1:]
|
||||||
|
else:
|
||||||
|
asint = False
|
||||||
|
result = 1
|
||||||
|
for arg in args:
|
||||||
|
result *= float(arg)
|
||||||
|
if asint: result = int(result)
|
||||||
|
return result
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def cmd_div(self, args):
|
||||||
|
try:
|
||||||
|
if args[0] == "asint":
|
||||||
|
asint = True
|
||||||
|
args = args[1:]
|
||||||
|
else:
|
||||||
|
asint = False
|
||||||
|
result = float(args[0])
|
||||||
|
for arg in args[1:]:
|
||||||
|
result /= float(arg)
|
||||||
|
if asint: result = int(result)
|
||||||
|
return result
|
||||||
|
except ValueError:
|
||||||
|
return errors.badarguments
|
||||||
|
|
||||||
|
def adder(registerer):
|
||||||
|
registerer(math)
|
8
rstrings.py
Normal file
8
rstrings.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
rstrings = {
|
||||||
|
"success": "Success",
|
||||||
|
"fail": "Failed",
|
||||||
|
"nochsuchcmd": "No such command",
|
||||||
|
"nosuchmodule": "No such module",
|
||||||
|
"nosuchvariable": "No such variable",
|
||||||
|
"badarguments": "Bad arguments"
|
||||||
|
}
|
2
rtypes.py
Normal file
2
rtypes.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
class success: pass
|
||||||
|
class fail: pass
|
16
test.pil
Normal file
16
test.pil
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Enable error catching
|
||||||
|
catch True
|
||||||
|
# Initialise stuff
|
||||||
|
set wasword,was
|
||||||
|
# Get input from user
|
||||||
|
set errnonum,Whatever you typed in... It's definitely not a number!!!
|
||||||
|
set name,$input "Name: "
|
||||||
|
cmp equal,$~name,,"print What? That person has no name???",exit 1
|
||||||
|
set current year,$input "Current year: "
|
||||||
|
cmp isnotnum,$~current year,0,print $~errnonum,exit 2
|
||||||
|
set birth year,$input "Year of birth: "
|
||||||
|
cmp isnotnum,$~birth year,0,print $~errnonum,exit 3
|
||||||
|
# Check if birth year is before current year
|
||||||
|
cmp smaller,$~current year,$~birth year,"print Will ,$~name, be born in the future?","set yesno,$input Yes/No?: ","cmp equal,$lower $~yesno,no,exit 4","cmp nonequal,$lower $~yesno,yes,print I give you up... Bye!,exit 4","set wasword,will be"
|
||||||
|
# Print result
|
||||||
|
print $~name, ,$~wasword, born in ,$~current year,",", so I guess he is ,$"sub asint,$~current year,$~birth year", Years old!
|
Loading…
Add table
Reference in a new issue