Trying to add a guard to combinators.
So they can notice if they're given a stack that doesn't match what they're expecting. This seems to work, but I realized that type variables in the pending expression need to be update()'d too. hmm...
This commit is contained in:
parent
bbc0fae2e9
commit
db28989b64
|
|
@ -10,8 +10,6 @@ an unbounded sequence of other types.
|
||||||
'''
|
'''
|
||||||
from itertools import chain, product
|
from itertools import chain, product
|
||||||
|
|
||||||
import sys
|
|
||||||
sys.path.append('/home/sforman/Desktop/Joypy-hg')
|
|
||||||
import joy.library
|
import joy.library
|
||||||
from joy.parser import Symbol
|
from joy.parser import Symbol
|
||||||
from joy.utils.stack import concat as CONCAT
|
from joy.utils.stack import concat as CONCAT
|
||||||
|
|
@ -109,7 +107,24 @@ class FunctionJoyType(AnyJoyType):
|
||||||
|
|
||||||
|
|
||||||
class SymbolJoyType(FunctionJoyType): prefix = 'F'
|
class SymbolJoyType(FunctionJoyType): prefix = 'F'
|
||||||
class CombinatorJoyType(FunctionJoyType): prefix = 'C'
|
|
||||||
|
|
||||||
|
class CombinatorJoyType(FunctionJoyType):
|
||||||
|
|
||||||
|
prefix = 'C'
|
||||||
|
|
||||||
|
def __init__(self, name, sec, number, expect=None):
|
||||||
|
super(CombinatorJoyType, self).__init__(name, sec, number)
|
||||||
|
self.expect = expect
|
||||||
|
|
||||||
|
def enter_guard(self, f):
|
||||||
|
if self.expect is None:
|
||||||
|
return f
|
||||||
|
g = self.expect, self.expect
|
||||||
|
new_f = list(C(f, g))
|
||||||
|
assert len(new_f) == 1, repr(new_f)
|
||||||
|
return new_f[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def unify(u, v, s=None):
|
def unify(u, v, s=None):
|
||||||
|
|
@ -224,10 +239,14 @@ def infer(e, F=ID):
|
||||||
res = flatten(infer(e, Fn) for Fn in MC([F], n.stack_effects))
|
res = flatten(infer(e, Fn) for Fn in MC([F], n.stack_effects))
|
||||||
|
|
||||||
elif isinstance(n, CombinatorJoyType):
|
elif isinstance(n, CombinatorJoyType):
|
||||||
|
fi, fo = n.enter_guard(F)
|
||||||
res = []
|
res = []
|
||||||
for combinator in n.stack_effects:
|
for combinator in n.stack_effects:
|
||||||
fi, fo = F
|
print fo
|
||||||
|
print e
|
||||||
new_fo, ee, _ = combinator(fo, e, {})
|
new_fo, ee, _ = combinator(fo, e, {})
|
||||||
|
print new_fo
|
||||||
|
print ee
|
||||||
ee = update(FUNCTIONS, ee) # Fix Symbols.
|
ee = update(FUNCTIONS, ee) # Fix Symbols.
|
||||||
new_F = fi, new_fo
|
new_F = fi, new_fo
|
||||||
res.extend(infer(ee, new_F))
|
res.extend(infer(ee, new_F))
|
||||||
|
|
@ -294,6 +313,10 @@ FUNCTIONS['branch'] = CombinatorJoyType('branch', [branch_true, branch_false], 1
|
||||||
|
|
||||||
globals().update(FUNCTIONS)
|
globals().update(FUNCTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
dip.expect = s8, (a8, s7)
|
||||||
|
|
||||||
|
|
||||||
def _ge(self, other):
|
def _ge(self, other):
|
||||||
return (issubclass(other.__class__, self.__class__)
|
return (issubclass(other.__class__, self.__class__)
|
||||||
or hasattr(self, 'accept')
|
or hasattr(self, 'accept')
|
||||||
|
|
@ -304,40 +327,41 @@ AnyJoyType.accept = tuple, int, float, long, str, unicode, bool, Symbol
|
||||||
StackJoyType.accept = tuple
|
StackJoyType.accept = tuple
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
##if __name__ == '__main__':
|
||||||
|
##
|
||||||
from joy.parser import text_to_expression
|
## from joy.parser import text_to_expression
|
||||||
from joy.utils.stack import list_to_stack as l2s
|
## from joy.utils.stack import list_to_stack as l2s
|
||||||
|
##
|
||||||
|
##
|
||||||
F = infer(l2s((pop, pop, pop)))
|
## F = infer(l2s((pop, pop, pop)))
|
||||||
for f in F:
|
## for f in F:
|
||||||
print doc_from_stack_effect(*f)
|
## print doc_from_stack_effect(*f)
|
||||||
s = text_to_expression('0 1 2')
|
## s = text_to_expression('0 1 2')
|
||||||
L = unify(s, F[0][0])
|
## L = unify(s, F[0][0])
|
||||||
print L
|
## print L
|
||||||
|
##
|
||||||
print
|
## print
|
||||||
|
##
|
||||||
F = infer(l2s((pop, swap, rolldown, rest, rest, cons, cons)))
|
## F = infer(l2s((pop, swap, rolldown, rest, rest, cons, cons)))
|
||||||
for f in F:
|
## for f in F:
|
||||||
print doc_from_stack_effect(*f)
|
## print doc_from_stack_effect(*f)
|
||||||
s = text_to_expression('0 1 2 [3 4]')
|
## s = text_to_expression('0 1 2 [3 4]')
|
||||||
L = unify(s, F[0][0])
|
## L = unify(s, F[0][0])
|
||||||
print L
|
## print L
|
||||||
print
|
## print
|
||||||
|
##
|
||||||
g = update(L[0], F[0])
|
## g = update(L[0], F[0])
|
||||||
print doc_from_stack_effect(*g)
|
## print doc_from_stack_effect(*g)
|
||||||
print g
|
## print g
|
||||||
|
##
|
||||||
|
##
|
||||||
print '- - - - - -'
|
## print '- - - - - -'
|
||||||
s = text_to_expression('[3 4]')
|
## s = text_to_expression('[3 4]')
|
||||||
L = unify(s, F[0][1])
|
## L = unify(s, F[0][1])
|
||||||
print L
|
## print L
|
||||||
print
|
## print
|
||||||
|
##
|
||||||
g = update(L[0], F[0])
|
## g = update(L[0], F[0])
|
||||||
print doc_from_stack_effect(*g)
|
## print doc_from_stack_effect(*g)
|
||||||
print g
|
## print g
|
||||||
|
##
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,15 @@ class TestCombinators(TestMixin, unittest.TestCase):
|
||||||
self.assertEqualTypeStructure(infr(expression), f)
|
self.assertEqualTypeStructure(infr(expression), f)
|
||||||
|
|
||||||
def test_cons_dip(self):
|
def test_cons_dip(self):
|
||||||
expression = a1, (cons, s0), dip # a1 [cons] dip
|
expression = (cons, s0), dip # [cons] dip
|
||||||
# (a0 [...0] -- [a0 ...0] a1)
|
# (a2 [...1] a1 -- [a2 ...1] a3)
|
||||||
f = ((s0, (a0, s1)), (a1, ((a0, s0), s1)))
|
f = (a1, (s1, (a2, s2))), (a1, ((a2, s1), s2))
|
||||||
|
# shouldn't a3 be a1?
|
||||||
|
self.assertEqualTypeStructure(infr(expression), [f])
|
||||||
|
|
||||||
|
def test_dip(self):
|
||||||
|
expression = dip,
|
||||||
|
f = ((s1, (a1, s2)), (a2, s2)) # (a1 [...1] -- a2)
|
||||||
self.assertEqualTypeStructure(infr(expression), [f])
|
self.assertEqualTypeStructure(infr(expression), [f])
|
||||||
|
|
||||||
def test_cons_dipd(self):
|
def test_cons_dipd(self):
|
||||||
|
|
@ -163,4 +169,4 @@ class TestYin(TestMixin, unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main(defaultTest='TestCombinators.test_cons_dip')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue