def expandFor(self, key, value, coll, block, catcher): if key.tag.name == "null": key = t.IgnorePattern(None) validateFor(self, scope(key).add(scope(value)), scope(coll)) fTemp = self.mktemp("validFlag") kTemp = self.mktemp("key") vTemp = self.mktemp("value") obj = t.Object( "For-loop body", t.IgnorePattern(None), t.Script(None, None, [], [ t.Method( None, "run", [t.FinalPattern(kTemp, None), t.FinalPattern(vTemp, None)], None, t.SeqExpr([ mcall("__validateFor", "run", fTemp), t.Escape( t.FinalPattern(t.NounExpr("__continue"), None), t.SeqExpr([ t.Def(key, None, kTemp), t.Def(value, None, vTemp), block, t.NounExpr("null") ]), None) ])) ], [])) return t.Escape( t.FinalPattern(t.NounExpr("__break"), None), t.SeqExpr([ t.Def(t.VarPattern(fTemp, None), None, t.NounExpr("true")), t.Finally( t.MethodCallExpr(t.NounExpr("__loop"), "run", [coll, obj]), t.Assign(fTemp, t.NounExpr("false"))), t.NounExpr("null") ]), catcher)
def expandComprehension(self, key, value, coll, filtr, exp, collector): if key is None: key = t.IgnorePattern(None) validateFor(self, scope(exp), scope(coll)) validateFor(self, scope(key).add(scope(value)), scope(coll)) fTemp = self.mktemp("validFlag") kTemp = self.mktemp("key") vTemp = self.mktemp("value") skip = self.mktemp("skip") value = t.SeqExpr( [t.Def(key, None, kTemp), t.Def(value, None, vTemp), exp]) if filtr: value = t.If(filtr, value, t.MethodCallExpr(skip, "run", [])) obj = t.Object( "For-loop body", t.IgnorePattern(None), t.Script(None, None, [], [ t.Method(None, "run", [ t.FinalPattern(kTemp, None), t.FinalPattern(vTemp, None), t.FinalPattern(skip, None) ], None, t.SeqExpr([mcall("__validateFor", "run", fTemp), value])) ], [])) return t.SeqExpr([ t.Def(t.VarPattern(fTemp, None), None, t.NounExpr("true")), t.Finally(t.MethodCallExpr(t.NounExpr(collector), "run", [coll, obj]), t.Assign(fTemp, t.NounExpr("false"))) ])
def matchExpr(self, matchers, sp, failures): ejs = [self.mktemp("ej") for _ in matchers] block = mcall("__switchFailed", "run", sp, *failures) for m, fail, ej in reversed(zip(matchers, failures, ejs)): block = t.Escape(t.FinalPattern(ej, None), t.SeqExpr([t.Def(m.args[0], ej, sp), m.args[1]]), t.Catch(t.FinalPattern(fail, None), block)) return block
def expandSwitch(self, expr, matchers): sp = self.mktemp("specimen") failures = [self.mktemp("failure") for _ in matchers] return t.HideExpr( t.SeqExpr([ t.Def(t.FinalPattern(sp, None), None, expr), matchExpr(self, matchers, sp, failures) ]))
def expandCallVerbAssign(self, verb, args, receiver, methVerb, methArgs): r = self.mktemp("recip") prelude = t.Def(t.FinalPattern(r, None), None, receiver) seq = [prelude] setArgs = [] for arg in methArgs.args: a = self.mktemp("arg") seq.append(t.Def(t.FinalPattern(a, None), None, arg)) setArgs.append(a) seq.extend( self.apply("transform", [ t.Assign( t.MethodCallExpr(r, methVerb, setArgs), t.MethodCallExpr(t.MethodCallExpr(r, methVerb, setArgs), verb, args)) ])[0][0].args[0].args) return t.SeqExpr(seq)
def expandDef(self, patt, optEj, rval, nouns): pattScope = scope(patt) defPatts = pattScope.defNames varPatts = pattScope.varNames rvalScope = scope(rval) if optEj: rvalScope = scope(optEj).add(rvalScope) rvalUsed = rvalScope.namesUsed() if len(varPatts & rvalUsed) != 0: err("Circular 'var' definition not allowed", self) if len(pattScope.namesUsed() & rvalScope.outNames()) != 0: err("Pattern may not use var defined on the right", self) conflicts = defPatts & rvalUsed if len(conflicts) == 0: return t.Def(patt, optEj, rval) else: promises = [] resolves = [] renamings = {} for oldNameStr in conflicts.getKeys(): newName = self.mktemp(oldNameStr) newNameR = self.mktemp(oldNameStr + "R") renamings[oldNameStr] = newName # def [newName, newNameR] := Ref.promise() pair = [ t.FinalPattern(newName, None), t.FinalPattern(newNameR, None) ] promises.append( t.Def(t.ListPattern(pair, None), None, mcall("Ref", "promise"))) resolves.append( t.MethodCallExpr(newNameR, "resolve", [t.NounExpr(oldNameStr)])) resName = self.mktemp("value") resolves.append(resName) cr = CycleRenamer([rval]) cr.renamings = renamings rval = cr.apply("transform")[0] resPatt = t.FinalPattern(resName, None) resDef = t.Def(resPatt, None, t.Def(patt, optEj, rval)) return t.SeqExpr(promises + [resDef] + resolves)
def expandInterface(doco, name, nameStr, guard, extends, implements, script): return t.Def( name, None, t.HideExpr( mcall( "__makeProtocolDesc", "run", doco and t.LiteralExpr(doco), t.MethodCallExpr( t.MethodCallExpr(t.Meta("context"), "getFQNPrefix", []), "add", [t.LiteralExpr(nameStr + "__T")]), mcall("__makeList", "run", *extends), mcall("__makeList", "run", *implements), mcall("__makeList", "run", *script))))
def expandMatchBind(self, spec, patt): pattScope = scope(patt) specScope = scope(spec) conflicts = pattScope.outNames() & specScope.namesUsed() if conflicts: err( "Use on left isn't really in scope of matchbind pattern: %s" % (', '.join(conflicts)), self) sp = self.mktemp("sp") ejector = self.mktemp("fail") result = self.mktemp("ok") problem = self.mktemp("problem") broken = self.mktemp("b") patternNouns = [t.NounExpr(n) for n in pattScope.outNames()] return t.SeqExpr([ t.Def(t.FinalPattern(sp, None), None, spec), t.Def( t.ListPattern([t.FinalPattern(result, None)] + [t.BindingPattern(n) for n in patternNouns], None), None, t.Escape( t.FinalPattern(ejector, None), t.SeqExpr([ t.Def(patt, ejector, sp), mcall("__makeList", "run", TRUE, *[t.BindingExpr(n) for n in patternNouns]) ]), t.Catch( t.FinalPattern(problem, None), t.SeqExpr([ t.Def(slotpatt(broken), None, mcall("Ref", "broken", problem)), mcall("__makeList", "run", FALSE, *([t.BindingExpr(broken)] * len(patternNouns))) ])))), result ])
def expandLogical(self, left, right, fn): leftmap = scope(left).outNames() rightmap = scope(right).outNames() both = [t.NounExpr(n) for n in leftmap | rightmap] result = self.mktemp("ok") success = t.MethodCallExpr(t.NounExpr("__makeList"), "run", [TRUE] + [t.BindingExpr(n) for n in both]) failure = t.MethodCallExpr(t.NounExpr("__booleanFlow"), "failureList", [t.LiteralExpr(len(both))]) return t.SeqExpr([ t.Def( t.ListPattern([t.FinalPattern(result, None)] + [t.BindingPattern(n) for n in both], None), None, fn(left, right, success, failure, leftmap, rightmap)), result ])
def broke(br, ex): return t.Def(t.FinalPattern(br, None), mcall("Ref", "broken", mcall("__makeList", "run", ex)))
def partialFail(failed): return t.SeqExpr( [t.Def(t.BindingPattern(n), None, broken) for n in failed] + [success])