예제 #1
0
파일: tlform.py 프로젝트: mamysa/PyPltRedex
    def run(self):
        self.modulebuilder.IncludeFromPythonSource('runtime/term.py')
        self.modulebuilder.IncludeFromPythonSource('runtime/parser.py')
        self.modulebuilder.IncludeFromPythonSource('runtime/fresh.py')
        self.modulebuilder.IncludeFromPythonSource('runtime/match.py')

        # parse all term literals.
        # ~~ 26.07.2020 disable lit terms for now, need to implement
        # nt caching acceleration technique first.
        """
        tmp0, tmp1 = rpy.gen_pyid_temporaries(2, self.symgen)
        for trm, sym1 in self.context._litterms.items():
            sym1 = rpy.gen_pyid_for(sym1)
            self.modulebuilder.AssignTo(tmp0).New('Parser', rpy.PyString(repr(trm)))
            self.modulebuilder.AssignTo(sym1).MethodCall(tmp0, 'parse')
        """

        # variable-not-otherwise-mentioned of given define language
        for ident, variables in self.context.get_variables_mentioned_all():
            ident = rpy.gen_pyid_for(ident)
            variables = map(lambda v: rpy.PyString(v), variables)
            self.modulebuilder.AssignTo(ident).PySet(*variables)

        for form in self.module.tlforms:
            self._visit(form)

        # generate main
        fb = rpy.BlockBuilder()
        symgen = SymGen()
        ## emit some dummy Terms to aid RPython with type inference.
        tmp0, tmp1, tmp2, tmp3, tmp4 = rpy.gen_pyid_temporaries(5, symgen)
        fb.AssignTo(tmp0).New('Integer', rpy.PyInt(0))
        fb.AssignTo(tmp1).New('Float', rpy.PyFloat(0.0))
        fb.AssignTo(tmp2).New('String', rpy.PyString("\"hello world!\""))
        fb.AssignTo(tmp3).New('Boolean', rpy.PyString("#f"))
        fb.AssignTo(tmp4).New('Variable', rpy.PyString("x"))
        for procedure in self.main_procedurecalls:
            tmpi = rpy.gen_pyid_temporaries(1, symgen)
            fb.AssignTo(tmpi).FunctionCall(procedure)
        fb.Return(rpy.PyInt(0))
        self.modulebuilder.Function('entrypoint').WithParameters(
            rpy.PyId('argv')).Block(fb)

        #required entry procedure for Rpython.

        fb = rpy.BlockBuilder()
        fb.Return(rpy.PyTuple(rpy.PyId('entrypoint'), rpy.PyNone()))
        self.modulebuilder.Function('target').WithParameters(
            rpy.PyVarArg('args')).Block(fb)

        # if __name__ == '__main__': entrypoint()
        # for python2.7 compatibility.
        ifb = rpy.BlockBuilder()
        tmp = rpy.gen_pyid_temporaries(1, self.symgen)
        ifb.AssignTo(tmp).FunctionCall('entrypoint', rpy.PyList())
        self.modulebuilder.If.Equal(rpy.PyId('__name__'),
                                    rpy.PyString('__main__')).ThenBlock(ifb)

        return rpy.Module(self.modulebuilder.build())
예제 #2
0
    def _gen_match_function_for_primitive(self, functionname, isafunction, patstr, sym=None):
        # tmp0 = asafunction(term)
        # if tmp0 == True:
        #   tmp1 = match.addtobinding(sym, term) # this is optional of sym != None; useful for holes.
        #   head = head + 1
        #   return [(match, head, tail)]
        # return []
        symgen = SymGen()
        term, match, head, tail = rpy.gen_pyid_for('term', 'match', 'head', 'tail')
        tmp0, tmp1 = rpy.gen_pyid_temporaries(2, symgen)

        ifb1 = rpy.BlockBuilder()
        if sym is not None:
            ifb1.AssignTo(tmp0).MethodCall(match, MatchMethodTable.AddToBinding, rpy.PyString(sym), term)
        ifb1.AssignTo(head).Add(head, rpy.PyInt(1))
        ifb1.Return(rpy.PyList( rpy.PyTuple(match, head, tail) ))

        fb = rpy.BlockBuilder()
        fb.AssignTo(tmp0).FunctionCall(isafunction, term)
        fb.If.Equal(tmp0, rpy.PyBoolean(True)).ThenBlock(ifb1)
        fb.Return(rpy.PyList())

        self.modulebuilder.SingleLineComment(patstr)
        self.modulebuilder.Function(functionname).WithParameters(term, match, head, tail).Block(fb)
예제 #3
0
파일: tlform.py 프로젝트: mamysa/PyPltRedex
    def _visitReadFromStdinAndApplyReductionRelation(self, form):
        assert isinstance(form, tlform.ReadFromStdinAndApplyReductionRelation)

        reduction_relation_func = self.context.get_reduction_relation(
            form.reductionrelationname)
        symgen = SymGen()
        term = rpy.gen_pyid_for('term')
        tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 = rpy.gen_pyid_temporaries(
            8, symgen)

        forb = rpy.BlockBuilder()
        forb.AssignTo(tmp3).FunctionCall(reduction_relation_func, term)
        forb.AssignTo(tmp2).Add(tmp2, tmp3)

        wh = rpy.BlockBuilder()
        wh.AssignTo(tmp2).PyList()
        wh.For(term).In(tmp1).Block(forb)
        wh.AssignTo(tmp1).PyId(tmp2)
        wh.AssignTo(tmp4).FunctionCall(TermHelperFuncs.PrintTermList, tmp1)

        fb = rpy.BlockBuilder()
        fb.AssignTo(tmp0).FunctionCall(ReadFromStdinAndParse)
        if form.metafunctionname != None:
            mfname = self.context.get_metafunction(form.metafunctionname)
            fb.AssignTo(tmp5).New('Variable',
                                  rpy.PyString(form.metafunctionname))
            fb.AssignTo(tmp6).New('Sequence', rpy.PyList(tmp5, tmp0))
            fb.AssignTo(tmp0).FunctionCall(mfname, tmp6)

        fb.AssignTo(tmp1).PyList(tmp0)
        fb.AssignTo(tmp4).FunctionCall(TermHelperFuncs.PrintTermList, tmp1)
        fb.While.LengthOf(tmp1).NotEqual(rpy.PyInt(0)).Block(wh)

        nameof_this_func = self.symgen.get('readfromstdinandeval')
        self.modulebuilder.Function(nameof_this_func).Block(fb)
        self.main_procedurecalls.append(nameof_this_func)

        return form
예제 #4
0
    def transformBuiltInPat(self, pat):
        assert isinstance(pat, pattern.BuiltInPat) 
        if pat.kind == pattern.BuiltInPatKind.Any:
            if self.context.get_function_for_pattern(self.languagename, repr(pat)) is None:
                nameof_this_func = 'match_lang_{}_builtin_{}'.format(self.languagename, self.symgen.get())
                self.context.add_function_for_pattern(self.languagename, repr(pat), nameof_this_func)

                # tmp0 = match.addtobinding(sym, term) 
                # head = head + 1
                # return [(match, head, tail)]
                symgen = SymGen()
                term, match, head, tail = rpy.gen_pyid_for('term', 'match', 'head', 'tail')
                tmp0 = rpy.gen_pyid_temporaries(1, symgen)

                fb = rpy.BlockBuilder()
                fb.AssignTo(tmp0).MethodCall(match, MatchMethodTable.AddToBinding, rpy.PyString(pat.sym), term)
                fb.AssignTo(head).Add(head, rpy.PyInt(1))
                fb.Return(rpy.PyList( rpy.PyTuple(match, head, tail) ))

                self.modulebuilder.SingleLineComment(repr(pat))
                self.modulebuilder.Function(nameof_this_func).WithParameters(term, match, head, tail).Block(fb)
            return pat

        elif pat.kind == pattern.BuiltInPatKind.VariableNotOtherwiseDefined:
            # generate isa function for variable-not-otherwise-mentioned here because we need to reference
            # compile-time generated language-specific array 'langname_variable_mentioned'
            if self.context.get_isa_function_name(self.languagename, pat.prefix) is None:
                nameof_this_func = 'lang_{}_isa_builtin_variable_not_othewise_mentioned'.format(self.languagename)
                self.context.add_isa_function_name(self.languagename, pat.prefix, nameof_this_func)

                symgen = SymGen()
                var, _ = self.context.get_variables_mentioned(self.languagename)
                var = rpy.gen_pyid_for(var)
                term = rpy.gen_pyid_for('term')
                tmp0, tmp1 = rpy.gen_pyid_temporaries(2, symgen)

                fb = rpy.BlockBuilder()
                fb.AssignTo(tmp0).FunctionCall(TermHelperFuncs.TermIsVariableNotOtherwiseMentioned, term, var)
                fb.Return(tmp0)

                self.modulebuilder.SingleLineComment('#Is this term {}?'.format(pat.prefix))
                self.modulebuilder.Function(nameof_this_func).WithParameters(term).Block(fb)
                """
                # tmp0 = term.kind()
                # if tmp0 == TermKind.Variable:
                #   tmp1 = term.value()
                #   if tmp1 not in var:
                #     return True
                # return False
                # This one is different from other built-in isa funcs because we do set membership test here.
                ifb2 = rpy.BlockBuilder()
                ifb2.Return(rpy.PyBoolean(True))

                ifb1 = rpy.BlockBuilder()
                ifb1.AssignTo(tmp1).MethodCall(term, TermMethodTable.Value)
                ifb1.If.NotContains(tmp1).In(var).ThenBlock(ifb2)

                fb = rpy.BlockBuilder()
                fb.If.IsInstance(term, 'Variable').ThenBlock(ifb1)
                fb.Return(rpy.PyBoolean(False))

                self.modulebuilder.SingleLineComment('#Is this term {}?'.format(pat.prefix))
                self.modulebuilder.Function(nameof_this_func).WithParameters(term).Block(fb)
                """

            ##----- generate actual match function
            if self.context.get_function_for_pattern(self.languagename, repr(pat)) is None:
                nameof_this_func = 'match_lang_{}_builtin_{}'.format(self.languagename, self.symgen.get())
                self.context.add_function_for_pattern(self.languagename, repr(pat), nameof_this_func)
                isafunc = self.context.get_isa_function_name(self.languagename, pat.prefix)
                self._gen_match_function_for_primitive(nameof_this_func, isafunc, repr(pat), sym=pat.sym)
            return pat
        else:
            if self.context.get_function_for_pattern(self.languagename, repr(pat)) is None:
                pat_isA_tab = {
                    pattern.BuiltInPatKind.Number:  TermHelperFuncs.TermIsNumber,
                    pattern.BuiltInPatKind.Integer: TermHelperFuncs.TermIsInteger,
                    pattern.BuiltInPatKind.Natural: TermHelperFuncs.TermIsNatural,
                    pattern.BuiltInPatKind.Float:   TermHelperFuncs.TermIsFloat,
                    pattern.BuiltInPatKind.String:  TermHelperFuncs.TermIsString,
                    pattern.BuiltInPatKind.Boolean: TermHelperFuncs.TermIsBoolean,
                    pattern.BuiltInPatKind.Hole:    TermHelperFuncs.TermIsHole,
                }

                try:
                    term_func = pat_isA_tab[pat.kind]
                    nameof_this_func = 'match_lang_{}_builtin_{}'.format(self.languagename, self.symgen.get())
                    self.context.add_function_for_pattern(self.languagename, repr(pat), nameof_this_func)
                    if pat.kind == pattern.BuiltInPatKind.Hole:
                        # 'hole' key is not present in the final Match object.
                        self._gen_match_function_for_primitive(nameof_this_func, term_func, repr(pat))
                    else:
                        self._gen_match_function_for_primitive(nameof_this_func, term_func, repr(pat), sym=pat.sym)
                except KeyError:
                    assert False, 'unsupported pattern' + pat.kind
            return pat
