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