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.parser import Symbol
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ codireco == cons dip rest cons
|
|||
make_generator == [codireco] ccons
|
||||
ifte == [nullary not] dipd branch
|
||||
'''
|
||||
#
|
||||
#
|
||||
# ifte == [nullary] dipd swap branch
|
||||
# genrec == [[genrec] cons cons cons cons] nullary swons concat ifte
|
||||
|
|
@ -365,17 +366,20 @@ class DefinitionWrapper(object):
|
|||
class_.add_def(definition, dictionary)
|
||||
|
||||
@classmethod
|
||||
def add_def(class_, definition, dictionary):
|
||||
def add_def(class_, definition, dictionary, fail_fails=False):
|
||||
'''
|
||||
Add the definition to the dictionary.
|
||||
'''
|
||||
F = class_.parse_definition(definition)
|
||||
try:
|
||||
#print F._body
|
||||
# print F.name, F._body
|
||||
secs = infer(*F._body)
|
||||
except JoyTypeError:
|
||||
pass
|
||||
print F.name, '==', expression_to_string(F.body), ' --failed to infer stack effect.'
|
||||
if fail_fails:
|
||||
print 'Function not inscribed.'
|
||||
return
|
||||
else:
|
||||
FUNCTIONS[F.name] = SymbolJoyType(F.name, secs, _SYM_NUMS())
|
||||
dictionary[F.name] = F
|
||||
|
|
@ -405,7 +409,7 @@ def inscribe_(stack, expression, dictionary):
|
|||
the definitions.txt resource.
|
||||
'''
|
||||
definition, stack = stack
|
||||
DefinitionWrapper.add_def(definition, dictionary)
|
||||
DefinitionWrapper.add_def(definition, dictionary, fail_fails=True)
|
||||
return stack, expression, dictionary
|
||||
|
||||
|
||||
|
|
@ -652,6 +656,7 @@ def reverse(S):
|
|||
|
||||
|
||||
@inscribe
|
||||
@combinator_effect(_COMB_NUMS(), s7, s6)
|
||||
@SimpleFunctionWrapper
|
||||
def concat_(S):
|
||||
'''Concatinate the two lists on the top of the stack.
|
||||
|
|
@ -982,7 +987,7 @@ def infra(stack, expression, dictionary):
|
|||
|
||||
|
||||
@inscribe
|
||||
@combinator_effect(_COMB_NUMS(), s7, s6, s5, s4)
|
||||
#@combinator_effect(_COMB_NUMS(), s7, s6, s5, s4)
|
||||
@FunctionWrapper
|
||||
def genrec(stack, expression, dictionary):
|
||||
'''
|
||||
|
|
@ -1396,7 +1401,7 @@ def times(stack, expression, dictionary):
|
|||
|
||||
|
||||
@inscribe
|
||||
@combinator_effect(_COMB_NUMS(), b1, s6)
|
||||
#@combinator_effect(_COMB_NUMS(), b1, s6)
|
||||
@FunctionWrapper
|
||||
def loop(stack, expression, dictionary):
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -1,58 +1,15 @@
|
|||
# -*- 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']
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
# 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
|
||||
scope = globals().copy()
|
||||
scope.update(FUNCTIONS)
|
||||
eval(set_expectations.func_code, scope)
|
||||
del scope
|
||||
joy.library._dictionary['disenstacken'],
|
||||
|
||||
|
||||
# scope = globals().copy()
|
||||
# scope.update(FUNCTIONS)
|
||||
# eval(set_expectations.func_code, scope)
|
||||
# del scope
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue