mirror of
https://github.com/egormanga/Slang.git
synced 2025-03-01 18:09:30 +03:00
226 lines
6.4 KiB
Python
226 lines
6.4 KiB
Python
#!/usr/bin/python3
|
|
# Slang stdlib
|
|
|
|
from .ast import Signature, Function, Object, Collection, CallArguments, MultiCollection
|
|
from .tokens import *
|
|
from utils import *
|
|
|
|
class Builtin(Signature):
|
|
@classitemget
|
|
def attrops(cls, optype, attr):
|
|
if (optype == '.'):
|
|
try: return getattr(cls, attr)()
|
|
except AttributeError: raise KeyError()
|
|
raise KeyError()
|
|
|
|
@property
|
|
def __reprname__(self):
|
|
return first(i.__name__ for i in self.__class__.mro() if i.__name__.startswith('Builtin'))
|
|
|
|
@property
|
|
def typename(self):
|
|
return self.__class__.__name__
|
|
|
|
class BuiltinFunction(Builtin, Function):
|
|
def __init__(self):
|
|
super().__init__(name=self.__class__.__name__)
|
|
|
|
class BuiltinObject(Builtin, Object): pass
|
|
|
|
class BuiltinType(Builtin):
|
|
def __eq__(self, x):
|
|
return (super().__eq__(x) or issubclass(x.__class__, self.__class__) or issubclass(self.__class__, x.__class__))
|
|
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None, selftype=None):
|
|
if (valsig is None):
|
|
if (op in operators[9]): return bool # unary `not'
|
|
else:
|
|
assert (selftype is not None)
|
|
if (isinstance(valsig, selftype) and op in operators[8]): return bool # comparisons
|
|
if (op in operators[10]+operators[11]+operators[12]): return type(valsig) # binary `and'. `xor', `or'
|
|
raise KeyError()
|
|
|
|
@singleton
|
|
class Any(BuiltinType):
|
|
def __eq__(self, x):
|
|
return True
|
|
|
|
class auto(BuiltinType): pass
|
|
|
|
class void(BuiltinType):
|
|
@staticitemget
|
|
def operators(op, valsig=None):
|
|
raise KeyError()
|
|
|
|
class bool(BuiltinType):
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None):
|
|
try: return BuiltinType.operators(op, valsig=valsig, selftype=bool)
|
|
except KeyError: pass
|
|
if (valsig is None):
|
|
if (op in map(UnaryOperator, '+-~')): return int
|
|
if (op == UnaryOperator('!')): return bool
|
|
raise KeyError()
|
|
|
|
class int(BuiltinType):
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None):
|
|
try: return BuiltinType.operators(op, valsig=valsig, selftype=int)
|
|
except KeyError: pass
|
|
if (valsig is None):
|
|
if (op in map(UnaryOperator, '+-~')): return int
|
|
if (op == UnaryOperator('!')): return bool
|
|
if (isinstance(valsig, (int, float))):
|
|
if (op in map(BinaryOperator, ('**', *'+-*%'))): return valsig
|
|
if (op in map(BinaryOperator, ('//', '<<', '>>', *'&^|'))): return int
|
|
if (op == BinaryOperator('/')): return float
|
|
if (isinstance(valsig, int)):
|
|
if (op == BinaryOperator('to')): return range
|
|
raise KeyError()
|
|
|
|
class float(BuiltinType):
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None):
|
|
try: return BuiltinType.operators(op, valsig=valsig, selftype=float)
|
|
except KeyError: pass
|
|
if (valsig is None):
|
|
if (op in map(UnaryOperator, '+-')): return float
|
|
if (op == UnaryOperator('!')): return bool
|
|
if (isinstance(valsig, (int, float))):
|
|
if (op in map(BinaryOperator, ('**', *'+-*%'))): return float
|
|
if (op == BinaryOperator('/')): return float
|
|
if (op == BinaryOperator('//')): return int
|
|
raise KeyError()
|
|
|
|
class str(BuiltinType):
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None):
|
|
try: return BuiltinType.operators(op, valsig=valsig, selftype=str)
|
|
except KeyError: pass
|
|
if (valsig is not None):
|
|
if (isinstance(valsig, (char, str)) and op == BinaryOperator('+')): return str
|
|
if (isinstance(valsig, int) and op == BinaryOperator('*')): return str
|
|
raise KeyError()
|
|
|
|
@staticitemget
|
|
@instantiate
|
|
def itemget(keysig, key):
|
|
if (isinstance(keysig, int)): return char
|
|
raise KeyError()
|
|
|
|
class rstrip(BuiltinFunction):
|
|
callargssigstr: "rstrip(char)"
|
|
|
|
@staticmethod
|
|
@instantiate
|
|
def compatible_call(callarguments, ns):
|
|
if (callarguments.kwargs or callarguments.starkwargs): return None
|
|
return (None, str())
|
|
|
|
class count(BuiltinFunction):
|
|
callargssig: "count(char)"
|
|
|
|
@staticmethod
|
|
@instantiate
|
|
def compatible_call(callarguments, ns):
|
|
if (callarguments.kwargs or callarguments.starkwargs): return None
|
|
return (None, int())
|
|
|
|
class char(BuiltinType):
|
|
@staticitemget
|
|
@instantiate
|
|
def operators(op, valsig=None):
|
|
try: return BuiltinType.operators(op, valsig=valsig, selftype=char)
|
|
except KeyError: pass
|
|
if (valsig is not None):
|
|
if (isinstance(valsig, str) and op in map(BinaryOperator, ('+', 'in'))): return str
|
|
if (isinstance(valsig, int) and op == BinaryOperator('*')): return str
|
|
if (isinstance(valsig, (char, int)) and op in map(BinaryOperator, '+-')): return char
|
|
raise KeyError()
|
|
|
|
class i8(int): fmt: 'b'
|
|
class u8(int): fmt: 'B'
|
|
class i16(int): fmt: 'h'
|
|
class u16(int): fmt: 'H'
|
|
class i32(int): fmt: 'i'
|
|
class u32(int): fmt: 'I'
|
|
class i64(int): fmt: 'q'
|
|
class u64(int): fmt: 'Q'
|
|
#class i128(int): fmt: '
|
|
#class u128(int): fmt: '
|
|
|
|
#class f8(float): fmt: '
|
|
#class f16(float): fmt: 'e'
|
|
#class f32(float): fmt: 'f'
|
|
#class f64(float): fmt: 'd'
|
|
#class f128(float): fmt: '
|
|
#uf8 = uf16 = uf32 = uf64 = uf128 = float
|
|
|
|
class range(BuiltinType):
|
|
keytype: int
|
|
valtype: int
|
|
|
|
@staticitemget
|
|
def operators(op, valsig=None):
|
|
raise KeyError()
|
|
|
|
class iterable(Collection, BuiltinType): pass
|
|
|
|
class list(iterable):
|
|
keytype: int
|
|
|
|
def __init__(self, *, valtype=Any):
|
|
super().__init__(keytype=self.keytype, valtype=valtype)
|
|
|
|
@staticitemget
|
|
def attrops(optype, attr):
|
|
if (optype == '.'):
|
|
if (attr == 'each'): return _each()
|
|
raise KeyError()
|
|
|
|
class tuple(iterable, MultiCollection):
|
|
keytype: int
|
|
|
|
def __init__(self, *, valtypes=()):
|
|
super().__init__(keytype=self.keytype, valtypes=valtypes)
|
|
|
|
class stdio(BuiltinObject):
|
|
class println(BuiltinFunction):
|
|
callargssigstr: "println(...)"
|
|
|
|
@staticmethod
|
|
def compatible_call(callarguments, ns):
|
|
if (callarguments.kwargs or callarguments.starkwargs): return None
|
|
return (None, void())
|
|
|
|
class _map(BuiltinFunction):
|
|
@staticmethod
|
|
def compatible_call(callarguments, ns):
|
|
if (len(callarguments.args) != 1 or
|
|
callarguments.starargs or
|
|
callarguments.kwargs or
|
|
callarguments.starkwargs): return None
|
|
return (None, list(valtype=Any))
|
|
|
|
|
|
class _each(BuiltinFunction):
|
|
@staticmethod
|
|
def compatible_call(callarguments, ns):
|
|
if (len(callarguments.args) != 1 or
|
|
callarguments.starargs or
|
|
callarguments.kwargs or
|
|
callarguments.starkwargs): return None
|
|
#fsig = Signature.build(callarguments.args[0], ns)
|
|
return (None, list(valtype=Any))
|
|
|
|
builtin_names = {k: v for i in map(allsubclassdict, Builtin.__subclasses__()) for k, v in i.items()}
|
|
builtin_names.update({i: globals()[i] for i in (i+j for j in map(builtins.str, (8, 16, 32, 64, 128)) for i in (*'iuf', 'uf') if i+j in globals())})
|
|
|
|
# by Sdore, 2020
|