Пример #1
0
def import_file(env):
    def extract_string(cap_string):
        if cap_string.__class__ is not strtools.CapString:
            throw_exception('ExpectedString',
                            '{0} is not a string'.format(cap_string))
        return cap_string.contents

    def read_entire_text_file(filename):
        filename = extract_string(filename)
        with open(filename, 'r') as file_obj:
            return strtools.CapString(file_obj.read())

    def write_entire_text_file(filename, contents):
        filename = extract_string(filename)
        contents = extract_string(contents)
        with open(filename, 'w') as file_obj:
            file_obj.write(contents)

    env.assign(
        'readEntireTextFile',
        builtin_function.BuiltinFunction('readEntireTextFile', ['filename'],
                                         read_entire_text_file))
    env.assign(
        'writeEntireTextFile',
        builtin_function.BuiltinFunction('writeEntireTextFile',
                                         ['filename', 'contents'],
                                         write_entire_text_file))
Пример #2
0
def table_methods(obj, name, env):
    if name == 'length' or name == 'size':
        return builtin_function.BuiltinFunction('constant', [], lambda: len(obj))
    elif name == 'keys':
        return builtin_function.BuiltinFunction('constant', [], lambda: obj.keys())
    elif name == 'hasKey':
        return builtin_function.BuiltinFunction('hasKey', ['key'], lambda key: obj.has_key(key))
    return None
Пример #3
0
def import_pretty_print(env):
    env.assign(
        'prettyFormat',
        builtin_function.BuiltinFunction('prettyFormat', ['obj'],
                                         pretty_print.pretty_format_wrapper))
    env.assign(
        'prettyPrint',
        builtin_function.BuiltinFunction('prettyPrint', ['obj'],
                                         pretty_print.pretty_print))
Пример #4
0
def import_debugging(env):
    env.assign(
        'getFrames',
        builtin_function.BuiltinFunction('getFrames', [], lambda: env.frames))
    env.assign(
        'getThisFrames',
        builtin_function.BuiltinFunction('getThisFrames', [],
                                         lambda: env.this_pointers))
    env.assign(
        'repl',
        builtin_function.BuiltinFunction('repl', [],
                                         lambda: capacita.repl(env)))
Пример #5
0
def str_methods(obj, name, env):
    if name == 'length' or name == 'size':
        # Strings are immutable, so only call len() once
        length = len(obj)
        return builtin_function.BuiltinFunction('constant', [], lambda: length)
    elif name == 'ord' or name == 'charNum':
        def char_num(string):
            if len(string) == 0:
                throw_exception(
                    'StringEmpty',
                    'Cannot convert first character to integer when string is empty'
                )
            return ord(string[0])
        return builtin_function.BuiltinFunction('charNum', [], lambda: char_num(obj))
    elif name == 'charAt':
        return builtin_function.BuiltinFunction('charAt', ['i'], lambda i: strtools.index_string(obj, i))
    elif name == 'insertAt':
        def insert_at(index, substr):
            strtools.validate_string_index(obj, index)
            return strtools.CapString(obj.contents[0:index] + substr.contents + obj.contents[index:], False)
        return builtin_function.BuiltinFunction('insertAt', ['index', 'substr'], insert_at)
    elif name == '$internals':
        # View internals of a string, for debugging purposes.
        print(repr(obj))
        return builtin_function.BuiltinFunction('constant', [], lambda: None)
    elif name == 'slice':
        def slice_string(start, stop=None):
            strtools.validate_string_index(obj, start)
            if stop is not None:
                strtools.validate_string_index(obj, stop)
                return strtools.CapString(obj.contents[start:stop], False)
            else:
                return strtools.CapString(obj.contents[start:], False)
        return builtin_function.BuiltinFunction('slice', ['start', 'stop?'], slice_string)
    elif name == 'replaceSlice':
        def replace_slice(start, stop, substr):
            strtools.validate_string_index(obj, start)
            strtools.validate_string_index(obj, stop)
            return strtools.CapString(obj.contents[0:start] + substr.contents + obj.contents[stop:])
        return builtin_function.BuiltinFunction('replaceSlice', ['start', 'stop', 'substr'], replace_slice)
    contents = obj.contents
    if name == 'split':
        def split_string(separator=None):
            if separator is None:
                return [strtools.CapString(elem, False) for elem in contents.split()]
            else:
                separator = separator.contents
                return [strtools.CapString(elem, False) for elem in contents.split(separator)]
        return builtin_function.BuiltinFunction('split', ['separator?'], split_string)
    elif name == 'find':
        def find_in_string(string, substr):
            result = string.find(substr)
            if result == -1:
                return None
            return result
        return builtin_function.BuiltinFunction('find', ['substring'], lambda s: find_in_string(contents, s.contents))
    return None