예제 #5
0
    def transformInHole(self, pat):
        assert isinstance(pat, pattern.InHole)
        if not self.context.get_function_for_pattern(self.languagename, repr(pat)):
            functionname = 'lang_{}_builtin_inhole_{}'.format(self.languagename, self.symgen.get())
            self.context.add_function_for_pattern(self.languagename, repr(pat), functionname)
            # 1. Look up all the terms that match pat2. Store (term, [match]) pairs.
            # 2. For each matching term,
            #    1. Replace term with hole
            #    2. Try match pat1. If match is successful, copy term recursively starting from hole, 
            #       and add appropriate binding into matches associated with the term.
            #    3. Replace hole with term to restore the whole term to it's original state.

            pat1, pat2 = pat.pat1, pat.pat2
            self.transform(pat1)
            self.transform(pat2)

            matchpat1 = self.context.get_function_for_pattern(self.languagename, repr(pat1))
            matchpat2 = self.context.get_function_for_pattern(self.languagename, repr(pat2))

            assignable_syms1 = pat1.getattribute(pattern.PatternAttribute.PatternVariables)
            assignable_syms2 = pat2.getattribute(pattern.PatternAttribute.PatternVariables)
            assignable_syms_all = assignable_syms1.union(assignable_syms2)

            # def inhole(term, match, head, tail, path):
            # matches = []
            # inpat2match = Match(...)
            # pat2matches = pat2matchfunc(term, inpat2match, 0, 1)
            # if len(pat2matches) != 0:
            #     inpat1match = Match(...)
            #     tmp0 = path + [term]
            #     tmp1 = copy_path_and_replace_last(tmp0, hole)
            #     pat1matches = pat1matchfunc(tmp1, inpat1match, 0, 1)
            #     if len(pat1matches) != 0:
            #         tmp11 = head + 1
            #         for m1, h1, t1 in pat1matches:
            #             for m2, h2, t2 in pat2matches:
            #                 tmp2 = combine_matches(m1, m2)
            #                 tmp{i} = match.copy()
            #                 tmp{j} = tmp2.getbinding(...)              ; same for inpat2match
            #                 tmp{k} = tmp{i}.addtobinding(..., tmp{j})  ; same for inpat2match
            #                 tmp3 = matches.append((tmp{i}, tmp11, tail))
            # tmp4 = term.kind()
            # if tmp4 == Term.Sequence:
            #     tmp5 = path.append(term)
            #     tmp6 = term.length()
            #     for tmp10 in range(tmp6):
            #         tmp7 = term.get(tmp10)
            #         tmp8 = inhole(tmp7, match, head, tail, path)
            #         matches = matches + tmp8
            #     tmp9 = path.pop()
            # return matches 

            symgen = SymGen()
            lookupfuncname = 'lang_{}_inhole_{}_impl'.format(self.languagename, self.symgen.get())

            matches, hole = rpy.gen_pyid_for('matches', '{}_hole'.format(self.languagename))

            term, match, head, tail, path = rpy.gen_pyid_for('term', 'match', 'head', 'tail', 'path')
            m1, h1, t1 = rpy.gen_pyid_for('m1', 'h1', 't1')
            m2, h2, t2 = rpy.gen_pyid_for('m2', 'h2', 't2')

            pat1matches, inpat1match = rpy.gen_pyid_for('pat1matches', 'inpat1match')
            pat2matches, inpat2match = rpy.gen_pyid_for('pat2matches', 'inpat2match')

            tmp0, tmp1, tmp2, tmp3, tmp4 = rpy.gen_pyid_temporaries(5, symgen)
            tmp5, tmp6, tmp7, tmp8, tmp9 = rpy.gen_pyid_temporaries(5, symgen)
            tmp10, tmp11, tmp12 = rpy.gen_pyid_temporaries(3, symgen)

            tmpm = rpy.gen_pyid_temporaries(1, symgen)

            forb2 = rpy.BlockBuilder()
            forb2.AssignTo(tmp2).FunctionCall(MatchHelperFuncs.CombineMatches, m1, m2) 
            forb2.AssignTo(tmpm).MethodCall(match, MatchMethodTable.DeepCopy)
            for sym in assignable_syms_all:
                tmpi, tmpj = rpy.gen_pyid_temporaries(2, symgen)
                forb2.AssignTo(tmpi).MethodCall(tmp2, MatchMethodTable.GetBinding, rpy.PyString(sym))
                forb2.AssignTo(tmpj).MethodCall(tmpm, MatchMethodTable.AddToBinding, rpy.PyString(sym), tmpi)
            forb2.AssignTo(tmp3).MethodCall(matches, 'append', rpy.PyTuple(tmpm, tmp11, tail))

            forb1 = rpy.BlockBuilder()
            forb1.For(m2, h2, t2).In(pat2matches).Block(forb2)

            ifb0 = rpy.BlockBuilder()
            ifb0.AssignTo(tmp11).Add(head, rpy.PyInt(1))
            ifb0.AssignTo(tmp2).FunctionCall(MatchHelperFuncs.CartesianProductAndCombineWith, pat1matches, pat2matches, match, tmp11, tail)
            ifb0.AssignTo(matches).Add(matches, tmp2)

            #ifb0.For(m1, h1, t1).In(pat1matches).Block(forb1)

            ifb1 = rpy.BlockBuilder()
            ifb1.AssignTo(inpat1match).New('Match', self._assignable_symbols_to_rpylist(assignable_syms1))
            ifb1.AssignTo(tmp0).Add(path, rpy.PyList(term))
            ifb1.AssignTo(tmp1).FunctionCall(TermHelperFuncs.CopyPathAndReplaceLast, tmp0, hole)
            ifb1.AssignTo(pat1matches).FunctionCall(matchpat1, tmp1, inpat1match, rpy.PyInt(0), rpy.PyInt(1)) 
            ifb1.If.LengthOf(pat1matches).NotEqual(rpy.PyInt(0)).ThenBlock(ifb0)

            # ---------------

            forb1 = rpy.BlockBuilder()
            forb1.AssignTo(tmp7).MethodCall(term, TermMethodTable.Get, tmp10)
            forb1.AssignTo(tmp8).FunctionCall(lookupfuncname, tmp7, match, head, tail, path)
            forb1.AssignTo(matches).Add(matches, tmp8)

            ifb3 = rpy.BlockBuilder()
            ifb3.AssignTo(tmp5).MethodCall(path, 'append', term)
            ifb3.AssignTo(tmp6).MethodCall(term, TermMethodTable.Length)
            ifb3.For(tmp10).InRange(tmp6).Block(forb1)
            ifb3.AssignTo(tmp9).MethodCall(path, 'pop')

            # ----------------

            fb = rpy.BlockBuilder()
            fb.AssignTo(matches).PyList()
            fb.AssignTo(inpat2match).New('Match', self._assignable_symbols_to_rpylist(assignable_syms2))
            fb.AssignTo(pat2matches).FunctionCall(matchpat2, term, inpat2match, rpy.PyInt(0), rpy.PyInt(1))
            fb.If.LengthOf(pat2matches).NotEqual(rpy.PyInt(0)).ThenBlock(ifb1)
            #fb.AssignTo(tmp4).MethodCall(term, TermMethodTable.Kind)
            fb.If.IsInstance(term, 'Sequence').ThenBlock(ifb3)
            fb.Return(matches)

            self.modulebuilder.SingleLineComment('{}'.format(repr(pat)))
            self.modulebuilder.Function(lookupfuncname).WithParameters(term, match, head, tail, path).Block(fb)

            #-------- this produces top-level function with empty list representing the path.
            # We do constraint checking here also.
            symgen = SymGen()

            m, h, t = rpy.gen_pyid_for('m', 'h', 't')
            fb = rpy.BlockBuilder()
            fb.AssignTo(tmp0).FunctionCall(lookupfuncname, term, match, head, tail, rpy.PyList())
            if pat.constraintchecks != None:
                fb.AssignTo(matches).PyList()
                forb = rpy.BlockBuilder()
                for chck in pat.constraintchecks:
                    tmpi = rpy.gen_pyid_temporaries(1, symgen)
                    ifb = rpy.BlockBuilder()
                    ifb.Continue

                    forb.AssignTo(tmpi).MethodCall(m, MatchMethodTable.CompareKeys, rpy.PyString(chck.sym1), rpy.PyString(chck.sym2))
                    forb.If.NotEqual(tmpi, rpy.PyBoolean(True)).ThenBlock(ifb)

                tmp = rpy.gen_pyid_temporaries(1, symgen)
                forb.AssignTo(tmp).MethodCall(matches, 'append', rpy.PyTuple(m, h, t))
                fb.For(m, h, t).In(tmp0).Block(forb)
                fb.Return(matches)
            else:
                fb.Return(tmp0)

            self.modulebuilder.Function(functionname).WithParameters(term, match, head, tail).Block(fb)
