117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
from typing import Callable, Dict, List, Tuple
|
|
|
|
from ppp_ast import Statements
|
|
from ppp_object import Bool, EnumValue, Int, Object, Function, Str, TypeObject, Void, List as ListObject
|
|
from ppp_types import Bool as BoolType, FunctionType, GenericType, Int as IntType, Str as StrType, Type, TypeType, VariableType, Void as VoidType, Object as ObjectType, ListType
|
|
|
|
|
|
def PythonFunction(name: str, parameters: List[Tuple[str, Type]], return_type: Type, func: Callable[..., Object]) -> Object:
|
|
return Function(FunctionType([parameter[1] for parameter in parameters], return_type), (name, parameters, return_type, Statements([]), lambda _0, _1, _2, _3, *args: func(*args)))
|
|
|
|
def print_impl(str_: Object) -> Object:
|
|
assert isinstance(str_, Str)
|
|
print(str_.str, end='')
|
|
return Void
|
|
|
|
Print = PythonFunction("print", [('string', StrType)], VoidType, print_impl)
|
|
|
|
def int_to_str_impl(int_: Object) -> Object:
|
|
assert isinstance(int_, Int)
|
|
return Str(str(int_.num))
|
|
|
|
IntToStr = PythonFunction("int_to_str", [('integer', IntType)], StrType, int_to_str_impl)
|
|
|
|
def debug_print_impl(obj: Object) -> Object:
|
|
print(obj)
|
|
return Void
|
|
|
|
DebugPrint = PythonFunction("debug_print", [('object', ObjectType)], VoidType, debug_print_impl)
|
|
|
|
def read_impl(str_: Object) -> Object:
|
|
assert isinstance(str_, Str)
|
|
with open(str_.str) as f: return Str(f.read())
|
|
|
|
Read = PythonFunction("read", [('file_path', StrType)], StrType, read_impl)
|
|
|
|
def len_impl(list_: Object) -> Object:
|
|
assert list_.get_type().is_indexable(), list_
|
|
match list_:
|
|
case Str(str): return Int(len(str))
|
|
case ListObject(_, list): return Int(len(list))
|
|
case _: assert False, ("Unimplemented", list_)
|
|
assert False
|
|
|
|
# TODO: Use polymorphism to make this work for both list<T> and str
|
|
Len = PythonFunction("len", [('list', ListType(VariableType("")))], IntType, len_impl)
|
|
|
|
def str_len_impl(str_: Object) -> Object:
|
|
assert isinstance(str_, Str)
|
|
return Int(len(str_.str))
|
|
|
|
StrLen = PythonFunction("strlen", [('string', StrType)], IntType, str_len_impl)
|
|
|
|
def str_to_int_impl(str_: Object) -> Object:
|
|
assert isinstance(str_, Str)
|
|
assert str_.str.isdigit()
|
|
return Int(int(str_.str))
|
|
|
|
StrToInt = PythonFunction("str_to_int", [('string', StrType)], IntType, str_to_int_impl)
|
|
|
|
def range_impl(start: Object, end: Object) -> Object:
|
|
assert isinstance(start, Int)
|
|
assert isinstance(end, Int)
|
|
return ListObject(ListType(IntType), [Int(i) for i in range(start.num, end.num)])
|
|
|
|
Range = PythonFunction("range", [('start', IntType), ('end', IntType)], ListType(IntType), range_impl)
|
|
|
|
def join_by_impl(seperator: Object, list: Object) -> Object:
|
|
assert isinstance(seperator, Str)
|
|
assert isinstance(list, ListObject)
|
|
if len(list.list) == 0: return Str("")
|
|
assert list.type.type.is_subtype_of(StrType), list
|
|
new_array: List[str] = []
|
|
for str_ in list.list:
|
|
assert isinstance(str_, Str)
|
|
new_array.append(str_.str)
|
|
return Str(seperator.str.join(new_array))
|
|
|
|
JoinBy = PythonFunction("join_by", [('seperator', StrType), ('list', ListType(StrType))], StrType, join_by_impl)
|
|
|
|
def id_impl(obj: Object) -> Object:
|
|
match obj:
|
|
case EnumValue(_, _, _): return Int(id(obj))
|
|
case _: assert False, ("Unimplemented", obj)
|
|
|
|
|
|
Id = PythonFunction("id", [('object', ObjectType)], IntType, id_impl)
|
|
|
|
StrTypeObj = TypeObject(StrType)
|
|
IntTypeObj = TypeObject(IntType)
|
|
VoidTypeObj = TypeObject(VoidType)
|
|
BoolTypeObj = TypeObject(BoolType)
|
|
|
|
True_ = Bool(True)
|
|
False_ = Bool(False)
|
|
|
|
NoneObj = Void
|
|
|
|
variables: Dict[str, Object] = {
|
|
'print': Print,
|
|
'true': True_,
|
|
'false': False_,
|
|
'int_to_str': IntToStr,
|
|
'str': StrTypeObj,
|
|
'int': IntTypeObj,
|
|
'bool': BoolTypeObj,
|
|
'void': VoidTypeObj,
|
|
'debug_print': DebugPrint,
|
|
'read': Read,
|
|
'len': Len,
|
|
'str_len': StrLen,
|
|
'str_to_int': StrToInt,
|
|
'none': NoneObj,
|
|
'range': Range,
|
|
'join_by': JoinBy,
|
|
'id': Id
|
|
}
|