Quiet mode for testing. Misc cleanup.
This commit is contained in:
parent
660fdb0bef
commit
d7b445fdd4
|
|
@ -37,7 +37,9 @@ import operator
|
||||||
|
|
||||||
|
|
||||||
class NotAListError(Exception):
|
class NotAListError(Exception):
|
||||||
'''Raised when a stack is expected.'''
|
'''
|
||||||
|
Raised when a stack is expected but not received.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
class NotAnIntError(Exception):
|
class NotAnIntError(Exception):
|
||||||
|
|
@ -48,6 +50,12 @@ class NotABoolError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ParseError(ValueError):
|
||||||
|
'''
|
||||||
|
Raised when there is a error while parsing text.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
class StackUnderflowError(Exception):
|
class StackUnderflowError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -110,11 +118,11 @@ the fact that they are not Symbol objects.
|
||||||
|
|
||||||
A crude grammar::
|
A crude grammar::
|
||||||
|
|
||||||
joy = term*
|
joy = <term>*
|
||||||
term = integer | '[' joy ']' | symbol
|
term = <integer> | 'true' | 'false' | '[' <joy> ']' | <symbol>
|
||||||
|
|
||||||
A Joy expression is a sequence of zero or more terms. A term is a
|
A Joy expression is a sequence of zero or more terms. A term is a
|
||||||
literal value (integer or quoted Joy expression) or a function symbol.
|
literal value (integer, Boolean, or quoted Joy expression) or a function symbol.
|
||||||
Function symbols are sequences of non-blanks and cannot contain square
|
Function symbols are sequences of non-blanks and cannot contain square
|
||||||
brackets. Terms must be separated by blanks, which can be omitted
|
brackets. Terms must be separated by blanks, which can be omitted
|
||||||
around square brackets.
|
around square brackets.
|
||||||
|
|
@ -168,12 +176,6 @@ def text_to_expression(text):
|
||||||
return _parse(_tokenize(text))
|
return _parse(_tokenize(text))
|
||||||
|
|
||||||
|
|
||||||
class ParseError(ValueError):
|
|
||||||
'''
|
|
||||||
Raised when there is a error while parsing text.
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
def _tokenize(text):
|
def _tokenize(text):
|
||||||
'''Convert a text into a stream of tokens.
|
'''Convert a text into a stream of tokens.
|
||||||
|
|
||||||
|
|
@ -349,7 +351,7 @@ def concat(quote, expression):
|
||||||
# recursion limit on long quotes.)
|
# recursion limit on long quotes.)
|
||||||
|
|
||||||
if not isinstance(quote, tuple):
|
if not isinstance(quote, tuple):
|
||||||
raise NotAListError('Not a list.')
|
raise NotAListError(f'Not a list {_s(quote)}')
|
||||||
temp = []
|
temp = []
|
||||||
while quote:
|
while quote:
|
||||||
item, quote = quote
|
item, quote = quote
|
||||||
|
|
@ -480,6 +482,36 @@ def run(text, stack, dictionary):
|
||||||
return joy(stack, expr, dictionary)
|
return joy(stack, expr, dictionary)
|
||||||
|
|
||||||
|
|
||||||
|
def interp(stack=(), dictionary=None):
|
||||||
|
'''
|
||||||
|
Simple REPL with no extra output, suitable for use in scripts.
|
||||||
|
'''
|
||||||
|
if dictionary is None:
|
||||||
|
dictionary = {}
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
text = input()
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
stack, _, dictionary = run(text, stack, dictionary)
|
||||||
|
except UnknownSymbolError as sym:
|
||||||
|
print('Unknown:', sym)
|
||||||
|
except StackUnderflowError as e:
|
||||||
|
print(e) # 'Not enough values on stack.'
|
||||||
|
except NotAnIntError:
|
||||||
|
print('Not an integer.')
|
||||||
|
except NotAListError as e:
|
||||||
|
print(e)
|
||||||
|
except:
|
||||||
|
print_exc()
|
||||||
|
print(stack_to_string(stack))
|
||||||
|
except:
|
||||||
|
print_exc()
|
||||||
|
return stack
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
██████╗ ██╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗ █████╗ ██████╗ ██╗ ██╗
|
██████╗ ██╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗ █████╗ ██████╗ ██╗ ██╗
|
||||||
██╔══██╗██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║██╔══██╗██╔══██╗╚██╗ ██╔╝
|
██╔══██╗██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║██╔══██╗██╔══██╗╚██╗ ██╔╝
|
||||||
|
|
@ -586,6 +618,12 @@ def branch(stack, expr, dictionary):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
(then, (else_, (flag, stack))) = stack
|
(then, (else_, (flag, stack))) = stack
|
||||||
|
if not isinstance(flag, bool):
|
||||||
|
raise NotABoolError(f'Not a Boolean value: {_s(flag)}')
|
||||||
|
if not isinstance(else_, tuple):
|
||||||
|
raise NotAListError(f'Not a list {_s(else_)}')
|
||||||
|
if not isinstance(then, tuple):
|
||||||
|
raise NotAListError(f'Not a list {_s(then)}')
|
||||||
do = then if flag else else_
|
do = then if flag else else_
|
||||||
return stack, concat(do, expr), dictionary
|
return stack, concat(do, expr), dictionary
|
||||||
|
|
||||||
|
|
@ -967,7 +1005,7 @@ class Def(object):
|
||||||
the pending expression.
|
the pending expression.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
tribar = '\u2261' # '≡'
|
# tribar = '\u2261' # '≡'
|
||||||
|
|
||||||
def __init__(self, name, body):
|
def __init__(self, name, body):
|
||||||
self.__doc__ = f'{name} ≡ {expression_to_string(body)}'
|
self.__doc__ = f'{name} ≡ {expression_to_string(body)}'
|
||||||
|
|
@ -999,6 +1037,13 @@ Start with increment and decrement:
|
||||||
-- ≡ 1 -
|
-- ≡ 1 -
|
||||||
++ ≡ 1 +
|
++ ≡ 1 +
|
||||||
|
|
||||||
|
= ≡ eq
|
||||||
|
+ ≡ add
|
||||||
|
> ≡ gt
|
||||||
|
< ≡ lt
|
||||||
|
>= ≡ ge
|
||||||
|
<= ≡ le
|
||||||
|
|
||||||
|
|
||||||
? ≡ dup bool
|
? ≡ dup bool
|
||||||
&& ≡ nulco [nullary [false]] dip branch
|
&& ≡ nulco [nullary [false]] dip branch
|
||||||
|
|
@ -1122,6 +1167,8 @@ _map2 [infrst] cons dipd roll< swons
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
J = interp if '-q' in sys.argv else repl
|
||||||
dictionary = initialize()
|
dictionary = initialize()
|
||||||
Def.load_definitions(DEFS.splitlines(), dictionary)
|
Def.load_definitions(DEFS.splitlines(), dictionary)
|
||||||
stack = repl(dictionary=dictionary)
|
stack = J(dictionary=dictionary)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue