コード例 #1
0
ファイル: expander.py プロジェクト: mythmon/monte
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")))
    ])
コード例 #2
0
ファイル: expander.py プロジェクト: mythmon/monte
def expandOr(left, right, success, failure, leftmap, rightmap):
    broken = mcall("__booleanFlow", "broken")

    def partialFail(failed):
        return t.SeqExpr(
            [t.Def(t.BindingPattern(n), None, broken)
             for n in failed] + [success])

    rightOnly = [t.NounExpr(n) for n in rightmap - leftmap]
    leftOnly = [t.NounExpr(n) for n in leftmap - rightmap]
    return t.If(left, partialFail(rightOnly),
                t.If(right, partialFail(leftOnly), failure))
コード例 #3
0
ファイル: expander.py プロジェクト: mythmon/monte
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
    ])
コード例 #4
0
ファイル: expander.py プロジェクト: mythmon/monte
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)
コード例 #5
0
ファイル: compiler.py プロジェクト: mythmon/monte
 def getBinding(self, n, default=_absent):
     if n in self.outers:
         return Binding(t.FinalPattern(t.NounExpr(n), None),
                        '_m_outerScope["%s"]' % n, None, OUTER)
     else:
         if default is _absent:
             raise CompileError("No global named " + repr(n))
         else:
             return default
コード例 #6
0
ファイル: expander.py プロジェクト: mythmon/monte
def reifyNoun(self, base, o):
    k = (base, o)
    if k in self.cache:
        return self.cache[k]

    self.id += 1
    noun = "%s__%s" % (base, self.id)
    while noun in self.nouns:
        self.id += 1
        noun = "%s__%s" % (base, self.id)
    self.nouns.add(noun)
    n = t.NounExpr(noun)
    self.cache[k] = n
    return n
コード例 #7
0
ファイル: expander.py プロジェクト: mythmon/monte
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)
コード例 #8
0
ファイル: expander.py プロジェクト: mythmon/monte
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
    ])
コード例 #9
0
ファイル: expander.py プロジェクト: mythmon/monte
def slotpatt(n):
    return t.ViaPattern(t.NounExpr("__slotToBinding"), t.BindingPattern(n))
コード例 #10
0
ファイル: expander.py プロジェクト: mythmon/monte
def mcall(noun, verb, *expr):
    return t.MethodCallExpr(t.NounExpr(noun), verb, expr)
コード例 #11
0
ファイル: expander.py プロジェクト: mythmon/monte
from ometa.grammar import TreeTransformerGrammar
from ometa.runtime import TreeTransformerBase, ParseError
from terml.nodes import Tag, Term, termMaker as t
### XXX TODO: Create TemporaryExprs for variables generated by
### expansion. Replace all temps with nouns in a single pass at the
### end.

TRUE = t.NounExpr('true')  #Term(Tag('true'), None, None, None)
FALSE = t.NounExpr('false')  #Term(Tag('false'), None, None, None)


class ScopeSet(object):
    def __init__(self, bits=()):
        self.contents = list(bits)[:]

    def __sub__(self, other):
        bits = self.contents[:]
        for bit in other:
            if bit in bits:
                bits[bits.index(bit)] = bits[-1]
                del bits[-1]
        return ScopeSet(bits)

    def __and__(self, other):
        if len(self) > len(other):
            big = self.contents
            small = list(other)
        else:
            small = self.contents
            big = list(other)
        bits = []