Pigeon Computer 0.1 documentation

pigeon.xerblin.library

Contents

Source code for pigeon.xerblin.library

# Library
'''
Library of Words
=================================

'''
from pickle import dumps, loads
from pigeon.xerblin.base import handle_sequence, handle_loop, handle_branch
from pigeon.xerblin.btree import get, insert, items, fill_tree
from pigeon.xerblin.stack import pop, push, pick_, iterStack


# Mark the current namespace contents.
_existing = set(dir())
_existing.add('_existing')


# Stack chatter.

[docs]def dup((stack, dictionary)): ''' "Duplicate" the top item on the stack. ''' return (stack[0], stack), dictionary
[docs]def swap((stack, dictionary)): ''' Reverse the order of the top two items on the stack. ''' TOS, second, stack = pop(stack, 2) stack = push(stack, TOS, second) return stack, dictionary
[docs]def pick((stack, dictionary)): ''' Takes a number from the stack, counts back that many items (starting from zero for the top item) and puts a "duplicate" of the item found on the top of the stack. (So pick with 0 on the stack is thte same as the command "dup".) ''' TOS, stack = stack stack = pick_(stack, TOS) return stack, dictionary
[docs]def tuck((stack, dictionary)): ''' Put a "duplicate" of the item on the top of the stack just under the second item on the stack. (I.e. top, second, top.) ''' TOS, second, stack = pop(stack, 2) stack = push(stack, TOS, second, TOS) return stack, dictionary
[docs]def drop((stack, dictionary)): ''' Remove the item on the top of the stack and discard it. ''' return stack[1], dictionary
[docs]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.
[docs]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
[docs]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) return stack, dictionary
[docs]def NewSeqWord((stack, dictionary)): ''' This command takes all the items on the stack and puts them into a tuple with the Sequence Handler function in front of them. The items on the stack should all be commands from the dictionary, either functions or combo commands. You get these by using the "lookup" command on the names of the functions you want. Put the first command to run on the stack first, then the second, and so on, so that the last item to run is on the top of the stack when you run this command. ''' words = tuple(reversed(list(iterStack(stack)))) seq = (handle_sequence,) + words return (seq, ()), dictionary
[docs]def NewLoopWord((stack, dictionary)): ''' This command takes all the items on the stack and puts them into a tuple with the Loop Handler function in front of them. A Loop consumes the top item on the stack, then depending on it's "truth" either runs the commands in its tuple and repeats if it's true or stops looping altogether if it's false. Put the first command to run on the stack first, then the second, and so on, so that the last item to run is on the top of the stack when you run this command. ''' words = tuple(reversed(list(iterStack(stack)))) loop = (handle_loop,) + words return (loop, ()), dictionary
[docs]def NewBranchWord((stack, dictionary)): ''' Create a new Branch command word. A branch consumes the top item on the stack and does one of two things depending on its "truth" value. Unlike Loops and Sequences which use all the items on the stack, Branch commands only take the top two items. The item on the top of the stack should be a function to use in case of "true" and the second should be a function to use for "false". ''' true, false, stack = pop(stack, 2) branch = (handle_branch, true, false) stack = push(stack, branch) return stack, dictionary # Math words.
[docs]def add((stack, dictionary)): ''' Add the top two items on the stack and replace them with the sum. ''' a, b, stack = pop(stack, 2) return (a + b, stack), dictionary
[docs]def sub((stack, dictionary)): ''' Replace the top two items on the stack with the result of subtracting the top item from the second item. ''' a, b, stack = pop(stack, 2) return (b - a, stack), dictionary
[docs]def mul((stack, dictionary)): ''' Replace the top two items on the stack with the result of multiplying them together. ''' a, b, stack = pop(stack, 2) return (a * b, stack), dictionary # Pickling words.
[docs]def pickle(interpreter): ''' Convert the current interpreter to a portable text format (called a "pickle".) ''' stack, dictionary = interpreter p = dumps(interpreter) return (p, stack), dictionary
[docs]def unpickle(interpreter): ''' Take a string "pickle" portable text representation of an interpreter and replace the current interpreter with it. ''' stack = interpreter[0] return loads(stack[0]) # System words
[docs]def rebalance((stack, dictionary)): ''' This "rebalances" a dictionary. It makes it more efficient to access commands in the dictionary if you've added a lot of new ones. It's a good idea to use this command before creating a pickle to save so that the saved pickle's dictionary is already balanced. ''' dictionary = fill_tree((), items(dictionary)) return stack, dictionary
[docs]def view(interpreter): ''' Pretty print the interpreter to stdout. ''' from pprint import pprint as p p(interpreter) return interpreter
[docs]def listwords(interpreter): ''' Print the list of words in the dictionary to stdout. ''' dictionary = interpreter[1] for name, func in items(dictionary): print name print return interpreter # Now extract all the library functions we just defined.
_word_names = set(dir()) - _existing # Pull words from this list. words = [ (name, function) for name, function in locals().items() if name in _word_names ]

Contents