예제 #6
0
    def transformPatSequence(self, seq):
        assert isinstance(seq, pattern.PatSequence)
        if self.context.get_function_for_pattern(self.languagename, repr(seq)) is None:
            match_fn = 'language_{}_match_term_{}'.format(self.languagename, self.symgen.get())
            self.context.add_function_for_pattern(self.languagename, repr(seq), match_fn)
            
            # generate code for all elements of the sequence.
            for pat in seq:
                if not isinstance(pat, pattern.CheckConstraint):
                    self.transform(pat)

            # symgen for the function
            symgen = SymGen()
            term, match, head, tail = rpy.gen_pyid_for('term', 'match', 'head', 'tail')
            m, h, t = rpy.gen_pyid_for('m', 'h', 't')
            subhead, subtail = rpy.gen_pyid_for('subhead', 'subtail')

            fb = rpy.BlockBuilder()

            # ensure term is actually a sequence.
            #
            # tmp{i} = term.kind()
            # if tmp{i} != TermKind.Sequence:
            #   return []
            tmpi = rpy.gen_pyid_temporaries(1, symgen)

            ifb = rpy.BlockBuilder()
            ifb.Return(rpy.PyList())
            
            fb.If.NotIsInstance(term, 'Sequence').ThenBlock(ifb)

            # 'enter' the term
            # subhead = 0
            # subtail = term.length()
            fb.AssignTo(subhead).PyInt(0)
            fb.AssignTo(subtail).MethodCall(term, TermMethodTable.Length)

            # ensure number of terms in the sequence is at least equal to number of non Repeat patterns. 
            # if num_required is zero, condition is always false.
            # tmp{i} = subtail - subhead
            # if tmp{i} < num_required:
            #   return []
            num_required = seq.get_number_of_nonoptional_matches_between(0, len(seq))
            tmpi = rpy.gen_pyid_temporaries(1, symgen)

            ifb = rpy.BlockBuilder()
            ifb.Return(rpy.PyList())

            fb.AssignTo(tmpi).Subtract(subtail, subhead)
            fb.If.LessThan(tmpi, rpy.PyInt(num_required)).ThenBlock(ifb)

            # stick initial match object into array - simplifies codegen.
            previousmatches = rpy.gen_pyid_for('matches')
            fb.AssignTo(previousmatches).PyList( rpy.PyTuple(match, subhead, subtail) )

            for i, pat in enumerate(seq):
                matches = rpy.gen_pyid_temporary_with_sym('matches', symgen)

                if isinstance(pat, pattern.Repeat) :
                    # matches{i} = [] # get temporary with symbol
                    # for m,h,t in matches{i-1}:
                    #   tmp{i} = matchfn(term, m, h, t)   
                    #   matches{i} = matches{i} + tmp{i}
                    functionname = self.context.get_function_for_pattern(self.languagename, repr(pat))

                    tmpi, tmpj  = rpy.gen_pyid_temporaries(2, symgen)
                    forb = rpy.BlockBuilder()
                    forb.AssignTo(tmpi).FunctionCall(functionname, term, m, h, t)
                    forb.AssignTo(matches).Add(matches, tmpi)
                    fb.AssignTo(matches).PyList()
                    fb.For(m, h, t).In(previousmatches).Block(forb)

                    # ensure number of terms in the sequence is at least equal to number of non Repeat patterns after 
                    # this repeat pattern.
                    #
                    # matches{i} = []
                    # for m, h, t in matches{i-1}:
                    #   tmp{i} = t - h
                    #   if tmp{i} >= num_required:
                    #     tmp{j} = matches{i}.append((m, h, t))
                    # if len(matches{i}) == 0:
                    #   return matches{i} 
                    num_required = seq.get_number_of_nonoptional_matches_between(i, len(seq))
                    if num_required > 0:
                        previousmatches = matches
                        matches = rpy.gen_pyid_temporary_with_sym('matches', symgen)
                        tmpi, tmpj  = rpy.gen_pyid_temporaries(2, symgen)

                        ifb1 = rpy.BlockBuilder()
                        ifb1.AssignTo(tmpj).MethodCall(matches, 'append', rpy.PyTuple(m, h, t))

                        forb = rpy.BlockBuilder()
                        forb.AssignTo(tmpi).Subtract(t, h)
                        forb.If.GreaterEqual(tmpi, rpy.PyInt(num_required)).ThenBlock(ifb1)

                        ifb2 = rpy.BlockBuilder()
                        ifb2.Return(matches)

                        fb.AssignTo(matches).PyList()
                        fb.For(m, h, t).In(previousmatches).Block(forb)
                        fb.If.LengthOf(matches).Equal(rpy.PyInt(0)).ThenBlock(ifb2)

                            
                elif isinstance(pat, pattern.CheckConstraint):
                    # matches{i} = []
                    # for m, h, t in matches{i-1}:
                    #   tmp{i} = m.CompareKeys(sym1, sym2)
                    #   if tmp{i} == True:
                    #     tmp{j} = matches{i}.append( (m, h, t) )
                    # if len(matches{i}) == 0:
                    #   return matches{i} 
                    tmpi, tmpj, tmpk  = rpy.gen_pyid_temporaries(3, symgen)

                    ifb1 = rpy.BlockBuilder()
                    ifb1.AssignTo(tmpj).MethodCall(matches, 'append', rpy.PyTuple(m, h, t))

                    forb = rpy.BlockBuilder()
                    forb.AssignTo(tmpi).MethodCall(m, MatchMethodTable.CompareKeys, rpy.PyString(pat.sym1), rpy.PyString(pat.sym2))
                    forb.If.Equal(tmpi, rpy.PyBoolean(True)).ThenBlock(ifb1)

                    ifb2 = rpy.BlockBuilder()
                    ifb2.Return(matches)

                    fb.AssignTo(matches).PyList()
                    fb.For(m, h, t).In(previousmatches).Block(forb)
                    fb.If.LengthOf(matches).Equal(rpy.PyInt(0)).ThenBlock(ifb2)

                else:
                    # matches{i} = []
                    # for m, h, t in matches{i-1}:
                    #   tmp{j} = term.get(h)
                    #   tmp{i} = func(tmp{j}, m, h, t)
                    #   matches{i} = matches{i} + tmp{i}
                    # if len(matches{i}) == 0: 
                    #   return  matches{i} 
                    function = self.context.get_function_for_pattern(self.languagename, repr(pat))
                    tmpi, tmpj = rpy.gen_pyid_temporaries(2, symgen)

                    forb = rpy.BlockBuilder()

                    forb.AssignTo(tmpj).MethodCall(term, TermMethodTable.Get, h)
                    forb.AssignTo(tmpi).FunctionCall(function, tmpj, m, h, t)
                    forb.AssignTo(matches).Add(matches, tmpi)

                    ifb1 = rpy.BlockBuilder()
                    ifb1.Return(matches)

                    fb.AssignTo(matches).PyList()
                    fb.For(m, h, t).In(previousmatches).Block(forb)
                    fb.If.LengthOf(matches).Equal(rpy.PyInt(0)).ThenBlock(ifb1)

                previousmatches = matches

            # exit term
            # 
            # matches{i} = []
            # for m, h, t in matches{i-1}:
            #   if h == t:
            #     tmp{k} = head + 1
            #     tmp{i} = (m, head, tail)
            #     tmp{j} = matches{i}.append(tmp{i})
            # return matches{i}
            tmpi, tmpj, tmpk = rpy.gen_pyid_temporaries(3, symgen)
            matches = rpy.gen_pyid_temporary_with_sym('matches', symgen)

            ifb = rpy.BlockBuilder()
            ifb.AssignTo(tmpk).Add(head, rpy.PyInt(1))
            ifb.AssignTo(tmpi).PyTuple(m, tmpk, tail)
            ifb.AssignTo(tmpj).MethodCall(matches, 'append', tmpi)

            forb = rpy.BlockBuilder()
            forb.If.Equal(h, t).ThenBlock(ifb)

            fb.AssignTo(matches).PyList()
            fb.For(m, h, t).In(previousmatches).Block(forb)
            fb.Return(matches)

            self.modulebuilder.SingleLineComment(repr(seq))
            self.modulebuilder.Function(match_fn).WithParameters(term, match, head, tail).Block(fb)
