mirror of
https://github.com/egormanga/Slang.git
synced 2025-10-15 16:37:15 +03:00
Huge work; i'm too tired to write commit message for all of it. Pleez let me sleep acouple of hours. Made most tests work. Started SBC.
This commit is contained in:
135
compilers/esolang/gibberish.py
Normal file
135
compilers/esolang/gibberish.py
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/python3
|
||||
# Slang Esolang Gibberish compilation target (PoC)
|
||||
# https://esolangs.org/wiki/Gibberish_(programming_language)
|
||||
|
||||
from .. import *
|
||||
from Slang.ast import *
|
||||
from utils import *
|
||||
|
||||
class Instrs:
|
||||
binopmap = {
|
||||
'+': b'ea',
|
||||
'-': b'es',
|
||||
'*': b'em',
|
||||
'/': b'ed',
|
||||
'<<': b'fl',
|
||||
'>>': b'fr',
|
||||
'&': b'ga',
|
||||
}
|
||||
|
||||
@init_defaults
|
||||
@autocast
|
||||
def __init__(self, ns, stack: Slist, functions: dict):
|
||||
self.ns, self.stack, self.functions = ns, stack, functions
|
||||
self.code = bytearray()
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTRootNode):
|
||||
self.add(x.code)
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTCodeNode):
|
||||
for i in x.nodes:
|
||||
self.add(i)
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTVardefNode):
|
||||
if (x.value is not None):
|
||||
self.load(x.value)
|
||||
self.stack[-1] = Signature.build(x, self.ns)
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTAssignmentNode):
|
||||
sig = Signature.build(x.name, self.ns)
|
||||
for ii, i in enumerate(self.stack):
|
||||
if (i == sig): self.stack[ii] = None
|
||||
self.load(x.value)
|
||||
self.stack[-1] = sig
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTFunccallNode):
|
||||
self.load(x)
|
||||
self.code += b'ev'
|
||||
self.stack.pop()
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTFuncdefNode):
|
||||
code_ns = self.ns.derive(x.name.identifier)
|
||||
if (x.name.identifier == 'main'):
|
||||
assert not x.argdefs
|
||||
name = x.name.identifier
|
||||
else: name = f"{x.name.identifier}__{self.ns.signatures[x.name.identifier].call.index(CallArguments(args=tuple(Signature.build(i, code_ns) for i in x.argdefs)))}"
|
||||
f_instrs = Instrs(ns=code_ns, stack=(Signature.build(i, code_ns) for i in x.argdefs), functions=self.functions.copy())
|
||||
f_instrs.add(x.code)
|
||||
#dlog(f"{x.__fsig__()} instrs:\n"+'\n'.join(f_instrs.instrs)+'\n')
|
||||
self.functions[name] = f_instrs
|
||||
|
||||
@dispatch
|
||||
def add(self, x: ASTKeywordExprNode):
|
||||
if (x.keyword.keyword == 'return'):
|
||||
self.load(x.value)
|
||||
else: raise NotImplementedError(x.keyword)
|
||||
|
||||
@dispatch
|
||||
def load(self, x: ASTLiteralNode):
|
||||
s = str(eval(str(x.literal))).encode().split(b']')
|
||||
if (s):
|
||||
s[0] = b'['+s[0]
|
||||
s[-1] += b']'
|
||||
self.code += b'][93]eigtec['.join(s) + b'c'*(len(s)-1)
|
||||
if (issubclass(literal_type(x.literal), (int, float))): self.code += b'ei'
|
||||
self.stack.append(None)
|
||||
|
||||
@dispatch
|
||||
def load(self, x: ASTIdentifierNode):
|
||||
dlog(self.stack)
|
||||
sig = Signature.build(x, self.ns)
|
||||
i = self.stack.rindex(sig)
|
||||
self.code += (b'[%d]eip' if (i >= 10) else b'%dep') % i
|
||||
self.stack.append(sig)
|
||||
|
||||
@dispatch
|
||||
def load(self, x: ASTValueNode):
|
||||
self.load(x.value)
|
||||
|
||||
@dispatch
|
||||
def load(self, x: ASTFunccallNode):
|
||||
assert not (x.callargs.starargs or x.callkwargs.callkwargs or x.callkwargs.starkwargs)
|
||||
if (x.callable.value.identifier == 'print'):
|
||||
for i in x.callargs.callargs[:-1]:
|
||||
self.load(i)
|
||||
self.code += b'eq[32]eigteq'
|
||||
self.stack.pop()
|
||||
if (x.callargs.callargs):
|
||||
self.load(x.callargs.callargs[-1])
|
||||
self.stack.pop()
|
||||
else: self.code += b'[]'
|
||||
self.code += b'eo'
|
||||
self.stack.append(None)
|
||||
return
|
||||
for i in x.callargs.callargs[::-1]:
|
||||
self.load(i)
|
||||
self.stack.pop()
|
||||
self.code += self.functions[f"{x.callable.value.identifier}__{self.ns.signatures[x.callable.value.identifier].call.index(CallArguments.build(x, self.ns))}" if (isinstance(x.callable, ASTValueNode) and isinstance(x.callable.value, ASTIdentifierNode) and x.callable.value.identifier in self.ns.signatures) else x.callable.value.identifier].code#.join((b'{', b'}'))
|
||||
|
||||
@dispatch
|
||||
def load(self, x: ASTBinaryExprNode):
|
||||
self.load(x.lvalue)
|
||||
self.load(x.rvalue)
|
||||
self.code += self.binopmap[x.operator.operator]
|
||||
self.stack.pop()
|
||||
self.stack.pop()
|
||||
self.stack.append(None)
|
||||
|
||||
class GibberishCompiler(Compiler):
|
||||
ext = '.gib'
|
||||
|
||||
@classmethod
|
||||
def compile_ast(cls, ast, ns, *, filename):
|
||||
instrs = Instrs(ns=ns)
|
||||
instrs.add(ast)
|
||||
code = bytes(instrs.code)
|
||||
dlog("Code:\n"+code.decode())
|
||||
return code
|
||||
|
||||
# by Sdore, 2019
|
Reference in New Issue
Block a user