Obython
Jump to navigation
Jump to search
Obython is a language made in python, when i thought, what could be the longest way to make a hello world program
Things in it
Print - does stuff Print(print=String(value="this is valid")), Print(print="this is valid"), Print("and so is this"), Print("also the commas are because thats how you structure \ this in...")
Program
Program - contains the program Program(code=[ Print("yeah thats why there was commas\ this is used to contain code, and etc"), Print("it goes through everything in the code and\ calls .value() on it, and also some things that\ use it is...") ])
If
If - checks if condition is true, and if it is, does its program If(condition=Equal(a=Number(value=1), b=Number(value=1)), program=Program(code=[ Print("yes this runs because 1 in fact does equal 1, also if\ you are wondering what Number and String are, they are...") ]))
Literals
Literal - when called .value() on, they return themselves but also for only literals, if .literal() is called on them, it returns its literal, which is used in print and Equal, and more String - a literal, specifically a string Number - a literal, specifically an int or float Boolean - a literal, specifically a bool Dict - a literal, specifically a dictionary List - a literal, specifically a list No - a literal, specifically None also Program returns a No(value=None) when the Program has empty code, as in [], or has its last statement not returning anything, it would return a None instead of a No, which is bad, because None isnt supported as an...
Object
Everything inherits from the Object class, just with different value method, and for literals, different typerfilter method class Object: def __init__(self, *positional, **values): if self.typefilter(values): self.values = values self.positional = positional else: raise TypeError() def value(self): raise NotImplementedError("Subclasses must override value()") def literal(self): raise NotImplementedError("Only Literals implement literal(), but got class '"+str(type(self))+"'") def typefilter(self, values): return True
There is more
i am just too lazy to show them
Examples
99 bottles of beer
code = Program(code=[ Assign(variable=String(value="bottles"), value=Number(value=99)), While(condition=GreaterThan(a=Get(variable=String(value="bottles")), b=Number(value=1)), code=Program(code=[ Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer on the wall"))), Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer"))), Print(String(value="Take one down, pass it around")), Assign(variable=String(value="bottles"), value=Subtract(a=Get(variable=String(value="bottles")), b=Number(value=1))), If(condition=GreaterThan(a=Get(variable=String(value="bottles")), b=Number(value=1)), program=Program(code=[ Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer on the wall"))) ])) ])), Print("1 bottle of beer on the wall"), Print("1 bottle of beer"), Print("Take one down, pass it around"), Print("No more bottles of beer on the wall") ])
Interpeter
import time, random class ReturnSignal(Exception): def __init__(self, value): self.value = value class Helper: def wrap_literal(value): if isinstance(value, bool): return Boolean(value=value) elif isinstance(value, int) or isinstance(value, float): return Number(value=value) elif isinstance(value, str): return String(value=value) elif isinstance(value, list): return List(value=[wrap_literal(v) for v in value]) else: raise TypeError(f"No literal wrapper for: {type(value)}") def wrapifneed(value): if not(isinstance(value, Object)): return Helper.wrap_literal(value) return value class Environment: frames = [{}] # a list of dicts, top is current scope recursionlimit = 100 @classmethod def get(cls, name): for frame in reversed(cls.frames): if name in frame: return frame[name] raise NameError(f"Variable '{name}' not found in any scope") @classmethod def set(cls, name, value, scope="local"): if scope == "local": cls.frames[-1][name] = value elif scope == "global": cls.frames[0][name] = value @classmethod def push(cls): if len(cls.frames) < cls.recursionlimit: cls.frames.append({}) else: raise RecursionError("too many recursive calls") @classmethod def pop(cls): cls.frames.pop() @classmethod def define(cls, varibs): for key in varibs: cls.frames[-1][key] = varibs[key].value() class Object: def __init__(self, *positional, **values): if self.typefilter(values): self.values = values self.positional = positional else: raise TypeError() def value(self): raise NotImplementedError("Subclasses must override value()") def literal(self): raise NotImplementedError("Only Literals implement literal(), but got class '"+str(type(self))+"'") def typefilter(self, values): return True class Time(Object): def value(self): start = time.perf_counter() self.values["do"].value() # Run the code block end = time.perf_counter() duration = end - start return Number(value=duration) class RandomInt(Object): def value(self): lo = self.values.get("min", Number(value=0)).value().literal() hi = self.values.get("max", Number(value=100)).value().literal() return Number(value=random.randint(lo, hi)) class Define(Object): def value(self): name = self.values["name"].value().literal() val = self.values["code"] Environment.set(name, val) return None class Return(Object): def value(self): result = self.values["value"].value() raise ReturnSignal(result) class Get(Object): def value(self): name = self.values["variable"].value().literal() return Environment.get(name) class Assign(Object): def value(self): if "scope" not in self.values: self.values["scope"] = "local" name = self.values["variable"].value().literal() val = self.values["value"].value() Environment.set(name, val, self.values["scope"]) return val # return the new value class Call(Object): def value(self): if "inputs" not in self.values: self.values["inputs"] = Dict(value={}) code = self.values["proced"] Environment.push() Environment.define(self.values["inputs"].value().literal()) try: result = code.value() except ReturnSignal as r: Environment.pop() return r.value Environment.pop() return result class Literal(Object): def value(self): return self def literal(self): return self.value().values["value"] class Program(Object): def value(self): lastval = No(value=None) for code in self.values["code"]: try: lastval = code.value() except ReturnSignal as r: # Bubble return up immediately raise r return lastval def literal(self): return self class Dot(Object): def value(self): obj = self.values["object"].value() method = self.values["method"] method.values["object"] = obj return method.value() class Number(Literal): def typefilter(self, values): return isinstance(values.get("value"), (int, float)) class String(Literal): def typefilter(self, values): return isinstance(values.get("value"), (str)) class List(Literal): def typefilter(self, values): return isinstance(values.get("value"), (list)) class Dict(Literal): def typefilter(self, values): return isinstance(values.get("value"), (dict)) class No(Literal): def typefilter(self, values): return isinstance(values.get("value"), type(None)) class Add(Object): def value(self): result = self.values["a"].value().literal() + self.values["b"].value().literal() return Helper.wrapifneed(value=result) class Subtract(Object): def value(self): result = self.values["a"].value().literal() - self.values["b"].value().literal() return Helper.wrapifneed(value=result) class Multiply(Object): def value(self): result = self.values["a"].value().literal() * self.values["b"].value().literal() return Helper.wrapifneed(value=result) class Divide(Object): def value(self): result = self.values["a"].value().literal() / self.values["b"].value().literal() return Helper.wrapifneed(value=result) class Print(Object): def value(self): if self.positional: self.values["print"] = self.positional[0] print(Helper.wrapifneed(self.values["print"]).value().literal(), flush=True) class Read(Object): def value(self): prompt = "" if "prompt" in self.values: prompt = self.values["prompt"].value().literal() user_input = input(prompt) return Helper.wrapifneed(user_input) class Repeat(Object): def value(self): for i in range(self.values["times"].literal()): self.values["code"].value() class Forever(Object): def value(self): while True: self.values["code"].value() class While(Object): def value(self): while self.values["condition"].value().literal(): self.values["code"].value() class Index(Object): def value(self): return Helper.wrapifneed(self.values["object"].value().literal()[self.values["index"].value().literal()]) class Boolean(Literal): def typefilter(self, values): return isinstance(values.get("value"), (bool)) class String(Literal): def typefilter(self, values): return isinstance(values.get("value"), (str)) class List(Literal): def typefilter(self, values): return isinstance(values.get("value"), (list)) class Dict(Literal): def typefilter(self, values): return isinstance(values.get("value"), (dict)) class No(Literal): def typefilter(self, values): return isinstance(values.get("value"), type(None)) class If(Object): def value(self): if self.values["condition"].value().literal(): self.values["program"].value() class Equal(Object): def value(self): result = self.values["a"].value().literal() == self.values["b"].value().literal() return Boolean(value=result) class GreaterThan(Object): def value(self): return Boolean( value=self.values["a"].value().literal() > self.values["b"].value().literal() ) class LessThan(Object): def value(self): return Boolean( value=self.values["a"].value().literal() < self.values["b"].value().literal() ) class Not(Object): def value(self): return Boolean(value=not(self.values["condition"].value().literal())) class And(Object): def value(self): a = self.values["a"].value().literal() if not(a): return Boolean(value=False) b = self.values["b"].value().literal() return Boolean(value=b) class Or(Object): def value(self): a = self.values["a"].value().literal() if a: return Boolean(value=True) b = self.values["b"].value().literal() return Boolean(value=b) class Scope(Object): def value(self): Environment.push() self.values["program"].value() Environment.pop() class ToNumber(Object): def value(self): val = self.values["value"].value().literal() return Number(value=float(val)) class ToString(Object): def value(self): val = self.values["value"].value().literal() return String(value=str(val)) code = Program(code=[ Assign(variable=String(value="bottles"), value=Number(value=99)), While(condition=GreaterThan(a=Get(variable=String(value="bottles")), b=Number(value=1)), code=Program(code=[ Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer on the wall"))), Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer"))), Print(String(value="Take one down, pass it around")), Assign(variable=String(value="bottles"), value=Subtract(a=Get(variable=String(value="bottles")), b=Number(value=1))), If(condition=GreaterThan(a=Get(variable=String(value="bottles")), b=Number(value=1)), program=Program(code=[ Print(Add(a=ToString(value=Get(variable=String(value="bottles"))), b=String(value=" bottles of beer on the wall"))) ])) ])), Print("1 bottle of beer on the wall"), Print("1 bottle of beer"), Print("Take one down, pass it around"), Print("No more bottles of beer on the wall") ]) try: code.value() except ReturnSignal as e: print("execution stopped with exit code", e.value)