예제 #7
0
 def _assignable_symbols_to_rpylist(self, assignable_symbols):
     assignable_syms = map(lambda s: rpy.PyString(s), assignable_symbols)
     return rpy.PyList(*assignable_syms)
예제 #8
0
파일: tlform.py 프로젝트: mamysa/PyPltRedex
        tmpa = rpy.gen_pyid_temporaries(1, symgen)
        ifb2 = rpy.BlockBuilder()
        ifb2.AssignTo(tmpa).MethodCall(argterm, TermMethodTable.ToString)
        ifb2.RaiseException('meta-function {}: clause {} produced multiple terms when matching term %s' \
                           .format(metafunction.contract.name, caseid), tmpa)

        fb = rpy.BlockBuilder()
        fb.AssignTo(tmp0).FunctionCall(matchfunc, argterm)
        fb.AssignTo(tmp1).PyList()
        fb.For(tmp2).In(tmp0).Block(forb)
        fb.If.LengthOf(tmp1).Equal(rpy.PyInt(0)).ThenBlock(ifb1)
        fb.AssignTo(tmp5).FunctionCall(TermHelperFuncs.AreTermsEqualPairwise,
                                       tmp1)
        fb.If.NotEqual(tmp5, rpy.PyBoolean(True)).ThenBlock(ifb2)
        fb.AssignTo(tmp6).ArrayGet(tmp1, rpy.PyInt(0))
        fb.Return(rpy.PyList(tmp6))

        nameof_function = self.symgen.get('{}_case'.format(mfname))
        self.modulebuilder.Function(nameof_function).WithParameters(
            argterm).Block(fb)
        return nameof_function

    def _visitDefineMetafunction(self, form):
        assert isinstance(form, tlform.DefineMetafunction)
        #def mf(argterm):
        #  tmp0 = domaincheck(argterm)
        #  if len(tmp0) == 0:
        #    raise Exception('mfname: term is not in my domain')
        #  { foreach reductioncase
        #  tmp{i} = mfcase(term)
        #  if len(tmp{i}) == 1: