Skip to content

Instantly share code, notes, and snippets.

@Nourz1234
Last active February 14, 2024 11:41
Show Gist options
  • Save Nourz1234/361b006efbab7379cf87ef1981649ca8 to your computer and use it in GitHub Desktop.
Save Nourz1234/361b006efbab7379cf87ef1981649ca8 to your computer and use it in GitHub Desktop.
Introducing new features into python! block scopes using curly braces, commas (instead of semicolons), multiline lambdas/anonymous functions, anonymous classes, "This" and "Base" keywords instead of "self" and "super", code minification, more commas, non-indentation sensitive code and more!
from madness import *
main = Function(lambda: {
# anonymous classes!
# notice the use of the magical keyword "This"
Person := Class(Object) (
"Person", # Optional class name
__init__ = lambda name, age: {
This.set(
name = name,
age = age,
),
},
say_hi = lambda: {
print(f"Hi, my name is {This.name}!")
},
__str__ = lambda: {
Return(f"{type(This).__name__} - Name: {This.name} - Age: {This.age}"),
},
),
person := Person(name="Jeff", age=20),
person.say_hi(),
print(person),
})
main()
from madness import *
main = Function(lambda: {
# inheritance:
# notice the use of the magical keyword "Base"
A := Class() (
foo = lambda x: {
print("A"),
Return(x / 2),
},
),
B := Class(A) (
foo = lambda x: {
print("B"),
Return(Base.foo(x) + 1),
},
),
C := Class(B) (
foo = lambda x: {
print("C"),
Return(Base.foo(x) * 2),
},
),
c := C(),
print(c.foo(2)),
})
main()
import ast
import importlib
import importlib.util
import inspect
import sys
from importlib.abc import SourceLoader
from importlib.machinery import FileFinder
def make_everything_nonlocal(
node: ast.Module | ast.FunctionDef | ast.ClassDef,
incl_globals=False,
_globals: list[str] = [],
_nonlocals: list[str] = [],
) -> ast.Module | ast.FunctionDef | ast.ClassDef:
st = ScopeTransformer(node)
node = st.process_scope()
globals = _globals.copy()
nonlocals = _nonlocals.copy()
if isinstance(node, ast.Module):
if incl_globals:
globals = list(set(globals + st.locales))
elif isinstance(node, ast.ClassDef):
pass
else:
nonlocals = list(set(nonlocals + st.locales))
for func_def in st.func_defs:
if globals:
func_def.body.insert(0, ast.Global(names=globals))
if nonlocals:
func_def.body.insert(0, ast.Nonlocal(names=nonlocals))
# print(f"func: {func_def.name} globals: {globals} nonlocals: {nonlocals}")
func_def = make_everything_nonlocal(
func_def, incl_globals, _globals=globals, _nonlocals=nonlocals
)
for class_def in st.class_defs:
class_def = make_everything_nonlocal(
class_def, incl_globals, _globals=globals, _nonlocals=nonlocals
)
return node
class ScopeTransformer(ast.NodeTransformer):
"""
gets a list of functions and classes and variable names
that are direct children of the current scope.
lambdas get converted to function defs.
"""
def __init__(self, scope: ast.Module | ast.FunctionDef | ast.ClassDef) -> None:
super().__init__()
self._lambdas: list[ast.FunctionDef] = []
self.func_defs: list[ast.FunctionDef] = []
self.class_defs: list[ast.ClassDef] = []
self.locales: list[str] = []
self.scope = scope
def process_scope(self):
scope = self.visit(self.scope)
scope.body[0:0] = self._lambdas
return scope
def visit_ClassDef(self, node: ast.ClassDef):
if self.scope == node:
return self.generic_visit(node)
self.class_defs.append(node)
self.locales.append(node.name)
return node
def visit_FunctionDef(self, node: ast.FunctionDef):
if self.scope == node:
return self.generic_visit(node)
self.func_defs.append(node)
self.locales.append(node.name)
return node
def visit_Lambda(self, node: ast.Lambda):
func_def = self.lambda_to_func(node)
self._lambdas.append(func_def)
self.func_defs.append(func_def)
return ast.Name(id=func_def.name, ctx=ast.Load())
def visit_NamedExpr(self, node: ast.NamedExpr):
self.locales.append(node.target.id)
return self.generic_visit(node)
def visit_Assign(self, node: ast.Assign):
nv = NameVisitor()
for target in node.targets:
nv.visit(target)
self.locales.extend(nv.names)
return self.generic_visit(node)
@staticmethod
def lambda_to_func(node: ast.Lambda) -> ast.FunctionDef:
return ast.FunctionDef(
name=ScopeTransformer.generate_unique_name(),
args=node.args,
body=[ast.Return(value=node.body)],
decorator_list=[],
)
_counter = 0
@staticmethod
def generate_unique_name() -> str:
"""
attempting to generate names that wont conflict with any naming style
but knowing devs, someone out there uses numbers prefixed with triple underscores as variable names.
"""
ScopeTransformer._counter += 1
return f"___{ScopeTransformer._counter}"
class NameVisitor(ast.NodeVisitor):
def __init__(self) -> None:
super().__init__()
self.names: list[str] = []
def visit_Name(self, node: ast.Name):
self.names.append(node.id)
class WhileFixer(ast.NodeTransformer):
def visit_Call(self, node: ast.Call):
if isinstance(node.func, ast.Name):
if node.func.id == "While" and len(node.args) == 1:
node.args = [
ast.Lambda(
args=ast.arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[],
),
body=node.args[0],
)
]
return self.generic_visit(node)
class InitCallRemover(ast.NodeTransformer):
def visit_Call(self, node: ast.Call):
if isinstance(node.func, ast.Name):
if node.func.id == init_experimental_stuff.__name__:
return ast.Constant(value=0)
return node
class ExperimentalStuffLoader(SourceLoader):
def __init__(self, fullname, path):
self.fullname = fullname
self.path = path
def get_filename(self, fullname):
return self.path
def get_data(self, filename):
with open(filename) as f:
data = f.read()
return data
@staticmethod
def source_to_code(data: str, path: str = "<string>"):
tree: ast.Module = ast.parse(data)
tree = InitCallRemover().visit(tree)
tree = WhileFixer().visit(tree)
tree = make_everything_nonlocal(tree)
tree = ast.fix_missing_locations(tree)
return compile(tree, path, "exec", dont_inherit=True)
def init_experimental_stuff():
# install the loader
loader_details = ExperimentalStuffLoader, [".py"]
sys.path_hooks.insert(0, FileFinder.path_hook(loader_details))
sys.path_importer_cache.clear()
importlib.invalidate_caches()
# import the calling file
frame_info = inspect.stack()[1]
filename = frame_info.filename
mod_name = frame_info.frame.f_globals["__name__"]
if mod_name != "__main__":
raise Exception("Must call from __main__")
spec = importlib.util.spec_from_loader(
mod_name, ExperimentalStuffLoader(mod_name, filename)
)
module = importlib.util.module_from_spec(spec)
sys.modules[mod_name] = module
spec.loader.exec_module(module)
# using '__builtins__' instead of directly calling 'quit'
# so that the IDE does not complain about unreachable code
__builtins__["quit"]()
from experimental_stuff import init_experimental_stuff
from madness import *
# should be at the very top, even before other imports!
init_experimental_stuff()
# what this line does is:
# 1- Make all variables nonlocal
# 2- Wrap anything passed to "While" in a lambda
# don't ask how it works, it's magic!
main = Function(lambda: {
counter := 0,
While(counter < 3) (lambda: {
print(counter),
counter := counter + 1,
}),
print(counter),
foo(),
})
# works with normal functions and methods as well.
def foo():
var = "foo"
def bar():
var += "bar"
def baz():
var += "baz"
baz()
bar()
print(var)
main()
# Li0uLi0uIC4uIC0gLyAuLiAuLi4gLyAtLS0gLS4gLi0uLiAtLi0tIC8gLS0uIC0tLSAtLS0gLS4uIC0uIC4gLi4uIC4uLiAvIC4tLSAuLi4uIC4uIC0uLS4gLi4uLiAvIC0tLiAuLiAuLi4tIC4gLi4uIC8gLiAtLi4tIC0gLi0uIC4tIC4uLiAuLS4uLS4=
from random import randint
from madness import *
main = Function (lambda: {
number := randint(1, 10),
print("Guess a number between 1 and 10"),
While (True) (lambda: {
# since we can't mutate non-local vars
# we create an object and mutate its properties instead
guess := Object(),
guess.set(value = input("Your guess: ")),
Try (lambda: {
guess.set(value = int(guess.value)),
})
.Except(ValueError) (lambda err: {
print("Not a valid number."),
Continue(),
}),
If (guess.value < 1 or guess.value > 10) (lambda: {
print("Number must be between 1 and 10."),
Continue(),
}),
If (guess.value == number) (lambda: {
print("Correct!"),
Break(),
})
.Else (lambda: {
print(f"Incorrect."),
}),
}),
})
main()
from madness import *
(is_even:=Function(lambda x:{negative:=True if x < 0 else False,vars:=Object(),vars.set(even=True),vars.set(y=0),While(True)(lambda:{If(vars.y == x)(lambda:{Return(vars.even),}),vars.set(y=vars.y+(-1 if negative else 1)),vars.set(even=not vars.even),}),}),main:=Function (lambda:{number:=input("Input a number: "),If(is_even(int(number)))(lambda:{print("Number is even!"),}).Else (lambda:{print("Number is odd!"),}),}),main())
from madness import *
is_even = Function (lambda x: {
negative := True if x < 0 else False,
vars := Object(),
vars.set(even = True),
vars.set(y = 0),
While (True) (lambda: {
If (vars.y == x) (lambda: {
Return(vars.even),
}),
vars.set(y = vars.y + (-1 if negative else 1)),
vars.set(even = not vars.even),
}),
})
main = Function (lambda: {
# don't input large numbers, your pc will burn!
number := input("Input a number: "),
If (is_even(int(number))) (lambda: {
print("Number is even!"),
})
.Else (lambda: {
print("Number is odd!"),
}),
})
main()
from typing import Any, Callable, Generic, Iterable, Optional, Type, TypeVar
T = TypeVar("T")
# just so the IDE doesn't complain about undefined variables
This = None
Base = None
class Object:
def set(self, **kwargs):
self.__dict__.update(**kwargs)
class If:
def __init__(self, condition: bool, /):
self.condition = condition
self.done = False
def __call__(self, func: Callable[[], None], /):
if not self.done and self.condition:
func()
self.done = True
return self
def Elif(self, condition: bool, /):
self.condition = condition
return self
def Else(self, func: Callable[[], None], /):
if not self.done:
func()
class For(Generic[T]):
def __init__(self, iter: Iterable[T], /):
self.iter = iter
def __call__(self, func: Callable[[T], None], /):
for item in self.iter:
try:
func(item)
except Continue:
continue
except Break:
break
class While:
def __init__(self, condition: bool | Callable[[], bool], /):
if isinstance(condition, Callable):
self.condition = condition
else:
self.condition = lambda: condition
def __call__(self, func: Callable[[], None], /):
while self.condition():
try:
func()
except Continue:
continue
except Break:
break
class Try:
def __init__(self, func: Callable[[], None], /):
self.err = None
try:
func()
except Exception as err:
self.err = err
def Except(self, exception: Type[T] = Exception, /, *exceptions):
def _handler(func: Callable[[T], None]):
if self.err and isinstance(self.err, (exception,) + exceptions):
func(self.err)
return self
return _handler
class With:
def __init__(self, ctx_mgr, /, *ctx_mgrs):
self.ctx_mgrs = (ctx_mgr,) + ctx_mgrs
def __call__(self, func):
self._With(*self.ctx_mgrs, ctx_items=[], func=func)
def _With(self, ctx_mgr, /, *ctx_mgrs, ctx_items: list, func):
with ctx_mgr as ctx_item:
ctx_items.append(ctx_item)
if ctx_mgrs:
self._With(*ctx_mgrs, ctx_items=ctx_items, func=func)
else:
func(*ctx_items)
class Function:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
try:
self.func(*args, **kwargs)
return None
except Return as err:
return err.value
class ClassType(type):
def __setattr__(cls, name, value):
if isinstance(value, Callable):
value = cls._wrap_method(value)
return super().__setattr__(name, value)
def _wrap_method(cls, method):
def wrapped(self, *args, **kwargs):
method.__globals__["This"] = self
method.__globals__["Base"] = super(cls, self)
try:
method(*args, **kwargs)
return None
except Return as err:
return err.value
return wrapped
class Class:
def __init__(self, *bases):
self.bases = bases
def __call__(self, name="<class>", /, **members):
cls = ClassType(name, self.bases, {})
for key, val in members.items():
setattr(cls, key, val)
return cls
class FlowException(Exception):
def __init__(self):
raise self
class Return(FlowException):
def __init__(self, value: Any = None, /):
self.value = value
super().__init__()
class Continue(FlowException):
pass
class Break(FlowException):
pass
class Raise:
def __init__(self, exception: Optional[Exception] = None, /):
if exception is None:
raise
else:
raise exception
from madness import *
main = Function(lambda: {
With (open("./foo.txt", "w")) (lambda file: {
file.write("bar"),
}),
With (open("./foo.txt", "r")) (lambda file: {
print(f"file content: {file.read()}"),
}),
})
main()
from madness import *
# "unexpected indent"? what is that?
do_stuff = Function (lambda: {
x := 10,
y := 20,
z := 30,
xyz := x + y + z,
Return(xyz),
})
print(do_stuff())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment