diff --git a/joy/gui/main.py b/joy/gui/main.py index 17539a3..0a2bf53 100755 --- a/joy/gui/main.py +++ b/joy/gui/main.py @@ -7,11 +7,21 @@ Joypy - Copyright © 2018 Simon Forman ' This is free software, and you are welcome to redistribute it under certain conditions;' ' right-click "sharing" for details.' ' Right-click on these commands to see docs on UI commands: key_bindings mouse_bindings') -import os, pickle, sys +import logging, os, pickle, sys from textwrap import dedent -from joy.gui.textwidget import TextViewerWidget, tk, get_font, TEXT_BINDINGS from joy.gui.utils import init_home, FileFaker + +JOY_HOME, repo = init_home() + +logging.basicConfig( + format='%(asctime)-15s %(levelname)s %(name)s %(message)s', + filename=os.path.join(JOY_HOME, 'thun.log'), + level=logging.INFO, + ) + + +from joy.gui.textwidget import TextViewerWidget, tk, get_font, TEXT_BINDINGS from joy.gui.world import StackDisplayWorld from joy.library import initialize from joy.utils.stack import stack_to_string @@ -101,7 +111,6 @@ def grand_reset(s, e, d): return stack, e, d -JOY_HOME, repo = init_home() STACK_FN = os.path.join(JOY_HOME, 'stack.pickle') REL_STACK_FN = repo_relative_path(STACK_FN) JOY_FN = os.path.join(JOY_HOME, 'scratch.txt') diff --git a/joy/utils/types.py b/joy/utils/types.py index 7c41005..0eec8d8 100644 --- a/joy/utils/types.py +++ b/joy/utils/types.py @@ -6,7 +6,12 @@ _log = getLogger(__name__) from collections import Counter from itertools import imap, chain, product from inspect import stack as inspect_stack -from joy.utils.stack import concat, expression_to_string, list_to_stack +from joy.utils.stack import ( + concat, + expression_to_string, + list_to_stack, + stack_to_string, + ) from joy.parser import Symbol, text_to_expression @@ -222,6 +227,8 @@ def relabel(left, right): def _1000(right): + if isinstance(right, Symbol): + return right if not isinstance(right, tuple): return 1000 + right return tuple(_1000(n) for n in right) @@ -539,7 +546,8 @@ ID = _S0, _S0 # Identity function. def _infer(e, F=ID): - _log_it(e, F) + if __debug__: + _log_it(e, F) if not e: return [F] @@ -577,7 +585,7 @@ def _interpret(f, fi, fo, e): def _log_it(e, F): - _log.info( + _log.debug( u'%3i %s ∘ %s', len(inspect_stack()), doc_from_stack_effect(*F), @@ -614,25 +622,38 @@ def infer_expression(expression): def type_check(name, stack): - ''' - Trinary predicate. True if named function type-checks, False if it - fails, None if it's indeterminate (because I haven't entered it into - the FUNCTIONS dict yet.) - ''' + ''' + Trinary predicate. True if named function type-checks, False if it + fails, None if it's indeterminate (because I haven't entered it into + the FUNCTIONS dict yet.) + ''' + try: + func = FUNCTIONS[name] + except KeyError: + return # None, indicating unknown + if isinstance(func, SymbolJoyType): + secs = func.stack_effects + elif isinstance(func, CombinatorJoyType): + if func.expect is None: + return # None, indicating unknown + secs = [(func.expect, ())] + else: + raise TypeError(repr(func)) # wtf? + for fi, fo in secs: try: - func = FUNCTIONS[name] - except KeyError: - return # None, indicating unknown - - for fi, fo in infer(func): - try: - U = unify(fi, stack) - except (JoyTypeError, ValueError), e: - #print >> sys.stderr, name, e, stack - continue - #print U - return True - return False + unify(fi, stack) + except (JoyTypeError, ValueError): + continue + except: + _log.exception( + 'Type-checking %s %s against %s', + name, + doc_from_stack_effect(fi, fo), + stack_to_string(stack), + ) + continue + return True + return False FUNCTIONS = {} # Polytypes (lists of stack effects.)