Пример #6
0
def import_data_structures(env):
    def list_range(start, stop, step=1):
        return range(start, stop + 1, step)

    env.assign(
        'ListRange',
        builtin_function.BuiltinFunction('ListRange',
                                         ['start', 'stop', 'step?'],
                                         list_range))
Пример #7
0
    def curry(f):
        num_args = f.get_num_args()
        if num_args <= 1:
            return f
        else:

            def curried_f(x):
                partially_applied_f = partial(f, [x])
                return curry(partially_applied_f)

            return builtin_function.BuiltinFunction('g', ['x'], curried_f)
Пример #8
0
def import_random(env):
    def throw_select_on_empty_list():
        throw_exception('SelectOnEmptyList',
                        "Can't select item from empty list")

    def select(lst):
        if len(lst) == 0:
            throw_select_on_empty_list()
        return random.sample(lst, 1)[0]

    def select_and_remove(lst):
        if len(lst) == 0:
            throw_select_on_empty_list()
        index = random.randint(0, len(lst) - 1)
        return lst.pop(index)

    def shuffle_and_return(lst):
        random.shuffle(lst)
        return lst

    env.assign(
        'randInt',
        builtin_function.BuiltinFunction('randInt', ['a', 'b'],
                                         random.randint))
    env.assign(
        'randDouble',
        builtin_function.BuiltinFunction('randDouble', [], random.random))
    env.assign(
        'shuffle',
        builtin_function.BuiltinFunction('shuffle', ['lst'],
                                         shuffle_and_return))
    env.assign('select',
               builtin_function.BuiltinFunction('select', ['lst'], select))
    env.assign(
        'selectAndRemove',
        builtin_function.BuiltinFunction('selectAndRemove', ['lst'],
                                         select_and_remove))
Пример #9
0
    def partial(f, fixed_args):
        num_original_args = f.get_num_args()
        num_fixed_args = len(fixed_args)
        num_args_needed = num_original_args - num_fixed_args
        if num_args_needed < 0:
            throw_exception(
                'TooManyFixedArguments',
                'Function {0} requires {1} arguments, but passing in {2}'.
                format(f.name, num_original_args, num_fixed_args))
        arg_names = ['x' + str(i) for i in xrange(num_args_needed)]

        def partially_applied_f(*args):
            return f.execute(fixed_args + list(args), env)

        return builtin_function.BuiltinFunction('fPrime', arg_names,
                                                partially_applied_f)
