#!/usr/bin/env python3
# -*- coding: utf8 -*-

# Neutrino Programming Language by HyperNeutrino
# Parts of this program are taken from Dennis's code for the Jelly programming language,
# in compliance to the MIT license and with his additionally expressed permission
# Parts of this program are taken from the Enlist programming language which is original work of HyperNeutrino

codepage  = """ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?"""
codepage += """@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂"""
codepage += """ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑªº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"""
codepage += """└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ """

import sys, re

cl_arg = re.compile("--?[A-Za-z_]+")

arguments = sys.argv[2:]

cl_args = [arg for arg in arguments if cl_arg.match(arg)]
pr_args = [arg for arg in arguments if arg not in cl_args]

cl = []

for arg in cl_args:
    if arg[1] == "-":
        cl.append(arg[2:])
    else:
        cl += list(arg[1:])

SYMPY = True
TEST = False
UTF_8 = False

for argument in cl:
    if argument == "native" or argument == "n":
        SYMPY = False
    if argument == "test":
        TEST = True
    if argument == "u" or argument == "utf-8":
        UTF_8 = True

if SYMPY: import sympy

import re, math, operator, sys, locale, functools, itertools, random

pyrange = range
sqrt = sympy.sqrt if SYMPY else math.sqrt

def range(*a):
    if SYMPY:
        return list(map(sympy.Integer, pyrange(*a)))
    else:
        return list(pyrange(*a))

def try_eval(string):
    try:
        return ntype(eval(string))
    except:
        return list(string)

def force_list(obj):
    try:
        return list(obj)
    except:
        return [obj]

def range_list(obj):
    try:
        return list(obj)
    except:
        try:
            return range(1, 1 + int(obj))
        except:
            return [obj]

def ntype(var):
    if hasattr(var, "__iter__") and type(var) != str:
        return list(map(ntype, var))
    if not SYMPY:
        return var
    if isinstance(var, (bool, int, float)):
        return sympy.Rational(str(float(var)))
    if isinstance(var, complex):
        return sympy.Rational(var.real) + sympy.Rational(var.imag) * sympy.I
    return var

def depth(nobj):
    if isinstance(nobj, list):
        return max(map(depth, nobj)) + 1
    else:
        return 0

class Vectorizer:
    def __init__(self, max_level = -1, min_depth_left = 0, min_depth_right = 0, left = True, right = True):
        self.ml = max_level
        self.mdl = min_depth_left
        self.mdr = min_depth_right
        self.vl = left
        self.vr = right
    def __call__(self, arity):
        if arity == 0:
            return lambda f: f
        if arity == 1:
            def provider(f):
                def inner(a, t = 0):
                    if (t < self.ml or self.ml == -1) and depth(a) > self.mdl and self.vl:
                        return [inner(e, t + 1) for e in a]
                    else:
                        return f(a)
                return inner
            return provider
        if arity == 2:
            def provider(f):
                def inner(x, y, t = 0):
                    if (t < self.ml or self.ml == -1):
                        if depth(x) > self.mdl and self.mdr < depth(y) and self.vl and self.vr:
                            return [inner(i, j, t + 1) for i, j in zip(x, y)] + x[len(y):] + y[len(x):]
                        elif depth(x) > self.mdl and self.vl:
                            return [inner(e, y, t + 1) for e in x]
                        elif depth(y) > self.mdr and self.vr:
                            return [inner(x, e, t + 1) for e in y]
                    return f(x, y)
                return inner
            return provider

class Function:
    def __init__(self, arity, function, vectorizer = None, vectorize = 0):
        self.arity = arity
        self.function = vectorizer(self.arity)(function) if vectorizer else function
        self.vectorize = vectorize
    def __repr__(self):
        return "{Function(%s) %s}" % (["Nilad", "Monad", "Dyad"][self.arity], self.function)
    def __call__(self, larg = 0, rarg = 0):
        if self.arity == 0:
            return self.function()
        if self.arity == 1:
            if self.vectorize & 1 and isinstance(larg, list):
                return [self(l) for l in larg]
            else:
                return self.function(larg)
        if self.arity == 2:
            if self.vectorize == 3 and isinstance(larg, list) and isinstance(rarg, list):
                return [self(l, r) for l, r in zip(larg, rarg)] + larg[len(rarg):] + rarg[len(larg):]
            elif self.vectorize & 1 and isinstance(larg, list):
                return [self(l, rarg) for l in larg]
            elif self.vectorize & 2 and isinstance(rarg, list):
                return [self(larg, r) for r in rarg]
            else:
                return self.function(larg, rarg)

class Operator:
    def __init__(self, function):
        self.function = function
    def __repr__(self):
        return "{Operator %s}" % self.function
    def __call__(self, s):
        return self.function(s)

class NamedFunction:
    def __init__(self, name, function):
        self.name = name
        self.function = function
    def __repr__(self):
        return "{NamedFunction %s}" % self.name
    def __call__(self, *a, **k):
        return self.function(*a, **k)

class Attempts:
    def __init__(self, *functions):
        self.functions = functions
    def __call__(self, *a, **k):
        for function in self.functions:
            try:
                return function(*a, **k)
            except:
                pass
        raise RuntimeError("All attempts failed!")

identity = lambda x: x

def global_deduplicator(key = identity):
    def inner(array):
        output = []
        keyed = []
        for element in array:
            ke = key(element)
            if ke not in keyed:
                output.append(element)
                keyed.append(ke)
        return output
    return inner

def find(array, element):
    array = force_list(array)
    return (sympy.Integer if SYMPY else identity)(array.index(element) + 1 if element in array else 0)

def median(array):
    array = sorted(force_list(array))
    if len(array) % 2 == 0:
        return sum(array[len(array) // 2 - 1:][:2]) / 2
    else:
        return array[len(array) // 2]

def rotate(array, amount):
    return array[amount:] + array[:amount]

def flatten(array):
    if isinstance(array, list):
        return sum(map(flatten, array), [])
    else:
        return [array]

def from_base(digits, base):
    integer = 0
    for digit in digits:
        integer = base * integer + digit
    return integer

def to_base(integer, base, bijective = False):
    if integer == 0:
        return [0] * (not bijective)
    if bijective:
        base = abs(base)
    if base == 0:
        return [integer]
    if base == -1:
        digits = [1, 0] * abs(integer)
        return digits[:-1] if integer > 0 else digits
    sign = -1 if integer < 0 and base > 0 else 1
    integer *= sign
    if base == 1:
        return [sign] * integer
    digits = []
    while integer:
        integer -= bijective
        integer, digit = divmod(integer, base)
        digit += bijective
        if digit < 0:
            integer += 1
            digit -= base
        digits.append(sign * digit)
    return digits[::-1]

def shuffle(array):
    array = force_list(array)
    random.shuffle(array)
    return array

if SYMPY: GCD = sympy.gcd
else: from fractions import gcd as GCD

def LCM(x, y):
    return x * y / (GCD(x, y) or 1)

#  ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?
# @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂
# ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑªº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐
# └┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■

functions = {
    ' '  : None,
    '☺'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '☻'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♥'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♦'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♣'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♠'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '•'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '◘'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '○'  : Operator(function = NamedFunction(name = "<Outer Product Table>", function = lambda s: (lambda f: Function(arity = 2, function = NamedFunction(name = "<Outer Product Table of %s>" % f, function = lambda x, y: [[f(i, j) for i in force_list(x)] for j in force_list(y)])))(s.pop()))),
    '◙'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♂'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♀'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '♪'  : None,
    '♫'  : None,
    '☼'  : None,
    '►'  : None,
    '◄'  : None,
    '↕'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '‼'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '¶'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '§'  : Function(arity = 1, function = NamedFunction(name = "<Reversed>", function = lambda x: list(reversed(force_list(x))))),
    '▬'  : Function(arity = 2, function = NamedFunction(name = "<Set Difference>", function = lambda x, y: [e for e in force_list(x) if e not in force_list(y)])),
    '↨'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '↑'  : Function(arity = 1, function = NamedFunction(name = "<Sort Ascending>", function = lambda x: sorted(force_list(x))), vectorizer = Vectorizer(min_depth_left = 1)),
    '↓'  : Function(arity = 1, function = NamedFunction(name = "<Sort Descending>", function = lambda x: sorted(force_list(x), reverse = True)), vectorizer = Vectorizer(min_depth_left = 1)),
    '→'  : Operator(function = NamedFunction(name = "<Map Over Right>", function = lambda s: (lambda f: Function(arity = f.arity, function = NamedFunction(name = "<Map %s Over Right>" % f, function = lambda x, y: [f(x, e) for e in force_list(y)])))(s.pop()))),
    '←'  : Operator(function = NamedFunction(name = "<Map Over Left>", function = lambda s: (lambda f: Function(arity = f.arity, function = NamedFunction(name = "<Map %s Over Left>" % f, function = lambda *a: [f(e, *(a[1:])) for e in force_list(a[0])])))(s.pop()))),
    '∟'  : Function(arity = 2, function = NamedFunction(name = "<Vectorizing Inequality>", function = operator.ne), vectorize = 3),
    '↔'  : Operator(function = NamedFunction(name = "<Map Over Pairs>", function = lambda s: (lambda f: Function(arity = 1, function = NamedFunction(name = "<Map %s Over Pairs>" % f, function = lambda x: (lambda a: [f(q, r) for q, r in zip(a, a[1:])])(force_list(x)))))(s.pop()))),
    '▲'  : Function(arity = 1, function = NamedFunction(name = "<Increment>", function = Attempts(lambda x: x + 1, lambda x: chr(ord(x) + 1))), vectorize = 1),
    '▼'  : Function(arity = 1, function = NamedFunction(name = "<Decrement>", function = Attempts(lambda x: x - 1, lambda x: chr(ord(x) - 1))), vectorize = 1),
    ' '  : None,
    '!'  : Function(arity = 1, function = NamedFunction(name = "<Factorial/Gamma>", function = lambda x: (-1 if x < 0 else 1) * (math.factorial(abs(x)) if (isinstance(x, sympy.Integer) if SYMPY else x % 1 == 0) else type(x)(math.gamma(x + 1))))),
    '"'  : None,
    '#'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '$'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '%'  : Function(arity = 2, function = NamedFunction(name = "<Remainder>", function = operator.mod), vectorize = 3),
    '&'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    "'"  : None,
    '('  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    ')'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '*'  : Function(arity = 2, function = NamedFunction(name = "<Multiplication>", function = operator.mul), vectorize = 3),
    '+'  : Function(arity = 2, function = NamedFunction(name = "<Addition>", function = operator.add), vectorize = 3),
    ','  : Function(arity = 2, function = NamedFunction(name = "<Pair>", function = lambda x, y: (x, y))),
    '-'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '.'  : None,
    '/'  : Operator(function = NamedFunction(name = "<LTR Reduce>", function = lambda s: (lambda f: Function(arity = 1, function = NamedFunction(name = "<LTR Reduce over %s>" % f, function = lambda x: functools.reduce(f, force_list(x)))))(s.pop()))),
    '0'  : None,
    '1'  : None,
    '2'  : None,
    '3'  : None,
    '4'  : None,
    '5'  : None,
    '6'  : None,
    '7'  : None,
    '8'  : None,
    '9'  : None,
    ':'  : Function(arity = 2, function = NamedFunction(name = "<Floor Division>", function = operator.floordiv), vectorize = 3),
    ';'  : Function(arity = 2, function = NamedFunction(name = "<Concatenate>", function = lambda x, y: force_list(x) + force_list(y))),
    '<'  : Function(arity = 2, function = NamedFunction(name = "<Less Than>", function = operator.lt), vectorize = 3),
    '='  : Function(arity = 2, function = NamedFunction(name = "<Non-vectorizing Equality>", function = operator.eq)),
    '>'  : Function(arity = 2, function = NamedFunction(name = "<Greater Than>", function = operator.gt)),
    '?'  : Function(arity = 1, function = NamedFunction(name = "<Random>", function = lambda x: random.choice(range_list(x)))),
    '@'  : Operator(function = lambda s: (lambda f: Function(arity = 2, function = NamedFunction(name = "<Swap Arguments %s>" % f, function = lambda x, y: f(y, x))))(s.pop())),
    'A'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'B'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'C'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'D'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'E'  : Function(arity = 1, function = NamedFunction(name = "<All Equal>", function = lambda a: len(set(a)) == 1)),
    'F'  : Function(arity = 1, function = NamedFunction(name = "<Flatten>", function = flatten)),
    'G'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'H'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'I'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'J'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'K'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'L'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'M'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'N'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'O'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'P'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Q'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'R'  : Function(arity = 1, function = NamedFunction(name = "<Raised Range>", function = lambda x: range(1, 1 + int(x)))),
    'S'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'T'  : Function(arity = 1, function = NamedFunction(name = "<Transpose>", function = lambda x: list(map(list, zip(*map(force_list, force_list(x))))))),
    'U'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'V'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'W'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'X'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Y'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Z'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '['  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '\\' : Operator(function = NamedFunction(name = "<RTL Reduce>", function = lambda s: (lambda f: Function(arity = 1, function = NamedFunction(name = "<RTL Reduce over %s>" % f, function = lambda x: functools.reduce(f, force_list(x)[::-1]))))(s.pop()))),
    ']'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '^'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '_'  : Function(arity = 2, function = NamedFunction(name = "<Subtraction>", function = operator.sub), vectorize = 3),
    '`'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'a'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'b'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'c'  : Function(arity = 2, function = NamedFunction(name = "<Strict Subset>", function = lambda x, y: (sympy.Integer if SYMPY else identity)(int(all(e in force_list(y) for e in force_list(x)) and not all(e in force_list(x) for e in force_list(y)))))),
    'd'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'e'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'f'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'g'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'h'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'i'  : Function(arity = 2, function = NamedFunction(name = "<First Index of Element>", function = lambda x, y: find(x, y)), vectorize = 2),
    'j'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'k'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'l'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'm'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'n'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'o'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'p'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'q'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'r'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    's'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'u'  : Function(arity = 2, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    't'  : Function(arity = 0, function = NamedFunction(name = "<Set Union>", function = lambda x, y: force_list(x) + [e for e in force_list(y) if e not in force_list(x)])),
    'v'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'w'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'x'  : Function(arity = 1, function = NamedFunction(name = "<Signum>", function = lambda x: 1 if x > 0 else 0 if x == 0 else -1), vectorize = 1),
    'y'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'z'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '{'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '|'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '}'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '~'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '⌂'  : None,
    'Ç'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ü'  : Function(arity = 1, function = NamedFunction(name = "<Global Deduplicate>", function = global_deduplicator())),
    'é'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'â'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ä'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'à'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'å'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ç'  : Function(arity = 2, function = NamedFunction(name = "<Subset>", function = lambda x, y: (sympy.Integer if SYMPY else identity)(int(all(e in force_list(y) for e in force_list(x)))))),
    'ê'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ë'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'è'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ï'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'î'  : None,
    'ì'  : None,
    'Ä'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Å'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'É'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'æ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Æ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ô'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ö'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ò'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'û'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ù'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ÿ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Ö'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Ü'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '¢'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '£'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '¥'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '₧'  : Function(arity = 1, function = NamedFunction(name = "<Python Evaluate>", function = lambda x: ntype(eval("".join(map(str, flatten(x))))))),
    'ƒ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'á'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'í'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ó'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ú'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ñ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Ñ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ª'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'º'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '¿'  : Function(arity = 1, function = NamedFunction(name = "<Shuffle>", function = shuffle)),
    '⌐'  : Function(arity = 2, function = NamedFunction(name = "<Non-vectorizing Inequality>", function = operator.ne)),
    '¬'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '½'  : Function(arity = 1, function = NamedFunction(name = "<Halve>", function = lambda x: x / 2), vectorize = 1),
    '¼'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '¡'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '«'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '»'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '░'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▒'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▓'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '│'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '┤'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╡'  : Function(arity = 2, function = NamedFunction(name = "<Left Argument>", function = lambda x, y: x)),
    '╢'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╖'  : Function(arity = 1, function = NamedFunction(name = "<Dequeue>", function = lambda x: force_list(x)[1:])),
    '╕'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╣'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '║'  : Function(arity = 1, function = NamedFunction(name = "<Magnitude>", function = lambda x: sqrt(sum(e * e for e in force_list(x)))), vectorizer = Vectorizer(min_depth_left = 1)),
    '╗'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╝'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╜'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╛'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '┐'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '└'  : Function(arity = 1, function = NamedFunction(name = "<Floor>", function = math.floor), vectorize = 1),
    '┴'  : Function(arity = 2, function = NamedFunction(name = "<Convert From Base>", function = from_base), vectorizer = Vectorizer(min_depth_left = 1, min_depth_right = 0)),
    '┬'  : Function(arity = 2, function = NamedFunction(name = "<Convert To Base>", function = to_base), vectorize = 3),
    '├'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '─'  : Function(arity = 2, function = NamedFunction(name = "<Inclusive Range>", function = lambda x, y: range(math.ceil(x), 1 + math.floor(y)) if y > x else range(math.floor(x), math.ceil(y) - 1, -1)), vectorize = 3),
    '┼'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╞'  : Function(arity = 2, function = NamedFunction(name = "<Get Right Argument>", function = lambda x, y: y)),
    '╟'  : Function(arity = 1, function = NamedFunction(name = "<Mean>", function = lambda x: sum(force_list(x)) / len(force_list(x))), vectorizer = Vectorizer(min_depth_left = 1)),
    '╚'  : Function(arity = 1, function = NamedFunction(name = "<Minimum>", function = lambda x: min(force_list(x))), vectorizer = Vectorizer(min_depth_left = 1)),
    '╔'  : Function(arity = 1, function = NamedFunction(name = "<Maximum>", function = lambda x: max(force_list(x))), vectorizer = Vectorizer(min_depth_left = 1)),
    '╩'  : Function(arity = 2, function = NamedFunction(name = "<LCM>", function = LCM)),
    '╦'  : Function(arity = 2, function = NamedFunction(name = "<GCD>", function = GCD)),
    '╠'  : Function(arity = 1, function = NamedFunction(name = "<Median>", function = median)),
    '═'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╬'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╧'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╨'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╤'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╥'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╙'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╘'  : Function(arity = 2, function = NamedFunction(name = "<Logarithm>", function = sympy.log if SYMPY else math.log), vectorize = 3),
    '╒'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╓'  : Function(arity = 1, function = NamedFunction(name = "<Pop>", function = lambda x: force_list(x)[:-1])),
    '╫'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '╪'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '┘'  : Function(arity = 2, function = NamedFunction(name = "<General Root>", function = lambda x, y: x ** (1 / y)), vectorize = 3),
    '┌'  : Function(arity = 1, function = NamedFunction(name = "<Ceiling>", function = math.ceil), vectorize = 1),
    '█'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▄'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▌'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▐'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '▀'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'α'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'ß'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Γ'  : Function(arity = 1, function = NamedFunction(name = "<Product>", function = lambda x: functools.reduce(Vectorizer()(2)(operator.mul), x))),
    'π'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Σ'  : Function(arity = 1, function = NamedFunction(name = "<Sum>", function = sum)),
    'σ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'µ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'τ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Φ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'Θ'  : Function(arity = 2, function = NamedFunction(name = "<Set Symmetric Difference>", function = lambda x, y: [e for e in force_list(x) if e not in force_list(y)] + [e for e in force_list(y) if e not in force_list(x)])),
    'Ω'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'δ'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '∞'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    'φ'  : Function(arity = 2, function = NamedFunction(name = "<Rotate>", function = lambda x, y: rotate(force_list(x), y)), vectorize = 2),
    'ε'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '∩'  : Function(arity = 2, function = NamedFunction(name = "<Set Intersection>", function = lambda x, y: [e for e in force_list(x) if e in force_list(y)])),
    '≡'  : Function(arity = 2, function = NamedFunction(name = "<Vectorizing Equality>", function = operator.eq), vectorize = 3),
    '±'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '≥'  : Function(arity = 2, function = NamedFunction(name = "<Greater Than/Equal>", function = operator.ge), vectorize = 3),
    '≤'  : Function(arity = 2, function = NamedFunction(name = "<Less Than/Equal>", function = operator.le), vectorize = 3),
    '⌠'  : None,
    '⌡'  : None,
    '÷'  : Function(arity = 2, function = NamedFunction(name = "<Division>", function = operator.truediv), vectorize = 3),
    '≈'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '°'  : Function(arity = 0, function = NamedFunction(name = "<TODO>", function = lambda: 0)),
    '∙'  : None,
    '·'  : Function(arity = 2, function = NamedFunction(name = "<Dot Product>", function = lambda x, y: sum(i * j for i, j in zip(force_list(x), force_list(y)))), vectorizer = Vectorizer(min_depth_left = 1, min_depth_right = 1)),
    '√'  : Function(arity = 1, function = NamedFunction(name = "<Square Root>", function = sqrt), vectorize = 3),
    'ⁿ'  : Function(arity = 2, function = NamedFunction(name = "<Exponentiation>", function = operator.pow), vectorize = 3),
    '²'  : Function(arity = 1, function = NamedFunction(name = "<Square>", function = lambda x: x * x), vectorize = 1),
    '■'  : Function(arity = 1, function = NamedFunction(name = "<Double>", function = lambda x: x * 2), vectorize = 1),
    ' '  : None,
}

overloads = "♪♫☼∙⌂"

def to_i(text):
    if text.startswith("-"):
        return "-" + to_i(text[1:])
    elif text == "":
        return "sympy.Integer(1)" if SYMPY else "1"
    else:
        return "sympy.Integer(" * SYMPY + repr(text) + ")" * SYMPY

def to_r(text):
    if text.startswith("-"):
        return "-" + to_r(text[1:])
    else:
        left, right = text.split(".")
        return "sympy.Rational(" * SYMPY + repr((left or "0") + "." + (right or "5")) + ")" * SYMPY

def to_n(text):
    if "ì" in text:
        left, right = text.split("ì", 1)
        return to_n(left or "0") + "+sympy.I*" + to_n(right or "1") if SYMPY else to_n(left or "0") + "+" + to_n(right or "1") + "j"
    elif "î" in text:
        left, right = text.split("î", 1)
        return to_n(left or "1") + "*10**" + to_n(right or "3")
    elif "." in text:
        return to_r(text)
    else:
        return to_i(text)

#  ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?
# @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂
# ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑªº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐
# └┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■

dgts = r"(?:[1-9][0-9]*)"
intg = r"(0|-?{d}|-)".format(d = dgts)
real = r"(-?{d}?\.[0-9]*)".format(d = dgts)
expn = r"{n}?î{n}?".format(n = "({r}|{i})".format(r = real, i = intg))
cmpx = r"{n}?ì{n}?".format(n = "({e}|{r}|{i})".format(e = expn, r = real, i = intg))
numr = "(" + "|".join([cmpx, expn, real, intg]) + ")"
slst = r"(\"(([^\"'«»⌐]|\\.)*))+('|«|»|⌐)"
char = r"'(.)"
litr = "(" + "|".join([char, slst, numr]) + ")"
ntrn = r"\[*" + litr + r"?(?:(?:\]*,\[*)" + litr + ")*" + r"\]*"
func = "(" + "|".join(map(re.escape, [f for f in functions if functions[f] is not None])) + ")"
spec = "(" + "|".join(map(re.escape, overloads)) + ")"
pyfn = "⌠.+?[☼♪♫⌡]"

def str_eval(type):
    type = "'«»⌐".index(type)
    if type == 0:
        return lambda code: list(eval('"""%s"""' % code))
    if type == 1:
        return lambda code: list(map(codepage.index, eval('"""%s"""' % code.replace('"', '\\"'))))
    if type == 2:
        return lambda code: (lambda str: "("+"+".join("sympy.Integer("*SYMPY+"250"+")"*SYMPY+"**"+str(len(str)-index-1)+"*"+"sympy.Integer("*SYMPY+repr(codepage.index(char)+1)+")"*SYMPY for index, char in enumerate(str))+")")(eval('"""%s"""' % code.replace('"', '\\"')))

def evalyank(code):
    match = re.match(char, code)
    if match:
        return (match.group(), repr(match.group()[1]))
    match = re.match(slst, code)
    if match:
        return (match.group(), repr(list(map(str_eval(match.group()[-1]), re.split(r"(?<!\\)\"", match.group()[1:-1])))))
    match = re.match(numr, code)
    if match:
        return (match.group(), to_n(match.group()))

def ntrneval(code):
    raw = ""
    while code:
        yanked = evalyank(code)
        if yanked:
            raw += yanked[1] + " "
            code = code[len(yanked[0]):]
        else:
            raw += code[0]
            code = code[1:]
    return ntype(eval(raw))

def ntrnevalmatcher(match):
    value = ntrneval(match.group())
    return Function(arity = 0, function = NamedFunction(name = "<Literal Value>", function = (lambda v: lambda: v)(value)))

matchers = [(m[0], re.compile(m[1]), m[2]) for m in [
    ("ntrn", ntrn, ntrnevalmatcher),
    ("func", func, lambda m: functions[m.group()]),
    ("spec", spec, lambda m: (-2, m.group())),
    ("pyfn", pyfn, lambda m: Function(arity = "☼♪♫".find(m.group()[-1]), function = NamedFunction(name = "<Native Python Function>", function = (lambda s: lambda x=0, y=0: eval(s, {"x": x, "y": y}))(m.group()[1:-1]))) if m.group()[-1] in "☼♪♫" else Function(arity = 0, function = (lambda v: lambda: v)(eval(m.group()[1:-1])))),
]]

def tokenize(code):
    code = "".join(char for char in code.replace("\n", "¶") if char in codepage)
    tokens = []
    while code:
        tokens = tokens or [[]]
        if code[0] == "¶": tokens.append([]); code = code[1:]; continue
        for matcher in matchers:
            token = matcher[1].match(code)
            if token:
                try:
                    tokens[-1].append(matcher[2](token))
                    code = code[len(token.group()):]
                    break
                except:
                    pass
        else:
            code = code[1:]
    return tokens

brackets = "☼∙♪∙♫∙"

def parse(tokens):
    result = []
    index = 0
    while index < len(tokens):
        if type(tokens[index]) == tuple and tokens[index][0] == -2 and brackets.find(tokens[index][1]) & 1 == 0:
            start = tokens[index][1]
            inner = []
            bcount = 1
            index += 1
            while bcount:
                if type(tokens[index]) == tuple and tokens[index][0] == -2 and tokens[index][1] in brackets:
                    if brackets.find(tokens[index][1]) & 1 == 1:
                        bcount -= 1
                        if not bcount: index += 1; break
                    else:
                        bcount += 1
                inner.append(tokens[index])
                index += 1
            result.append(Function(arity = brackets.find(start) >> 1, function = parse(inner)))
        else:
            result.append(tokens[index])
            index += 1
    return result

def preexecute(tokens):
    func_stack = []
    for token in tokens:
        if isinstance(token, Function):
            if isinstance(token.function, list):
                func_stack.append(Function(arity = token.arity, function = preexecute(token.function)))
            else:
                func_stack.append(token)
        elif isinstance(token, Operator):
            func_stack.append(token(func_stack))
        else:
            pass
            # TODO do something to make metaoperators/functions work
    return func_stack

class Evaluator:
    def __init__(self, function):
        self.function = function
    def __call__(self, tokens, *args, **kwargs):
        if isinstance(tokens, list): return self.function(tokens[:], *args, **kwargs)
        else: return self.function([tokens], *args, **kwargs)

@Evaluator
def nileval(tokens, layer = 0, nest = False, links = [], index = -1):
    if tokens:
        if tokens[0].arity == 0:
            if isinstance(tokens[0].function, list):
                value = nileval(tokens.pop(0).function, layer = layer + 1, nest = True)
            else:
                value = tokens.pop(0)()
        elif tokens[0].arity == -2:
            value = 0
        else:
            value = 0
    else:
        value = 0
    return moneval(tokens, value, layer = layer)

@Evaluator
def moneval(tokens, argument, layer = 0, nest = False, links = [], index = -1):
    if nest and tokens and not any(token.arity for token in tokens):
        values = [nileval([token], layer = layer + 1, nest = False) for token in tokens]
        if argument in values: return values[(values.index(argument) + 1) % len(values)]
        return argument
    if tokens and tokens[0].arity == 0:
        value = nileval(tokens.pop(0), layer = layer)
    else:
        value = None
    while tokens:
        v = argument if value is None else value
        if len(tokens) >= 3 and tokens[0].arity == tokens[1].arity == 2 and tokens[2].arity == 0:
            value = dydeval(tokens.pop(1), dydeval(tokens.pop(0), v, argument, layer), nileval(tokens.pop(0), layer), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == 2 and tokens[1].arity == 1:
            value = dydeval(tokens.pop(0), v, tokens.pop(0)(argument), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == 2 and tokens[1].arity == 0:
            value = dydeval(tokens.pop(0), v, nileval(tokens.pop(0), layer = layer), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == 0 and tokens[1].arity == 2:
            value = dydeval(tokens.pop(1), nileval(tokens.pop(0), layer = layer), v, layer = layer)
        elif tokens[0].arity == 2:
            if isinstance(tokens[0].function, list):
                value = dydeval(tokens.pop(0), v, argument, layer = layer + 1, nest = True)
            else:
                value = tokens.pop(0)(v, argument)
        elif tokens[0].arity == 1:
            if isinstance(tokens[0].function, list):
                value = moneval(tokens.pop(0).function, v, layer = layer + 1, nest = True)
            else:
                value = tokens.pop(0)(v)
        else:
            if value is not None:
                print(value, end = "")
            value = nileval(tokens.pop(0), layer = layer)
    return argument if value is None else value

@Evaluator
def dydeval(tokens, left, right, layer = 0, nest = False, links = [], index = -1):
    if len(tokens) >= 3 and tokens[0].arity == tokens[1].arity == tokens[2].arity == 2:
        if isinstance(tokens[0].function, list):
            value = dydeval(tokens.pop(0).function, left, right, layer = layer + 1, nest = True)
        else:
            value = tokens.pop(0)(left, right)
    elif tokens and tokens[0] == 0:
        value = nileval(tokens.pop(0), layer = layer)
    else:
        value = None
    while tokens:
        v = left if value is None else value
        if len(tokens) >= 3 and tokens[0].arity == tokens[1].arity == 2 and tokens[2].arity == 0:
            value = dydeval(tokens.pop(1), dydeval(tokens.pop(0), v, right, layer = layer), nileval(tokens.pop(0), layer = layer), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == tokens[1].arity == 2:
            value = dydeval(tokens.pop(0), v, dydeval(tokens.pop(0), left, right, layer = layer), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == 2 and tokens[1].arity == 0:
            value = dydeval(tokens.pop(0), v, nileval(tokens.pop(0), layer = layer), layer = layer)
        elif len(tokens) >= 2 and tokens[0].arity == 0 and tokens[1].arity == 2:
            value = dydeval(tokens.pop(1), nileval(tokens.pop(0), layer = layer), v, layer = layer)
        elif tokens[0].arity == 2:
            if isinstance(tokens[0].function, list):
                value = dydeval(tokens.pop(0).function, v, right, layer = layer + 1, nest = True)
            else:
                value = tokens.pop(0)(v, right)
        elif tokens[0].arity == 1:
            if isinstance(tokens[0].function, list):
                value = moneval(tokens.pop(0).function, v, layer = layer + 1, nest = True)
            else:
                value = tokens.pop(0)(v)
        else:
            if value is not None:
                neutrino_output(value, "")
            value = nileval(tokens.pop(0), layer = layer)
    return left if value is None else value

def evaluate(links, arguments):
    links = links or [[]]
    link = links[-1]
    if len(arguments) >= 1:
        functions["┤"] = Function(arity = 0, function = NamedFunction(name = "<Left Argument Nilad>", function = (lambda v: lambda: v)(arguments[0])))
    if len(arguments) >= 2:
        functions["├"] = Function(arity = 0, function = NamedFunction(name = "<Right Argument Nilad>", function = (lambda v: lambda: v)(arguments[1])))
    # TODO other argument getters
    if len(arguments) >= 2:
        return dydeval(link, arguments[0], arguments[1], links = links, index = len(links) - 1)
    elif len(arguments) == 1:
        return moneval(link, arguments[0], links = links, index = len(links) - 1)
    else:
        return nileval(link, links = links, index = len(links) - 1)

def neutrino_eval(code, arguments):
    return evaluate(list(map(preexecute, map(parse, tokenize(code)))), arguments)

def stringify(iterable, recurse = True):
    if type(iterable) != list:
         return 1 if iterable is True else 0 if iterable is False else iterable
    if len(iterable) == 1:
         return stringify(iterable[0])
    if str in map(type, iterable) and not list in map(type, iterable) or not iterable:
        return "".join(map(str, iterable))
    iterable = [stringify(item) for item in iterable]
    return stringify(iterable, False) if recurse else iterable

def unicode_to_neutrino(string):
    return "".join(chr(codepage.find(char)) for char in str(string).replace("\n", "¶") if char in codepage)

def neutrino_output(argument, end = "\n", transform = stringify):
    if argument is None: return
    if locale.getdefaultlocale()[1][:3] == "UTF":
        print(transform(argument), end = end)
    else:
        print(unicode_to_neutrino(transform(argument)), end = unicode_to_neutrino(end))
    sys.stdout.flush()
    return argument

test_cases = [

]

if __name__ == "__main__":
    if TEST:
        for test_case in test_cases:
            args = list(map(try_eval, test_case[1:-1][:6]))
            for i, e in enumerate(args):
                functions["☺☻♥♦♣♠"[i]] = Function(arity = 0, function = NamedFunction(name = "<Argument %d Nilad>" % i, function = (lambda v: lambda: v)(e)))
            output = str(neutrino_eval(test_case[0], args))
            if output == test_case[-1]:
                print("Test Case Passed: ⌠%s⌡(%s) := ⌠%s⌡" % (test_case[0], " ; ".join(test_case[1:-1][:6]), output))
            else:
                print("Test Case Failed: ⌠%s⌡(%s) := ⌠%s⌡ but was ⌠%s⌡" % (test_case[0], " ; ".join(test_case[1:-1][:6]), test_case[-1], output))
    else:
        args = list(map(try_eval, pr_args[:6]))
        for i, e in enumerate(args):
            functions["☺☻♥♦♣♠"[i]] = Function(arity = 0, function = NamedFunction(name = "<Argument %d Nilad>" % i, function = (lambda v: lambda: v)(e)))
        code = open(sys.argv[1], "rb").read()
        if UTF_8:
            code = "".join(char for char in code.decode("utf-8").replace("\n", "¶") if char in codepage)
        else:
            code = "".join(codepage[i] for i in code)
        neutrino_output(neutrino_eval(code, args))
