Esempio n. 1
0
def _while(states, scope, arguments, block):
    if not len(block.lines):
        raise InvalidArguments('A block is required in `while`')
    if len(arguments.args) != 1 \
        or len(arguments.kwargs):
        raise InvalidArguments('`while` only accepts one conditional argument')
    var = arguments.args[0]

    retval = None
    while var.python_value(scope):
        if retval is None:
            retval = ''
        try:
            retval += str(block.python_value(scope))
        except BreakException as e:
            retval += e.retval
            break
        except ContinueException as e:
            retval += e.retval
            continue
    else:
        if retval is None:
            return [Continue(), EmptyState(), ElseState()], ''
        return [Continue(), ElseState()], retval
    return [Continue()], retval
Esempio n. 2
0
def binary_or(left, right, scope):
    if isinstance(right, PlywoodCallOperator):
        new_op = right.copy()
        new_op.right.args.insert(0, left.get_value(scope))
        arguments = new_op.right
        _, retval = new_op.run([Continue()], scope)
    else:
        arguments = PlywoodParens(right.location, [left])
        block = PlywoodBlock(right.location, [])
        _, retval = right.call([Continue()], scope, arguments, block)
    return retval
Esempio n. 3
0
def _elif(states, scope, arguments, block):
    if not len(block.lines):
        raise InvalidArguments('A block is required in `elif`')
    if len(arguments.args) != 1:
        raise InvalidArguments(
            'A condition (and only one condition) is required in `elif`')
    if len(arguments.args) != 1 or len(arguments.kwargs):
        raise InvalidArguments('`elif` only accepts one argument')
    arg = arguments.args[0].python_value(scope)
    if arg:
        return [Continue()], block.get_value(scope)
    return [Continue(), ElseState()], ''
Esempio n. 4
0
def _for(states, scope, arguments, block):
    if not len(block.lines):
        raise InvalidArguments('A block is required in `for`')
    if len(arguments.args) != 1 \
        or len(arguments.kwargs) \
        or not isinstance(arguments.args[0], PlywoodOperator) \
        or arguments.args[0].operator != 'in':
        raise InvalidArguments('`for` only accepts an `in` operation')
    var = arguments.args[0].left
    if not isinstance(var, PlywoodVariable) and not isinstance(
            var, PlywoodParens):
        raise InvalidArguments(
            '`for` expects a variable name or tuple of variable names')
    if isinstance(var, PlywoodParens):
        if var.kwargs:
            raise InvalidArguments(
                'keyword arguments are not in appropriate in the list of  `for` variable names'
            )
        for arg in var.arguments:
            if not isinstance(arg, PlywoodVariable):
                raise InvalidArguments(
                    '`for` expects a variable name or tuple of variable names')
    iterator = arguments.args[0].right.python_value(scope)

    retval = None
    if not iterator:
        return [Continue(), EmptyState(), ElseState()], ''
    for for_value in iterator:
        if retval is None:
            retval = ''
        if isinstance(var, PlywoodVariable):
            varname = var.get_name()
            scope[varname] = for_value
        elif isinstance(var, PlywoodParens):
            raise Exception('huh?')
            # for_values should be a PlywoodList, PlywoodDict,
            # if len(var.arguments) !=
            # scope[]
            pass
        try:
            retval += str(block.python_value(scope))
        except BreakException as e:
            retval += e.retval
            break
        except ContinueException as e:
            retval += e.retval
            continue
    else:
        if retval is None:
            return [Continue(), EmptyState(), ElseState()], ''
        return [Continue(), ElseState()], retval
    return [Continue()], retval
Esempio n. 5
0
    def the_function(states, called_scope, called_arguments, called_block):
        args = called_arguments.args
        kwargs = called_arguments.kwargs
        local_arglist = [] + final_arglist
        called_scope.push()
        for plywood_kwarg in kwargs:
            local_value = plywood_kwarg.value.python_value(scope)
            local_var_name = plywood_kwarg.key.python_value(scope)
            if local_var_name in local_arglist:
                local_arglist.remove(local_var_name)
            else:
                raise InvalidArguments('Unknown keyword argument {0!r}'.format(local_var_name))
            called_scope[local_var_name] = local_value

        for plywood_value in args:
            local_value = plywood_value.python_value(called_scope)
            if not local_arglist:
                raise InvalidArguments('Too many arguments passed to {0}'.format(function_name))
            local_var_name = local_arglist.pop(0)
            called_scope[local_var_name] = local_value

        for local_var_name, local_value in defaults.items():
            if local_var_name in local_arglist:
                local_arglist.remove(local_var_name)
                called_scope[local_var_name] = local_value

        if local_arglist:
            raise InvalidArguments('Unassigned values: {0}'.format(', '.join(local_arglist)))

        def return_function(arg):
            raise ReturnException(arg)

        called_scope['return'] = PlywoodFunction(return_function)
        try:
            retval = block.get_value(called_scope)
        except ReturnException as e:
            retval = e.retval
        called_scope.pop()
        return [Continue()], retval
Esempio n. 6
0
def markdown(states, scope, arguments, block):
    code = block.get_value(scope).python_value(scope)
    markup = misaka.smartypants(compiler(code).strip())
    return [Continue()], markup
Esempio n. 7
0
def _def(states, scope, arguments, block):
    '''
    Example:
        def foo(bar, baz, quux='value')
    foo => name of function
    [bar, baz] => arguments, no default values.  These must be variable names.

    Sorry, no support for *args and **kwargs just yet.
    '''
    if not len(block.lines):
        raise InvalidArguments('A block is required in `def`')
    if len(arguments.args) != 1 \
        or len(arguments.kwargs) \
        or not isinstance(arguments.args[0], PlywoodCallOperator) \
        or arguments.args[0].operator != '()':
        raise InvalidArguments('`def` should be followed by a function definition')
    function_name = arguments.args[0].left.get_name()
    arglist = arguments.args[0].right.args
    kwarglist = arguments.args[0].right.kwargs
    final_arglist = []
    defaults = {}
    # all arglist.args should be a varname
    for var_name in arglist:
        if not isinstance(var_name, PlywoodVariable):
            raise InvalidArguments('`def` should be given a list of variable names.  '
                                   '{0!r} is invalid'.format(var_name.python_value(scope)))
        final_arglist.append(var_name.get_name())

    for kwarg in kwarglist:
        var_name = kwarg.key.python_value(scope)
        final_arglist.append(var_name)
        value = kwarg.value.python_value(scope)
        defaults[var_name] = value

    # Now we have to re-produce python's way of accepting arguments, but I'm
    # gonna get away with being sloppy about it...
    # First, any kwargs can be assigned, and removed from the final_arglist.
    # Then, args is scanned and values are assigned to corresponding names in
    # final_arglist.  If any values are left over in final_arglist, args, or
    # kwargs, something went wrong.
    #
    # The sloppy part comes because unlike python, you can specify args and
    # kwargs in pretty much any order.  All kwargs are assigned first, then
    # the args are assigned to whatever is left in the local_arglist, then
    # defaults.  Only after all that is local_arglist checked to make sure it is
    # empty.
    def the_function(states, called_scope, called_arguments, called_block):
        args = called_arguments.args
        kwargs = called_arguments.kwargs
        local_arglist = [] + final_arglist
        called_scope.push()
        for plywood_kwarg in kwargs:
            local_value = plywood_kwarg.value.python_value(scope)
            local_var_name = plywood_kwarg.key.python_value(scope)
            if local_var_name in local_arglist:
                local_arglist.remove(local_var_name)
            else:
                raise InvalidArguments('Unknown keyword argument {0!r}'.format(local_var_name))
            called_scope[local_var_name] = local_value

        for plywood_value in args:
            local_value = plywood_value.python_value(called_scope)
            if not local_arglist:
                raise InvalidArguments('Too many arguments passed to {0}'.format(function_name))
            local_var_name = local_arglist.pop(0)
            called_scope[local_var_name] = local_value

        for local_var_name, local_value in defaults.items():
            if local_var_name in local_arglist:
                local_arglist.remove(local_var_name)
                called_scope[local_var_name] = local_value

        if local_arglist:
            raise InvalidArguments('Unassigned values: {0}'.format(', '.join(local_arglist)))

        def return_function(arg):
            raise ReturnException(arg)

        called_scope['return'] = PlywoodFunction(return_function)
        try:
            retval = block.get_value(called_scope)
        except ReturnException as e:
            retval = e.retval
        called_scope.pop()
        return [Continue()], retval
    the_function.__name__ = function_name

    scope[function_name] = PlywoodRuntime(the_function)
    return [Continue()], ''
Esempio n. 8
0
def _else(states, scope, arguments, block):
    if not len(block.lines):
        raise InvalidArguments('A block is required in `else`')
    if len(arguments.args) or len(arguments.kwargs):
        raise InvalidArguments('`else` does not accept any arguments')
    return [Continue()], block.get_value(scope)
Esempio n. 9
0
def empty(state, scope, arguments, block):
    if not len(block.lines):
        raise ParseException('A block is required in `empty`')
    if len(arguments.args) or len(arguments.kwargs):
        raise ParseException('`empty` does not accept any arguments')
    return [Continue()], block.get_value(scope)