Пример #10
0
def number_methods(obj, name, env):
    if name == 'next':
        return builtin_function.BuiltinFunction('constant', [], lambda: obj + 1)
    elif name == 'previous':
        return builtin_function.BuiltinFunction('constant', [], lambda: obj - 1)
    if type(obj) in [int, long]:
        if name == 'toChar':
            return builtin_function.BuiltinFunction('toChar', [], lambda: strtools.CapString(chr(obj), False))
        elif name == 'bitNot':
            return builtin_function.BuiltinFunction('bitNot', [], lambda: ~obj)
        elif name == 'bitAnd':
            return builtin_function.BuiltinFunction('bitAnd', ['n'], lambda n: obj & n)
        elif name == 'bitOr':
            return builtin_function.BuiltinFunction('bitOr', ['n'], lambda n: obj | n)
        elif name == 'bitXor':
            return builtin_function.BuiltinFunction('bitXor', ['n'], lambda n: obj ^ n)
        elif name == 'bitNand':
            return builtin_function.BuiltinFunction('bitNand', ['n'], lambda n: ~(obj & n))
        elif name == 'bitNor':
            return builtin_function.BuiltinFunction('bitNor', ['n'], lambda n: ~(obj | n))
        elif name == 'bitXnor':
            return builtin_function.BuiltinFunction('bitXnor', ['n'], lambda n: ~(obj ^ n))
        elif name == 'toBin':
            # The bin function will add '0b' to the beginning of the binary string, which should be removed
            return builtin_function.BuiltinFunction('toBin', [],
                                                    lambda: strtools.CapString(remove_radix_prefix(bin(obj)), False))
        elif name == 'toHex':
            # The hex function will add '0x' to the beginning of the hexadecimal string, which should be removed
            return builtin_function.BuiltinFunction('toHex', [],
                                                    lambda: strtools.CapString(remove_radix_prefix(hex(obj)), False))
        elif name == 'toUnsignedBits':
            return builtin_function.BuiltinFunction('toUnsignedBits', [],
                                                    lambda: strtools.CapString(to_unsigned_bits(obj), False))
        elif name == 'getBit':
            return builtin_function.BuiltinFunction('getBit', ['i'], lambda i: (obj & (1 << i)) >> i)
        elif name == 'setBit':
            return builtin_function.BuiltinFunction('setBit', ['i'], lambda i: obj | (1 << i))
        elif name == 'resetBit':
            return builtin_function.BuiltinFunction('resetBit', ['i'], lambda i: obj & ~(1 << i))
        elif name == 'toggleBit':
            return builtin_function.BuiltinFunction('toggleBit', ['i'], lambda i: obj ^ (1 << i))
        elif name == 'toBase':
            return builtin_function.BuiltinFunction('toBase', ['base'],
                                                    lambda base: strtools.CapString(to_base(obj, base), False))
        elif name == 'getDigit':
            return builtin_function.BuiltinFunction('getDigit', ['index', 'base?'],
                                                    lambda index, base=10: get_digit(obj, index, base))
        elif name == 'setDigit':
            return builtin_function.BuiltinFunction('setDigit', ['index', 'newDigit', 'base?'],
                                                    lambda index, new_digit, base=10: set_digit(obj, index, base, new_digit))
        elif name == 'shiftLeft':
            return builtin_function.BuiltinFunction('shiftLeft', ['numDigits', 'base?'],
                                                    lambda num_digits, base=2: shift_left(obj, num_digits, base))
        elif name == 'shiftRight':
            return builtin_function.BuiltinFunction('shiftRight', ['numDigits', 'base?'],
                                                    lambda num_digits, base=2: shift_right(obj, num_digits, base))
    return None
Пример #11
0
def import_math(env):
    def binomial_choose(n, k):
        if k < 0 or k > n:
            return 0
        result = 1
        for i in xrange(1, min(k, n - k) + 1):
            # Do not use
            # result *= (n + 1 - i) / i
            # since dividing by i before multiplying
            # by result may have rounding errors
            result = (result * (n + 1 - i)) / i
        return result

    def fib(n):
        # Use the matrix form of Fibonacci numbers
        # to perform the computation in O(log(n)) operations.
        # Please see the Wikipedia page on Fibonacci numbers
        # for more information.
        if n == 0 or n == 1:
            return n

        def is_odd(n):
            return (n & 1) == 1

        if is_odd(n):
            k = (n + 1) / 2
            return fib(k)**2 + fib(k - 1)**2
        else:
            k = n / 2
            fib_k = fib(k)
            return 2 * fib(k - 1) * fib_k + fib_k**2

    def differentiate(f, dx=1e-6):
        def f_prime(x):
            df = f.execute([x + dx], env) - f.execute([x], env)
            return df / dx

        return builtin_function.BuiltinFunction('fPrime', ['x'], f_prime)

    def integrate(f, a, b, num_rectangles=1000):
        if b < a:
            return -integrate(f, b, a, num_rectangles)
        current_sum = 0
        dx = (b - a) / float(num_rectangles)
        while a < b:
            current_sum += f.execute([a], env) * dx
            a += dx
        return current_sum

    env.assign('pi', math.pi)
    env.assign('e', math.e)
    env.assign('phi', 1.6180339887498948482)
    env.assign('infinity', float('inf'))
    env.assign('negativeInfinity', -float('inf'))
    env.assign('nan', float('nan'))
    env.assign('sqrt',
               builtin_function.BuiltinFunction('sqrt', ['x'], math.sqrt))
    env.assign(
        'cbrt',
        builtin_function.BuiltinFunction('cbrt', ['x'],
                                         lambda x: x**0.3333333333333333333))
    env.assign(
        'log',
        builtin_function.BuiltinFunction('log', ['x', 'b'],
                                         lambda x, b: math.log(x, b)))
    env.assign(
        'ln',
        builtin_function.BuiltinFunction('ln', ['x'], lambda x: math.log(x)))
    env.assign(
        'binomialChoose',
        builtin_function.BuiltinFunction('binomialChoose', ['n', 'k'],
                                         binomial_choose))
    env.assign('fib', builtin_function.BuiltinFunction('fib', ['n'], fib))
    env.assign(
        'factorial',
        builtin_function.BuiltinFunction('factorial', ['n'], math.factorial))
    env.assign(
        'differentiate',
        builtin_function.BuiltinFunction('differentiate', ['f', 'epsilon?'],
                                         differentiate))
    env.assign('min',
               builtin_function.BuiltinFunction('min', ['n', '[args]'], min))
    env.assign('max',
               builtin_function.BuiltinFunction('max', ['n', '[args]'], max))
    env.assign(
        'integrate',
        builtin_function.BuiltinFunction('integrate',
                                         ['f', 'a', 'b', 'numRectangles?'],
                                         integrate))
    env.assign('sin', builtin_function.BuiltinFunction('sin', ['x'], math.sin))
    env.assign('cos', builtin_function.BuiltinFunction('cos', ['x'], math.cos))
    env.assign('atan',
               builtin_function.BuiltinFunction('atan', ['x'], math.atan))
    env.assign(
        'atan2',
        builtin_function.BuiltinFunction('atan2', ['y', 'x'], math.atan2))
Пример #12
0
    def compose(f, g):
        def h(x):
            return f.execute([g.execute([x], env)], env)

        return builtin_function.BuiltinFunction('h', ['x'], h)
Пример #13
0
def import_functional(env):
    def compose(f, g):
        def h(x):
            return f.execute([g.execute([x], env)], env)

        return builtin_function.BuiltinFunction('h', ['x'], h)

    def map_prime(f, lst):
        return map(lambda x: f.execute([x], env), lst)

    def filter_prime(predicate, lst):
        return filter(lambda x: predicate.execute([x], env), lst)

    def flip(f):
        return builtin_function.BuiltinFunction(
            'g', ['x', 'y'], lambda x, y: f.execute([y, x], env))

    def fold_left(f, lst):
        if len(lst) < 2:
            return lst[0]
        result = f.execute(lst[:2], env)
        lst = lst[2:]
        for elem in lst:
            result = f.execute([result, elem], env)
        return result

    def fold_right(f, lst):
        if len(lst) < 2:
            return lst[0]
        result = f.execute(lst[-2:], env)
        lst = lst[:-2]
        for elem in reversed(lst):
            result = f.execute([elem, result], env)
        return result

    def any_prime(f, lst):
        for elem in lst:
            result = f.execute([elem], env)
            if result:
                return True
        return False

    def all_prime(f, lst):
        for elem in lst:
            result = f.execute([elem], env)
            if not result:
                return False
        return True

    def curry(f):
        num_args = f.get_num_args()
        if num_args <= 1:
            return f
        else:

            def curried_f(x):
                partially_applied_f = partial(f, [x])
                return curry(partially_applied_f)

            return builtin_function.BuiltinFunction('g', ['x'], curried_f)

    def partial(f, fixed_args):
        num_original_args = f.get_num_args()
        num_fixed_args = len(fixed_args)
        num_args_needed = num_original_args - num_fixed_args
        if num_args_needed < 0:
            throw_exception(
                'TooManyFixedArguments',
                'Function {0} requires {1} arguments, but passing in {2}'.
                format(f.name, num_original_args, num_fixed_args))
        arg_names = ['x' + str(i) for i in xrange(num_args_needed)]

        def partially_applied_f(*args):
            return f.execute(fixed_args + list(args), env)

        return builtin_function.BuiltinFunction('fPrime', arg_names,
                                                partially_applied_f)

    def feed(*args):
        if len(args) == 0:
            throw_exception('NotEnoughArguments',
                            'Function requires at least 1 argument')
        result = args[0]
        for elem in args[1:]:
            if function.is_function(elem):
                result = elem.execute([result], env)
            elif type(elem) is list:
                if len(elem) == 0 or not function.is_function(elem[0]):
                    throw_exception(
                        'InvalidArgument',
                        'List must contain a function as first element')
                f = elem[0]
                rest = list(elem[1:])
                result = f.execute(rest + [result], env)
            else:
                throw_exception('InvalidArgument',
                                'Argument must be a list or function')
        return result

    env.assign(
        'compose',
        builtin_function.BuiltinFunction('compose', ['f', 'g'], compose))
    env.assign(
        'map', builtin_function.BuiltinFunction('map', ['f', 'lst'],
                                                map_prime))
    env.assign(
        'filter',
        builtin_function.BuiltinFunction('filter', ['predicate', 'lst'],
                                         filter_prime))
    env.assign('flip', builtin_function.BuiltinFunction('flip', ['f'], flip))
    env.assign(
        'foldLeft',
        builtin_function.BuiltinFunction('foldLeft', ['f', 'lst'], fold_left))
    env.assign(
        'foldRight',
        builtin_function.BuiltinFunction('foldRight', ['f', 'lst'],
                                         fold_right))
    env.assign(
        'any', builtin_function.BuiltinFunction('any', ['f', 'lst'],
                                                any_prime))
    env.assign(
        'all', builtin_function.BuiltinFunction('all', ['f', 'lst'],
                                                all_prime))
    env.assign('curry',
               builtin_function.BuiltinFunction('curry', ['f'], curry))
    env.assign(
        'partial',
        builtin_function.BuiltinFunction('partial', ['f', 'fixedArgs'],
                                         partial))
    env.assign(
        'feed',
        builtin_function.BuiltinFunction('feed', ['initial', '[tasks]'], feed))
