# Path: pigeon/xerblin/base.py
# def handle_sequence(I, seq):
#     '''
#     Run a sequence and return the modified interpreter.
#     '''
#     for func in seq[1:]:
#         I = apply_func(I, func)
#     return I
# 
# def handle_loop(I, loop):
#     '''
#     Check TOS and do body if it's true, repeat.
#     '''
#     while True:
#         TOS, I = _pop_TOS(I)
#         if not TOS:
#             break
#         I = handle_sequence(I, loop)
#     return I
# 
# def handle_branch(I, branch):
#     '''
#     Check TOS and do one thing or another depending.
#     '''
#     TOS, I = _pop_TOS(I)
#     func = branch[(not TOS) + 1] # i.e. True = 1; False = 2
#     return apply_func(I, func)
# 
# def enstacken((stack, dictionary), stack_us):
#     '''
#     Push the items in the body onto the stack.
#     '''
#     stack = push(stack, *stack_us[1:])
#     return stack, dictionary
# 
# Path: pigeon/xerblin/btree.py
# def get(node, key):
#     '''
#     Return the value stored under key or raise KeyError if not found.
#     '''
#     if not node:
#         raise KeyError, key
# 
#     node_key, value, lower, higher = node
# 
#     if key == node_key:
#         return value
# 
#     return get(lower if key < node_key else higher, key)
# 
# def insert(node, key, value):
#     '''
#     Return a tree with value stored under key. Replaces old value if any.
#     '''
#     if not node:
#         return key, value, (), ()
# 
#     node_key, node_value, lower, higher = node
# 
#     if key < node_key:
#         return node_key, node_value, insert(lower, key, value), higher
# 
#     if key > node_key:
#         return node_key, node_value, lower, insert(higher, key, value)
# 
#     return key, value, lower, higher
# 
# def items(node):
#     '''
#     Iterate in order over the (key, value) pairs in a tree.
#     '''
#     if not node:
#         return
# 
#     key, value, lower, higher = node
#     
#     for kv in items(lower):
#         yield kv
#     
#     yield key, value
#     
#     for kv in items(higher):
#         yield kv
# 
# def fill_tree(node, items):
#     '''
#     Add the (key, value) pairs in items to a btree in a balanced way.
# 
#     You can balance a tree like so:
# 
#         tree = fill_tree((), items(tree))
# 
#     This iterates through the tree and returns a new, balanced tree from
#     its contents.
#     '''
#     for key, value in _yield_balanced(sorted(items)):
#         node = insert(node, key, value)
#     return node
# 
# Path: pigeon/xerblin/stack.py
# def pop(stack, number):
#     '''Pop number arguments from stack.'''
#     for _ in range(number):
#         item, stack = stack # pop
#         yield item
#     yield stack
# 
# def push(stack, *items):
#     '''Push arguments onto a stack.'''
#     for item in items:
#         stack = item, stack # push
#     return stack
# 
# def pick_(stack, n):
#     '''
#     Find the nth item on the stack and duplicate it to TOS. (Pick with
#     zero is the same as "dup".)
#     '''
#     if n < 0:
#         raise ValueError
#     s = stack
#     while True:
#         try:
#             item, s = s
#         except ValueError:
#             raise IndexError
#         n -= 1
#         if n < 0:
#             break
#     return item, stack
# 
# def iterStack(stack):
#     '''Iterate through the items on the stack.'''
#     while stack:
#         item, stack = stack
#         yield item
# 
# Path: pigeon/assembler/pyavrasm.py
# def assemble(self, text):
#   '''
#   Assemble the string asm source code.
# 
#   :param text: Assembly source code.
#   :type text: ``str``
#   :rtype: ``None``
#   '''
#   exec text in self.context
#   del self.context['__builtins__']
#   self.pass2()
# 
# Path: pigeon/metacompiler/metaii.py
# def comp(source, machine):
#   m2 = MetaII()
#   m2.assemble(machine)
#   return m2.compile(source)


from pickle import dumps, loads
from pigeon.xerblin.base import handle_sequence, handle_loop, handle_branch, enstacken
from pigeon.xerblin.btree import get, insert, items, fill_tree
from pigeon.xerblin.stack import pop, push, pick_, iterStack
from pigeon.assembler.pyavrasm import assemble as assemble_raw
from pigeon.metacompiler.metaii import comp
    from pprint import pprint as p
def over((stack, dictionary)):
    '''
    Put a "duplicate" of the second item down in the stack on the top of
    the stack. (I.e. second, top, second.)
    '''
    second = stack[1][0]
    return (second, stack), dictionary


# Programming words.

def lookup(interpreter):
    '''
    Given a name on the top of the stack, look up the named command in
    the dictionary and put it on the stack in place of the name.
    '''
    (name, stack), dictionary = interpreter
    word = get(dictionary, name)
    return (word, stack), dictionary


def inscribe((stack, dictionary)):
    '''
    Given a name string on the top of the stack and a "combo" command
    underneath it (see NewSeqWord, NewLoopWord, and NewBranchWord for how
    to make combo commands) "inscribe" the combo command into the
    dictionary under that name, replacing any previous command of that
    name.
    '''
    name, word, stack = pop(stack, 2)

# Path: pigeon/xerblin/base.py
# def handle_sequence(I, seq):
#     '''
#     Run a sequence and return the modified interpreter.
#     '''
#     for func in seq[1:]:
#         I = apply_func(I, func)
#     return I
# 
# def handle_loop(I, loop):
#     '''
#     Check TOS and do body if it's true, repeat.
#     '''
#     while True:
#         TOS, I = _pop_TOS(I)
#         if not TOS:
#             break
#         I = handle_sequence(I, loop)
#     return I
# 
# def handle_branch(I, branch):
#     '''
#     Check TOS and do one thing or another depending.
#     '''
#     TOS, I = _pop_TOS(I)
#     func = branch[(not TOS) + 1] # i.e. True = 1; False = 2
#     return apply_func(I, func)
# 
# def enstacken((stack, dictionary), stack_us):
#     '''
#     Push the items in the body onto the stack.
#     '''
#     stack = push(stack, *stack_us[1:])
#     return stack, dictionary
# 
# Path: pigeon/xerblin/btree.py
# def get(node, key):
#     '''
#     Return the value stored under key or raise KeyError if not found.
#     '''
#     if not node:
#         raise KeyError, key
# 
#     node_key, value, lower, higher = node
# 
#     if key == node_key:
#         return value
# 
#     return get(lower if key < node_key else higher, key)
# 
# def insert(node, key, value):
#     '''
#     Return a tree with value stored under key. Replaces old value if any.
#     '''
#     if not node:
#         return key, value, (), ()
# 
#     node_key, node_value, lower, higher = node
# 
#     if key < node_key:
#         return node_key, node_value, insert(lower, key, value), higher
# 
#     if key > node_key:
#         return node_key, node_value, lower, insert(higher, key, value)
# 
#     return key, value, lower, higher
# 
# def items(node):
#     '''
#     Iterate in order over the (key, value) pairs in a tree.
#     '''
#     if not node:
#         return
# 
#     key, value, lower, higher = node
#     
#     for kv in items(lower):
#         yield kv
#     
#     yield key, value
#     
#     for kv in items(higher):
#         yield kv
# 
# def fill_tree(node, items):
#     '''
#     Add the (key, value) pairs in items to a btree in a balanced way.
# 
#     You can balance a tree like so:
# 
#         tree = fill_tree((), items(tree))
# 
#     This iterates through the tree and returns a new, balanced tree from
#     its contents.
#     '''
#     for key, value in _yield_balanced(sorted(items)):
#         node = insert(node, key, value)
#     return node
# 
# Path: pigeon/xerblin/stack.py
# def pop(stack, number):
#     '''Pop number arguments from stack.'''
#     for _ in range(number):
#         item, stack = stack # pop
#         yield item
#     yield stack
# 
# def push(stack, *items):
#     '''Push arguments onto a stack.'''
#     for item in items:
#         stack = item, stack # push
#     return stack
# 
# def pick_(stack, n):
#     '''
#     Find the nth item on the stack and duplicate it to TOS. (Pick with
#     zero is the same as "dup".)
#     '''
#     if n < 0:
#         raise ValueError
#     s = stack
#     while True:
#         try:
#             item, s = s
#         except ValueError:
#             raise IndexError
#         n -= 1
#         if n < 0:
#             break
#     return item, stack
# 
# def iterStack(stack):
#     '''Iterate through the items on the stack.'''
#     while stack:
#         item, stack = stack
#         yield item
# 
# Path: pigeon/assembler/pyavrasm.py
# def assemble(self, text):
#   '''
#   Assemble the string asm source code.
# 
#   :param text: Assembly source code.
#   :type text: ``str``
#   :rtype: ``None``
#   '''
#   exec text in self.context
#   del self.context['__builtins__']
#   self.pass2()
# 
# Path: pigeon/metacompiler/metaii.py
# def comp(source, machine):
#   m2 = MetaII()
#   m2.assemble(machine)
#   return m2.compile(source)


# Path: pigeon/xerblin/library.py
from pickle import dumps, loads
from pigeon.xerblin.base import handle_sequence, handle_loop, handle_branch, enstacken
from pigeon.xerblin.btree import get, insert, items, fill_tree
from pigeon.xerblin.stack import pop, push, pick_, iterStack
from pigeon.assembler.pyavrasm import assemble as assemble_raw
from pigeon.metacompiler.metaii import comp
    from pprint import pprint as p

def over((stack, dictionary)):
    '''
    Put a "duplicate" of the second item down in the stack on the top of
    the stack. (I.e. second, top, second.)
    '''
    second = stack[1][0]
    return (second, stack), dictionary


# Programming words.

def lookup(interpreter):
    '''
    Given a name on the top of the stack, look up the named command in
    the dictionary and put it on the stack in place of the name.
    '''
    (name, stack), dictionary = interpreter
    word = get(dictionary, name)
    return (word, stack), dictionary


def inscribe((stack, dictionary)):
    '''
    Given a name string on the top of the stack and a "combo" command
    underneath it (see NewSeqWord, NewLoopWord, and NewBranchWord for how
    to make combo commands) "inscribe" the combo command into the
    dictionary under that name, replacing any previous command of that
    name.
    '''
    name, word, stack = pop(stack, 2)

    dictionary = insert(dictionary, name, word)