def build_rule(l, r, cons=None): lpat = [] rpat = [] sym = set() cons = cons or {} for pat, bind, ty in free(l): if bind in sym: # TODO unify ty lpat.append(bind) else: lpat.append(bind) sym.add(bind) for pat, bind, ty in free(r): if bind in sym: rpat.append(bind) else: raise Exception('Unbound variable: %s' % pat) left = freev(l) right = freev(r) ana = partial(unfold, lpat, left) cata = partial(fold, rpat, right) rr = partial(hylo, ana, cata) return Rule(lpat, rpat, left, right, rr)
def main(): parser = argparse.ArgumentParser() parser.add_argument('module', nargs='?', help='Module') parser.add_argument('--noprelude', action='store_true', help='Include prelude') args = parser.parse_args() # State mod = {} last = None bindings = {} if args.module: with open(args.module) as fd: mod = module(fd.read()) if not args.noprelude: mod.update(prelude) print banner readline.parse_and_bind("tab: complete") readline.set_completer(partial(completer, mod)) while True: try: line = raw_input('>> ').strip() except EOFError: break #----------------------------------------------- if line.startswith('?'): at = aparse(line[1:]) matcher = partial(match, freev(at)) matched, localbind = matcher(last) # TODO: Use dict #bindings.update(localbind) #if matched: # print bindings #else: # print 'failed' #----------------------------------------------- elif line.startswith('!'): try: rr = mod[line[1:].strip()] last = rr.rewrite(last) print last except KeyError: print "No such rule or strategy '%s'" % line[1:] except NoMatch: print 'failed' #----------------------------------------------- elif line.startswith(':show') or line.startswith(':s'): try: rr = mod[line[1:].strip()] print rr except KeyError: print "No such rule or strategy '%s'" % line[1:] #----------------------------------------------- elif line.startswith(':type') or line.startswith(':t'): try: at = aparse(line[2:]) print type(at).__name__ except Exception as e: print e #----------------------------------------------- elif line.startswith(':bindings'): if bindings: pprint.pprint(bindings) continue #----------------------------------------------- elif line.startswith(':let'): env = module(line[4:], _env=mod) mod.update(env) #----------------------------------------------- elif line.startswith(':load'): fname = line[5:].strip() try: contents = open(fname).read() mod.update(module(contents)) except IOError: print "No such module", fname #----------------------------------------------- elif line.startswith(':browse'): pprint.pprint(mod) #----------------------------------------------- elif line.startswith(':help'): print help pass #----------------------------------------------- else: bindings = {} try: last = aparse(line) print last except EOFError: pass except Exception as e: print traceback.format_exc()