Пример #14
0
def type_tree_methods(obj, name, env):
    # This method allows us to view the type tree of a given environment
    if name == 'format':
        return builtin_function.BuiltinFunction('constant', [], lambda: obj.format_as_literal())
    return None
Пример #15
0
 def flip(f):
     return builtin_function.BuiltinFunction(
         'g', ['x', 'y'], lambda x, y: f.execute([y, x], env))
Пример #16
0
    def differentiate(f, dx=1e-6):
        def f_prime(x):
            df = f.execute([x + dx], env) - f.execute([x], env)
            return df / dx

        return builtin_function.BuiltinFunction('fPrime', ['x'], f_prime)
Пример #17
0
def list_methods(obj, name, env):
    if name == 'length' or name == 'size':
        length = len(obj)
        return builtin_function.BuiltinFunction('constant', [], lambda: length)
    elif name == 'pop':
        last_elem = obj.pop()
        return builtin_function.BuiltinFunction('constant', [], lambda: last_elem)
    elif name == 'push':
        def func_push(new_elem):
            obj.append(new_elem)
            return obj
        return builtin_function.BuiltinFunction('list', ['newElem'], func_push)
    elif name == 'removeAt':
        return builtin_function.BuiltinFunction('constant', ['index'], lambda i: obj.pop(i))
    elif name == 'insertAt':
        def insert_at(index, elem):
            obj.insert(index, elem)
            return obj
        return builtin_function.BuiltinFunction('insertAt', ['index', 'elem'], insert_at)
    elif name == 'reverse':
        def reverse_list():
            obj.reverse()
            return obj
        return builtin_function.BuiltinFunction('reverse', [], reverse_list)
    elif name == 'find':
        # Returns the position of the element in the list.
        # If the element is not found, returns null.
        def find(elem):
            if type(elem) is dict and '$eq' in elem:
                eq_method = elem['$eq']
                # TODO : if there is no $eq method, and the $notEq (not equals) method
                #        is defined, use the default definition $eq(a, b) = not $notEq(a, b)
                for i, item in enumerate(obj):
                    if eq_method.execute([item], env):
                        return i
                return None
            try:
                return obj.index(elem)
            except ValueError:
                return None
        return builtin_function.BuiltinFunction('find', ['elem'], find)
    elif name == 'slice':
        def slice(start, stop=None):
            if stop is None:
                return obj[start:]
            else:
                return obj[start:stop]
        return builtin_function.BuiltinFunction('slice', ['start', 'stop?'], slice)
    elif name == 'first':
        return builtin_function.BuiltinFunction('first', [], lambda: None if len(obj) == 0 else obj[0])
    elif name == 'last':
        return builtin_function.BuiltinFunction('last', [], lambda: None if len(obj) == 0 else obj[-1])
    elif name == 'rest':
        return builtin_function.BuiltinFunction('rest', [], lambda: obj[1:])
    elif name == 'leading':
        return builtin_function.BuiltinFunction('leading', [], lambda: obj[:-1])
    return None