# -*- coding: utf-8 -*- ''' A dialect of Joy in Python. Joy is a programming language created by Manfred von Thun that is easy to use and understand and has many other nice properties. This Python script is an interpreter for a dialect of Joy that attempts to stay very close to the spirit of Joy but does not precisely match the behaviour of the original version(s) written in C. A Tkinter GUI is provided as well. Copyright © 2014, 2016, 2017 Simon Forman This file is part of Joypy. Joypy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Joypy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Joypy. If not see . § joy() The basic joy() function is quite straightforward. It iterates through a sequence of terms which are either literals (strings, numbers, sequences) or functions. Literals are put onto the stack and functions are executed. Every Joy function is an unary mapping from stacks to stacks. Even literals are considered to be functions that accept a stack and return a new stack with the literal value on top. Exports: joy(stack, expression, dictionary, viewer=None) run(text, stack, dictionary, viewer=None) repl(stack=(), dictionary=()) ''' from __future__ import print_function try: input = raw_input except NameError: pass from traceback import print_exc, format_exc from .parser import text_to_expression, ParseError, Symbol from .utils.stack import stack_to_string from .utils.pretty_print import TracePrinter def joy(stack, expression, dictionary, viewer=None): ''' Evaluate the Joy expression on the stack. ''' while expression: if viewer: viewer(stack, expression) term, expression = expression if isinstance(term, Symbol): term = dictionary[term] stack, expression, dictionary = term(stack, expression, dictionary) else: stack = term, stack if viewer: viewer(stack, expression) return stack, expression, dictionary def run(text, stack, dictionary, viewer=None): ''' Return the stack resulting from running the Joy code text on the stack. ''' expression = text_to_expression(text) return joy(stack, expression, dictionary, viewer) def repl(stack=(), dictionary=None): ''' Read-Evaluate-Print Loop Accept input and run it on the stack, loop. ''' if dictionary is None: dictionary = {} try: while True: print() print(stack_to_string(stack), '<-top') print() try: text = input('joy? ') except (EOFError, KeyboardInterrupt): break viewer = TracePrinter() try: stack, _, dictionary = run(text, stack, dictionary, viewer.viewer) except: exc = format_exc() # Capture the exception. viewer.print_() # Print the Joy trace. print('-' * 73) print(exc) # Print the original exception. else: viewer.print_() except: print_exc() print() return stack