Definitions infer stack effects.
At start-up defs that DON'T type check are permitted (so you can use e.g. loop, map, etc.) in the definitions "source", but then the user-facing inscribe command only allows you to define new commands that DO type-check. The ideal solution here is to get inference working for the loopy words. (In the meantime you can select and execute their definition text directly. That's not (yet!) type-checked.)
This commit is contained in:
parent
c9f405fbe9
commit
7607ca7650
|
|
@ -23,7 +23,7 @@ from inspect import getdoc
|
||||||
from joy.joy import run
|
from joy.joy import run
|
||||||
from joy.parser import Symbol
|
from joy.parser import Symbol
|
||||||
from joy.utils.stack import stack_to_string
|
from joy.utils.stack import stack_to_string
|
||||||
from joy.utils.polytypes import type_check
|
from joy.utils.types import type_check
|
||||||
|
|
||||||
|
|
||||||
def is_numerical(s):
|
def is_numerical(s):
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ codireco == cons dip rest cons
|
||||||
make_generator == [codireco] ccons
|
make_generator == [codireco] ccons
|
||||||
ifte == [nullary not] dipd branch
|
ifte == [nullary not] dipd branch
|
||||||
'''
|
'''
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# ifte == [nullary] dipd swap branch
|
# ifte == [nullary] dipd swap branch
|
||||||
# genrec == [[genrec] cons cons cons cons] nullary swons concat ifte
|
# genrec == [[genrec] cons cons cons cons] nullary swons concat ifte
|
||||||
|
|
@ -365,17 +366,20 @@ class DefinitionWrapper(object):
|
||||||
class_.add_def(definition, dictionary)
|
class_.add_def(definition, dictionary)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_def(class_, definition, dictionary):
|
def add_def(class_, definition, dictionary, fail_fails=False):
|
||||||
'''
|
'''
|
||||||
Add the definition to the dictionary.
|
Add the definition to the dictionary.
|
||||||
'''
|
'''
|
||||||
F = class_.parse_definition(definition)
|
F = class_.parse_definition(definition)
|
||||||
try:
|
try:
|
||||||
#print F._body
|
# print F.name, F._body
|
||||||
secs = infer(*F._body)
|
secs = infer(*F._body)
|
||||||
except JoyTypeError:
|
except JoyTypeError:
|
||||||
pass
|
pass
|
||||||
print F.name, '==', expression_to_string(F.body), ' --failed to infer stack effect.'
|
print F.name, '==', expression_to_string(F.body), ' --failed to infer stack effect.'
|
||||||
|
if fail_fails:
|
||||||
|
print 'Function not inscribed.'
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
FUNCTIONS[F.name] = SymbolJoyType(F.name, secs, _SYM_NUMS())
|
FUNCTIONS[F.name] = SymbolJoyType(F.name, secs, _SYM_NUMS())
|
||||||
dictionary[F.name] = F
|
dictionary[F.name] = F
|
||||||
|
|
@ -405,7 +409,7 @@ def inscribe_(stack, expression, dictionary):
|
||||||
the definitions.txt resource.
|
the definitions.txt resource.
|
||||||
'''
|
'''
|
||||||
definition, stack = stack
|
definition, stack = stack
|
||||||
DefinitionWrapper.add_def(definition, dictionary)
|
DefinitionWrapper.add_def(definition, dictionary, fail_fails=True)
|
||||||
return stack, expression, dictionary
|
return stack, expression, dictionary
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -652,6 +656,7 @@ def reverse(S):
|
||||||
|
|
||||||
|
|
||||||
@inscribe
|
@inscribe
|
||||||
|
@combinator_effect(_COMB_NUMS(), s7, s6)
|
||||||
@SimpleFunctionWrapper
|
@SimpleFunctionWrapper
|
||||||
def concat_(S):
|
def concat_(S):
|
||||||
'''Concatinate the two lists on the top of the stack.
|
'''Concatinate the two lists on the top of the stack.
|
||||||
|
|
@ -982,7 +987,7 @@ def infra(stack, expression, dictionary):
|
||||||
|
|
||||||
|
|
||||||
@inscribe
|
@inscribe
|
||||||
@combinator_effect(_COMB_NUMS(), s7, s6, s5, s4)
|
#@combinator_effect(_COMB_NUMS(), s7, s6, s5, s4)
|
||||||
@FunctionWrapper
|
@FunctionWrapper
|
||||||
def genrec(stack, expression, dictionary):
|
def genrec(stack, expression, dictionary):
|
||||||
'''
|
'''
|
||||||
|
|
@ -1396,7 +1401,7 @@ def times(stack, expression, dictionary):
|
||||||
|
|
||||||
|
|
||||||
@inscribe
|
@inscribe
|
||||||
@combinator_effect(_COMB_NUMS(), b1, s6)
|
#@combinator_effect(_COMB_NUMS(), b1, s6)
|
||||||
@FunctionWrapper
|
@FunctionWrapper
|
||||||
def loop(stack, expression, dictionary):
|
def loop(stack, expression, dictionary):
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,15 @@
|
||||||
# -*- coding: utf_8
|
# -*- coding: utf_8
|
||||||
'''
|
|
||||||
|
|
||||||
Multiple Stack Effects
|
|
||||||
|
|
||||||
By adjusting the machinery in types.py to handles lists of stack effect comments
|
|
||||||
we can capture more information about the type signatures of some functions,
|
|
||||||
and we can introduce a kind of Kleene Star or sequence type that can stand for
|
|
||||||
an unbounded sequence of other types.
|
|
||||||
|
|
||||||
'''
|
|
||||||
import sys
|
|
||||||
import joy.library
|
|
||||||
from joy.parser import Symbol, text_to_expression
|
|
||||||
from joy.utils.stack import (
|
|
||||||
concat as CONCAT,
|
|
||||||
expression_to_string,
|
|
||||||
list_to_stack,
|
|
||||||
)
|
|
||||||
|
|
||||||
average =
|
|
||||||
# sum_ =
|
|
||||||
# product =
|
|
||||||
# min_ = max_ = [(((Ns[1], s1), s0), (n0, s0))]
|
|
||||||
# flatten = [(((Ss[1], s1), s0), (s2, s0))]
|
|
||||||
|
|
||||||
return {
|
|
||||||
name.rstrip('_'): stack_effect
|
|
||||||
for name, stack_effect in locals().iteritems()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FUNCTIONS.update({
|
|
||||||
name: SymbolJoyType(name, stack_effect, i)
|
|
||||||
for i, (name, stack_effect) in enumerate(defs().iteritems())
|
|
||||||
})
|
|
||||||
FUNCTIONS.update({
|
|
||||||
combo.__name__: CombinatorJoyType(combo.__name__, [combo], i)
|
|
||||||
for i, combo in enumerate((
|
|
||||||
joy.library.concat_,
|
|
||||||
joy.library._dictionary['disenstacken'],
|
|
||||||
joy.library.x,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def branch_true(stack, expression, dictionary):
|
|
||||||
(then, (else_, (flag, stack))) = stack
|
|
||||||
return stack, CONCAT(then, expression), dictionary
|
|
||||||
|
|
||||||
def branch_false(stack, expression, dictionary):
|
|
||||||
(then, (else_, (flag, stack))) = stack
|
|
||||||
return stack, CONCAT(else_, expression), dictionary
|
|
||||||
|
|
||||||
FUNCTIONS['branch'] = CombinatorJoyType('branch', [branch_true, branch_false], 100)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pop = FUNCTIONS['pop']
|
pop = FUNCTIONS['pop']
|
||||||
|
|
||||||
def loop_true(stack, expression, dictionary):
|
def loop_true(stack, expression, dictionary):
|
||||||
|
|
@ -70,41 +27,42 @@ def loop_false(stack, expression, dictionary):
|
||||||
FUNCTIONS['loop'] = CombinatorJoyType('loop', [loop_two_true, loop_true, loop_false], 101)
|
FUNCTIONS['loop'] = CombinatorJoyType('loop', [loop_two_true, loop_true, loop_false], 101)
|
||||||
|
|
||||||
|
|
||||||
joy.library.add_aliases(FUNCTIONS, joy.library.ALIASES)
|
|
||||||
|
|
||||||
|
|
||||||
def set_expectations_of_definition(cjt):
|
|
||||||
if len(cjt.stack_effects) != 1:
|
|
||||||
raise ValueError
|
|
||||||
defi = cjt.stack_effects[0]
|
|
||||||
if not isinstance(defi, joy.library.DefinitionWrapper):
|
|
||||||
raise ValueError
|
|
||||||
F = infer_expression(defi.body)
|
|
||||||
assert len(F) == 1, repr(F)
|
|
||||||
fi, fo = F[0]
|
|
||||||
cjt.expect = fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def set_expectations():
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# joy.library.add_aliases(FUNCTIONS, joy.library.ALIASES)
|
||||||
|
|
||||||
|
|
||||||
|
# def set_expectations_of_definition(cjt):
|
||||||
|
# if len(cjt.stack_effects) != 1:
|
||||||
|
# raise ValueError
|
||||||
|
# defi = cjt.stack_effects[0]
|
||||||
|
# if not isinstance(defi, joy.library.DefinitionWrapper):
|
||||||
|
# raise ValueError
|
||||||
|
# F = infer_expression(defi.body)
|
||||||
|
# assert len(F) == 1, repr(F)
|
||||||
|
# fi, fo = F[0]
|
||||||
|
# cjt.expect = fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
average =
|
||||||
loop.expect = s6, (b1, s5)
|
loop.expect = s6, (b1, s5)
|
||||||
# i.expect = nullary.expect = x.expect = s7, s6
|
|
||||||
# dip.expect = dupdip.expect = s8, (a8, s7)
|
|
||||||
# dipd.expect = s8, (a8, (a7, s7))
|
|
||||||
# dipdd.expect = s8, (a8, (a7, (a6, s7)))
|
|
||||||
concat_.expect = s8, (s7, s6)
|
|
||||||
# b.expect = infra.expect = s8, (s7, s6)
|
|
||||||
# set_expectations_of_definition(unary)
|
|
||||||
# set_expectations_of_definition(binary)
|
|
||||||
# set_expectations_of_definition(ternary)
|
|
||||||
# set_expectations_of_definition(quoted)
|
|
||||||
# set_expectations_of_definition(unquoted)
|
|
||||||
# set_expectations_of_definition(enstacken)
|
|
||||||
disenstacken.expect = (As[1], s1), s0
|
disenstacken.expect = (As[1], s1), s0
|
||||||
scope = globals().copy()
|
joy.library._dictionary['disenstacken'],
|
||||||
scope.update(FUNCTIONS)
|
|
||||||
eval(set_expectations.func_code, scope)
|
|
||||||
del scope
|
# scope = globals().copy()
|
||||||
|
# scope.update(FUNCTIONS)
|
||||||
|
# eval(set_expectations.func_code, scope)
|
||||||
|
# del scope
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue