ithon/debug.txt
2024-11-28 18:17:24 -05:00

1703 lines
21 KiB
Text

---START FILE---
name: examples/test.it, len: 752
# ITHON START
import typing as _INTERNAL_typing
import types as _INTERNAL_types
import inspect as _INTERNAL_inspect
import sys as _INTERNAL_sys
class _INTERNAL_Token:
__slots__ = ('action',)
def __init__(self, action):
self.action = action
def __rrshift__(self, lhs):
return _INTERNAL_Operation(self.action, lhs)
class _INTERNAL_Operation:
__slots__ = ('action', 'lhs')
def __init__(self, action, lhs):
self.action = action
self.lhs = lhs
def __lshift__(self, rhs):
return self.action(self.lhs, rhs)
class _INTERNAL_LazyIterable:
__slots__ = ('x','y')
def __init__(self, x, y) -> None:
self.x = iter(x)
self.y = iter(y)
def __iter__(self):
yield from self.x
yield from self.y
def curry(f):
def wrapper(*args, **kwds) -> _INTERNAL_typing.Any | _INTERNAL_typing.Callable:
signature = _INTERNAL_inspect.signature(f)
ba = signature.bind_partial(*args, **kwds)
if len(ba.arguments) == len(signature.parameters):
return f(*args, **kwds)
else:
def _partial(*other_args, **other_kwds):
combined_args = args + other_args
combined_kwargs = dict(**kwds, **other_kwds)
return curry(f)(*combined_args, **combined_kwargs)
return _partial
return wrapper
def compose(*funcs):
def _composed(arg):
val = arg
for i in funcs:
val = i(val)
return val
return _composed
def _INTERNAL_add_fakeimport(name: str, code: str): # TODO: make this use sys.meta_path
module = _INTERNAL_types.ModuleType(name)
parent = '.'.join(name.split('.')[:-1]) if '.'.join(name.split('.')[:-1]) else name
if not parent == name and parent not in _INTERNAL_sys.modules:
_INTERNAL_sys.modules[parent] = _INTERNAL_types.ModuleType(parent)
globals = {'__package__': parent}
module.__dict__.update(globals)
exec(code, module.__dict__)
_INTERNAL_sys.modules[name] = module
_INTERNAL_add_fakeimport('sentinels', '''import sys as _sys
from threading import Lock as _Lock
__all__ = ['Sentinel']
# Design and implementation decisions:
#
# The first implementations created a dedicated class for each instance.
# However, once it was decided to use Sentinel for type signatures, there
# was no longer a need for a dedicated class for each sentinel value on order
# to enable strict type signatures. Since class objects consume a relatively
# large amount of memory, the implementation was changed to avoid this.
#
# With this change, the mechanism used for unpickling/copying objects needed
# to be changed too, since we could no longer count on each dedicated class
# simply returning its singleton instance as before. __reduce__ can return
# a string, upon which an attribute with that name is looked up in the module
# and returned. However, that would have meant that pickling/copying support
# would depend on the "name" argument being exactly the name of the variable
# used in the module, and simply wouldn't work for sentinels created in
# functions/methods. Instead, a registry for sentinels was added, where all
# sentinel objects are stored keyed by their name + module name. This is used
# to look up existing sentinels both during normal object creation and during
# copying/unpickling.
class Sentinel:
"""Create a unique sentinel object.
*name* should be the fully-qualified name of the variable to which the
return value shall be assigned.
*repr*, if supplied, will be used for the repr of the sentinel object.
If not provided, "<name>" will be used (with any leading class names
removed).
*module_name*, if supplied, will be used instead of inspecting the call
stack to find the name of the module from which
"""
_name: str
_repr: str
_module_name: str
def __new__(
cls,
name: str,
repr: str | None = None,
module_name: str | None = None,
):
name = str(name)
repr = str(repr) if repr else f'<{name.split(".")[-1]}>'
if not module_name:
parent_frame = _get_parent_frame()
module_name = (
parent_frame.f_globals.get('__name__', '__main__')
if parent_frame is not None
else __name__
)
# Include the class's module and fully qualified name in the
# registry key to support sub-classing.
registry_key = _sys.intern(
f'{cls.__module__}-{cls.__qualname__}-{module_name}-{name}'
)
sentinel = _registry.get(registry_key, None)
if sentinel is not None:
return sentinel
sentinel = super().__new__(cls)
sentinel._name = name
sentinel._repr = repr
sentinel._module_name = module_name
with _lock:
return _registry.setdefault(registry_key, sentinel)
def __repr__(self):
return self._repr
def __reduce__(self):
return (
self.__class__,
(
self._name,
self._repr,
self._module_name,
),
)
_lock = _Lock()
_registry: dict[str, Sentinel] = {}
# The following implementation attempts to support Python
# implementations which don't support sys._getframe(2), such as
# Jython and IronPython.
#
# For reference, see the implementation of namedtuple:
# https://github.com/python/cpython/blob/67444902a0f10419a557d0a2d3b8675c31b075a9/Lib/collections/__init__.py#L503
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
try:
# Two frames up = the parent of the function which called this.
return _sys._getframe(2)
except (AttributeError, ValueError):
global _get_parent_frame
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
try:
raise Exception
except Exception:
try:
return _sys.exc_info()[2].tb_frame.f_back.f_back
except Exception:
global _get_parent_frame
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
return None
return _get_parent_frame()
return _get_parent_frame()''')
_INTERNAL_add_fakeimport('ipathlib', '''import pathlib
from typing import Self
"""
Pathlib without all the PAINlib.
"""
class Path(pathlib.Path):
def listdir(self: Self) -> list[Self]:
return list(self.iterdir())
def remove(self: Self, missing_ok: bool = True) -> None:
"""Remove this file or link. If the path is a directory, use rmdir() instead."""
self.unlink(missing_ok=missing_ok)
def rmtree(self: Self):
if self.is_file():
self.remove()
else:
for child in self.iterdir():
child.rmtree()
self.rmdir()
PurePath = pathlib.PurePath''')
_INTERNAL_lazymerge = _INTERNAL_Token(lambda lhs, rhs: _INTERNAL_LazyIterable(lhs, rhs))
_INTERNAL_lpipe = _INTERNAL_Token(lambda lhs, rhs: rhs(lhs))
_INTERNAL_rpipe = _INTERNAL_Token(lambda lhs, rhs: lhs(rhs))
_INTERNAL_lspipe = _INTERNAL_Token(lambda lhs, rhs: rhs(*lhs))
_INTERNAL_rspipe = _INTERNAL_Token(lambda lhs, rhs: lhs(*rhs))
_INTERNAL_nonereplace = _INTERNAL_Token(lambda lhs, rhs: lhs if lhs != None else rhs)
_INTERNAL_lto = _INTERNAL_Token(lambda lhs, rhs: lhs(*rhs))
# If you write in other programming languages, this is very, very useful.
null = None
nil = None
void = None
# ITHON END
def fibonacci(x: int) -> list[int]:
start = [0,1]
for i in range(1, x):
start.append <| start[i] + start[i - 1]
return start
def a():
yield 1
+> 2
def b():
yield from a()
+>> a()
b() |> list |> print
a = 12 |> fibonacci
b = a :: a :: a :: a
c = b :: b :: b :: b
print <| [i for i in c]
print <*| ('a', 'b', 'c')
d = lambda x: x * 2
#d2 = λ x: x * 2
d3d = curry <| (lambda x, y: x**2 + y**2)
print(d3d(2,4))
print(d3d(2)(4))
print(d3d(x=2)(y=4))
@curry
def d3d2(x,y) = x**2 + y**2
print(d3d2(2,4))
print(d3d2(2)(4))
print(d3d2(x=2)(y=4))
a = 1
a++
print(None ?? a) # 2
'''a'''
/*
very bad code that is
commented out for a very
good reason
*/
a++ /* something */ # something
dtwice = compose(d,d)
print(dtwice(2))
---END FILE---
---START DEBOUT---
name: examples/test.it
64 # ITHON START
65
1 import
1 typing
1 as
1 _INTERNAL_typing
4
1 import
1 types
1 as
1 _INTERNAL_types
4
1 import
1 inspect
1 as
1 _INTERNAL_inspect
4
1 import
1 sys
1 as
1 _INTERNAL_sys
4
1 class
1 _INTERNAL_Token
55 :
4
5
1 __slots__
55 =
OP = ( 'action'
55 (
3 'action'
55 ,
OP , )
55 )
4
65
1 def
1 __init__
55 (
1 self
55 ,
1 action
55 )
OP ) :
55 :
4
5
1 self
55 .
1 action
55 =
1 action
4
65
6
1 def
1 __rrshift__
55 (
1 self
55 ,
1 lhs
55 )
OP ) :
55 :
4
5
1 return
1 _INTERNAL_Operation
55 (
1 self
55 .
1 action
55 ,
1 lhs
55 )
4
65
6
6
1 class
1 _INTERNAL_Operation
55 :
4
5
1 __slots__
55 =
OP = ( 'action'
55 (
3 'action'
55 ,
3 'lhs'
55 )
4
65
1 def
1 __init__
55 (
1 self
55 ,
1 action
55 ,
1 lhs
55 )
OP ) :
55 :
4
5
1 self
55 .
1 action
55 =
1 action
4
1 self
55 .
1 lhs
55 =
1 lhs
4
65
6
1 def
1 __lshift__
55 (
1 self
55 ,
1 rhs
55 )
OP ) :
55 :
4
5
1 return
1 self
55 .
1 action
55 (
1 self
55 .
1 lhs
55 ,
1 rhs
55 )
4
65
6
6
1 class
1 _INTERNAL_LazyIterable
55 :
4
5
1 __slots__
55 =
OP = ( 'x'
55 (
3 'x'
55 ,
3 'y'
55 )
4
1 def
1 __init__
55 (
1 self
55 ,
1 x
55 ,
1 y
55 )
OP ) -> None
55 ->
1 None
55 :
4
5
1 self
55 .
1 x
55 =
1 iter
55 (
1 x
55 )
4
1 self
55 .
1 y
55 =
1 iter
55 (
1 y
55 )
4
6
1 def
1 __iter__
55 (
1 self
55 )
OP ) :
55 :
4
5
1 yield
1 from
1 self
55 .
1 x
4
1 yield
1 from
1 self
55 .
1 y
4
65
6
6
1 def
1 curry
55 (
1 f
55 )
OP ) :
55 :
4
5
1 def
1 wrapper
55 (
OP ( * args
55 *
1 args
55 ,
OP , ** kwds
55 **
1 kwds
55 )
OP ) -> _INTERNAL_typing
55 ->
1 _INTERNAL_typing
55 .
1 Any
55 |
1 _INTERNAL_typing
55 .
1 Callable
55 :
4
5
1 signature
55 =
1 _INTERNAL_inspect
55 .
1 signature
55 (
1 f
55 )
4
1 ba
55 =
1 signature
55 .
1 bind_partial
55 (
OP ( * args
55 *
1 args
55 ,
OP , ** kwds
55 **
1 kwds
55 )
4
1 if
1 len
55 (
1 ba
55 .
1 arguments
55 )
OP ) == len
55 ==
1 len
55 (
1 signature
55 .
1 parameters
55 )
OP ) :
55 :
4
5
1 return
1 f
55 (
OP ( * args
55 *
1 args
55 ,
OP , ** kwds
55 **
1 kwds
55 )
4
6
1 else
55 :
4
5
1 def
1 _partial
55 (
OP ( * other_args
55 *
1 other_args
55 ,
OP , ** other_kwds
55 **
1 other_kwds
55 )
OP ) :
55 :
4
5
1 combined_args
55 =
1 args
55 +
1 other_args
4
1 combined_kwargs
55 =
1 dict
55 (
OP ( ** kwds
55 **
1 kwds
55 ,
OP , ** other_kwds
55 **
1 other_kwds
55 )
4
1 return
1 curry
55 (
1 f
55 )
OP ) ( *
55 (
OP ( * combined_args
55 *
1 combined_args
55 ,
OP , ** combined_kwargs
55 **
1 combined_kwargs
55 )
4
6
1 return
1 _partial
4
6
6
1 return
1 wrapper
4
65
6
1 def
1 compose
55 (
OP ( * funcs
55 *
1 funcs
55 )
OP ) :
55 :
4
5
1 def
1 _composed
55 (
1 arg
55 )
OP ) :
55 :
4
5
1 val
55 =
1 arg
4
1 for
1 i
1 in
1 funcs
55 :
4
5
1 val
55 =
1 i
55 (
1 val
55 )
4
6
1 return
1 val
4
6
1 return
1 _composed
4
65
6
1 def
1 _INTERNAL_add_fakeimport
55 (
1 name
55 :
1 str
55 ,
1 code
55 :
1 str
55 )
OP ) : # TODO: make this use sys.meta_path
55 :
64 # TODO: make this use sys.meta_path
4
5
1 module
55 =
1 _INTERNAL_types
55 .
1 ModuleType
55 (
1 name
55 )
4
1 parent
55 =
3 '.'
55 .
1 join
55 (
1 name
55 .
1 split
55 (
3 '.'
55 )
OP ) [ :
55 [
OP [ : -
55 :
OP : - 1
55 -
2 1
55 ]
OP ] ) if
55 )
1 if
3 '.'
55 .
1 join
55 (
1 name
55 .
1 split
55 (
3 '.'
55 )
OP ) [ :
55 [
OP [ : -
55 :
OP : - 1
55 -
2 1
55 ]
OP ] ) else
55 )
1 else
1 name
4
1 if
1 not
1 parent
55 ==
1 name
1 and
1 parent
1 not
1 in
1 _INTERNAL_sys
55 .
1 modules
55 :
4
5
1 _INTERNAL_sys
55 .
1 modules
55 [
1 parent
55 ]
OP ] = _INTERNAL_types
55 =
1 _INTERNAL_types
55 .
1 ModuleType
55 (
1 parent
55 )
4
6
1 globals
55 =
OP = { '__package__'
55 {
3 '__package__'
55 :
1 parent
55 }
4
1 module
55 .
1 __dict__
55 .
1 update
55 (
1 globals
55 )
4
1 exec
55 (
1 code
55 ,
1 module
55 .
1 __dict__
55 )
4
1 _INTERNAL_sys
55 .
1 modules
55 [
1 name
55 ]
OP ] = module
55 =
1 module
4
65
6
1 _INTERNAL_add_fakeimport
55 (
3 'sentinels'
55 ,
3 '''import sys as _sys
from threading import Lock as _Lock
__all__ = ['Sentinel']
# Design and implementation decisions:
#
# The first implementations created a dedicated class for each instance.
# However, once it was decided to use Sentinel for type signatures, there
# was no longer a need for a dedicated class for each sentinel value on order
# to enable strict type signatures. Since class objects consume a relatively
# large amount of memory, the implementation was changed to avoid this.
#
# With this change, the mechanism used for unpickling/copying objects needed
# to be changed too, since we could no longer count on each dedicated class
# simply returning its singleton instance as before. __reduce__ can return
# a string, upon which an attribute with that name is looked up in the module
# and returned. However, that would have meant that pickling/copying support
# would depend on the "name" argument being exactly the name of the variable
# used in the module, and simply wouldn't work for sentinels created in
# functions/methods. Instead, a registry for sentinels was added, where all
# sentinel objects are stored keyed by their name + module name. This is used
# to look up existing sentinels both during normal object creation and during
# copying/unpickling.
class Sentinel:
"""Create a unique sentinel object.
*name* should be the fully-qualified name of the variable to which the
return value shall be assigned.
*repr*, if supplied, will be used for the repr of the sentinel object.
If not provided, "<name>" will be used (with any leading class names
removed).
*module_name*, if supplied, will be used instead of inspecting the call
stack to find the name of the module from which
"""
_name: str
_repr: str
_module_name: str
def __new__(
cls,
name: str,
repr: str | None = None,
module_name: str | None = None,
):
name = str(name)
repr = str(repr) if repr else f'<{name.split(".")[-1]}>'
if not module_name:
parent_frame = _get_parent_frame()
module_name = (
parent_frame.f_globals.get('__name__', '__main__')
if parent_frame is not None
else __name__
)
# Include the class's module and fully qualified name in the
# registry key to support sub-classing.
registry_key = _sys.intern(
f'{cls.__module__}-{cls.__qualname__}-{module_name}-{name}'
)
sentinel = _registry.get(registry_key, None)
if sentinel is not None:
return sentinel
sentinel = super().__new__(cls)
sentinel._name = name
sentinel._repr = repr
sentinel._module_name = module_name
with _lock:
return _registry.setdefault(registry_key, sentinel)
def __repr__(self):
return self._repr
def __reduce__(self):
return (
self.__class__,
(
self._name,
self._repr,
self._module_name,
),
)
_lock = _Lock()
_registry: dict[str, Sentinel] = {}
# The following implementation attempts to support Python
# implementations which don't support sys._getframe(2), such as
# Jython and IronPython.
#
# For reference, see the implementation of namedtuple:
# https://github.com/python/cpython/blob/67444902a0f10419a557d0a2d3b8675c31b075a9/Lib/collections/__init__.py#L503
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
try:
# Two frames up = the parent of the function which called this.
return _sys._getframe(2)
except (AttributeError, ValueError):
global _get_parent_frame
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
try:
raise Exception
except Exception:
try:
return _sys.exc_info()[2].tb_frame.f_back.f_back
except Exception:
global _get_parent_frame
def _get_parent_frame():
"""Return the frame object for the caller's parent stack frame."""
return None
return _get_parent_frame()
return _get_parent_frame()'''[1, 2]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
a b c
20
20
20
20
20
20
2
8
55 )
4
1 _INTERNAL_add_fakeimport
55 (
3 'ipathlib'
55 ,
3 '''import pathlib
from typing import Self
"""
Pathlib without all the PAINlib.
"""
class Path(pathlib.Path):
def listdir(self: Self) -> list[Self]:
return list(self.iterdir())
def remove(self: Self, missing_ok: bool = True) -> None:
"""Remove this file or link. If the path is a directory, use rmdir() instead."""
self.unlink(missing_ok=missing_ok)
def rmtree(self: Self):
if self.is_file():
self.remove()
else:
for child in self.iterdir():
child.rmtree()
self.rmdir()
PurePath = pathlib.PurePath'''
55 )
4
1 _INTERNAL_lazymerge
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 _INTERNAL_LazyIterable
55 (
1 lhs
55 ,
1 rhs
55 )
OP ) )
55 )
4
65
1 _INTERNAL_lpipe
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 rhs
55 (
1 lhs
55 )
OP ) )
55 )
4
1 _INTERNAL_rpipe
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 lhs
55 (
1 rhs
55 )
OP ) )
55 )
4
1 _INTERNAL_lspipe
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 rhs
55 (
OP ( * lhs
55 *
1 lhs
55 )
OP ) )
55 )
4
1 _INTERNAL_rspipe
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 lhs
55 (
OP ( * rhs
55 *
1 rhs
55 )
OP ) )
55 )
4
65
1 _INTERNAL_nonereplace
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 lhs
1 if
1 lhs
55 !=
1 None
1 else
1 rhs
55 )
4
65
1 _INTERNAL_lto
55 =
1 _INTERNAL_Token
55 (
1 lambda
1 lhs
55 ,
1 rhs
55 :
1 lhs
55 (
OP ( * rhs
55 *
1 rhs
55 )
OP ) )
55 )
4
65
64 # If you write in other programming languages, this is very, very useful.
65
1 null
55 =
1 None
4
1 nil
55 =
1 None
4
1 void
55 =
1 None
4
65
64 # ITHON END
65
65
1 def
1 fibonacci
55 (
1 x
55 :
1 int
55 )
OP ) -> list
55 ->
1 list
55 [
1 int
55 ]
OP ] :
55 :
4
5
1 start
55 =
OP = [ 0
55 [
2 0
55 ,
2 1
55 ]
4
1 for
1 i
1 in
1 range
55 (
2 1
55 ,
1 x
55 )
OP ) :
55 :
4
5
1 start
55 .
1 append
55 <
OP < | start
55 |
1 start
55 [
1 i
55 ]
OP ] + start
55 +
1 start
55 [
1 i
55 -
2 1
55 ]
4
6
1 return
1 start
4
6
1 def
1 a
55 (
OP ( ) :
55 )
OP ) :
55 :
4
5
1 yield
2 1
4
55 +
OP + > 2
55 >
2 2
4
6
1 def
1 b
55 (
OP ( ) :
55 )
OP ) :
55 :
4
5
1 yield
1 from
1 a
55 (
OP ( )
55 )
4
55 +
OP + >> a
55 >>
1 a
55 (
OP ( )
55 )
4
6
1 b
55 (
OP ( ) |
55 )
OP ) | >
55 |
OP | > list
55 >
1 list
55 |
OP | > print
55 >
1 print
4
1 a
55 =
2 12
55 |
OP | > fibonacci
55 >
1 fibonacci
4
1 b
55 =
1 a
55 :
OP : : a
55 :
1 a
55 :
OP : : a
55 :
1 a
55 :
OP : : a
55 :
1 a
4
1 c
55 =
1 b
55 :
OP : : b
55 :
1 b
55 :
OP : : b
55 :
1 b
55 :
OP : : b
55 :
1 b
4
1 print
55 <
OP < | [
55 |
55 [
1 i
1 for
1 i
1 in
1 c
55 ]
4
1 print
55 <
OP < * |
55 *
55 |
55 (
3 'a'
55 ,
3 'b'
55 ,
3 'c'
55 )
4
1 d
55 =
1 lambda
1 x
55 :
1 x
55 *
2 2
4
64 #d2 = λ x: x * 2
65
65
1 d3d
55 =
1 curry
55 <
OP < | (
55 |
55 (
1 lambda
1 x
55 ,
1 y
55 :
1 x
55 **
2 2
55 +
1 y
55 **
2 2
55 )
4
1 print
55 (
1 d3d
55 (
2 2
55 ,
2 4
55 )
OP ) )
55 )
4
1 print
55 (
1 d3d
55 (
2 2
55 )
OP ) ( 4
55 (
2 4
55 )
OP ) )
55 )
4
1 print
55 (
1 d3d
55 (
1 x
55 =
2 2
55 )
OP ) ( y
55 (
1 y
55 =
2 4
55 )
OP ) )
55 )
4
55 @
1 curry
4
1 def
1 d3d2
55 (
1 x
55 ,
1 y
55 )
OP ) = x
55 =
1 x
55 **
2 2
55 +
1 y
55 **
2 2
4
1 print
55 (
1 d3d2
55 (
2 2
55 ,
2 4
55 )
OP ) )
55 )
4
1 print
55 (
1 d3d2
55 (
2 2
55 )
OP ) ( 4
55 (
2 4
55 )
OP ) )
55 )
4
1 print
55 (
1 d3d2
55 (
1 x
55 =
2 2
55 )
OP ) ( y
55 (
1 y
55 =
2 4
55 )
OP ) )
55 )
4
65
1 a
55 =
2 1
4
1 a
55 +
OP + +
55 +
4
1 print
55 (
1 None
55 ?
OP ? ? a
55 ?
1 a
55 )
64 # 2
4
3 '''a'''
4
55 /
OP / *
55 *
4
1 very
1 bad
1 code
1 that
1 is
4
1 commented
1 out
1 for
1 a
1 very
4
1 good
1 reason
4
55 *
OP * /
55 /
4
1 a
55 +
OP + + /
55 +
55 /
OP / * something
55 *
1 something
55 *
OP * / # something
55 /
64 # something
4
65
1 dtwice
55 =
1 compose
55 (
1 d
55 ,
1 d
55 )
4
1 print
55 (
1 dtwice
55 (
2 2
55 )
OP ) )
55 )
4
0
---END DEBOUT---