Exemplo n.º 1
0
 def create(s):
     e = E()
     e.t = 'string'
     e.v = s
     f = E()
     f.t = 'const'
     f.v = '?'
     return E.func('`apply', [f, e])
Exemplo n.º 2
0
def _gc(el, repls):
    if type(el) in [list, tuple]:
        if len(el) == 0:
            return (False, el)
        res = [_gc(e, repls) for e in el]
        if not max(e[0] for e in res):
            return (False, el)
        res = [e[1] for e in res]
        if type(el) == tuple:
            res = tuple(res)
        return (True, res)
    if not isinstance(el, E):
        return (False, el)
    if el.t != 'f':
        return (False, el)
    if len(el.args) == 0:
        return (False, el)
    if el.v == '`apply':
        for e in repls:
            if e[2][0] == el[0]:
                e[0] = True
                print('Use =>', el)
        return (False, el)
    if el.v == ';':
        # [use? gced? repl]
        isChange = False
        subrepls = [[False, False, e] for e in el[:-1]]
        (c, resE) = _gc(el[-1], repls + subrepls)
        if c:
            isChange = True
        isDo = True
        while isDo:
            isDo = False
            for i in range(len(subrepls) - 1, -1, -1):
                if not subrepls[i][0] or subrepls[i][1]:
                    continue
                isDo = True
                (c, res) = _gc(subrepls[i][2][2], repls + subrepls[:i])
                if c:
                    subrepls[i][2] = E.func(
                        '`repl',
                        subrepls[i][2][:2] + [res] + subrepls[i][2][3:])
                    isChange = True
                subrepls[i][1] = True
        nsubrepls = [e[2] for e in subrepls if e[0]]
        if len(nsubrepls) != len(subrepls):
            isChange = True
        if not isChange:
            return (False, el)
        return (True, E.func(';', nsubrepls + [resE]))
    args = [_gc(e, repls) for e in el.args]
    if el.v == '`pipely' and args[0][1].isFunc('`apply'):
        return (True,
                E.func('`apply', [args[0][1][0]] + [e[1] for e in args[1:]]))
    if not max(e[0] for e in args):
        return (False, el)
    return (True, E.func(el.v, [e[1] for e in args]))
Exemplo n.º 3
0
 def bind(el, faker=None):
     if faker is None:
         faker = E.Fake()
     repls = []
     r = Unclosure._bind(el, [], repls, faker)
     if len(repls) > 0:
         return E.func(';', repls + [r])
     else:
         return r
Exemplo n.º 4
0
def _res2E(res):
    if type(res) in [int, float]:
        el = E()
        el.t = 'number'
        el.v = str(res)
        return el
    if type(res) in [str]:
        el = E()
        el.t = 'string'
        el.v = res
        return el
    if type(res) == E:
        if res.isFunc('≺'):
            return res
        return E.func('≺', [res])
    return None
Exemplo n.º 5
0
def inject(dst, data):
    if R.iff(dst):
        if dst[1].v not in data:
            raise Exception('No template <%s> in dst' % dst[1].v)
        return data[dst[1].v]
    if (type(dst) != E or dst.t != 'f'):
        return dst
    return E.func(dst.v, [inject(e, data) for e in dst.args])
Exemplo n.º 6
0
def _gorun(el, repls):
    s = E.func(';', repls + [el])
    s = Unclosure.bind(s)
    MACRO.clear()
    s = cody(s, 'py', 'generators/py.py')
    s = execute(s)
    s = s()
    s = _res2E(s)
    return s
Exemplo n.º 7
0
 def vl(lvars, lstat):
     lv = lvars[-len(v.args):]
     lf = [
         walk_t_apply(E.func('`apply', [f] + lv), lvars, lstat).copy()
         for f in v.dict
     ]
     for i in range(len(lf)):
         lf[i].n = el[2][i]
     return walk_exc(el[3], lvars + lf, lstat)
Exemplo n.º 8
0
def apply(eqn, src, dst, isRec=True):
    if isinstance(dst, type(lambda: 0)):
        dstf = dst
    elif isinstance(dst, E):

        def dstf(data):
            return inject(dst, data)
    else:
        raise Exception('dst must be tree or function')
    eqn = _apply(eqn, src, dstf, isRec)
    return E.squeeze(eqn)
Exemplo n.º 9
0
def _apply(eqn, src, dst, isRec):
    data = {}
    r = eject(eqn, src, data)
    if r:
        if isRec:
            for k in data:
                data[k] = _apply(data[k], src, dst, isRec)
        d = dst(data)
        if d is None:
            if not isRec:
                return eqn
        else:
            return d
    if (type(eqn) != E or eqn.t != 'f'):
        return eqn
    return E.func(eqn.v, [_apply(e, src, dst, isRec) for e in eqn.args])
Exemplo n.º 10
0
def _insert_full(el, repls, uncert):
    (isChange, nel) = _insert(el, uncert)
    if isChange:
        return nel
    ri = None
    for i in range(len(repls)):
        ii = len(repls) - i - 1
        if repls[ii][2] is None:
            continue
        (isChange, nel) = _insert(repls[ii], uncert)
        if not isChange:
            continue
        if ri is not None:
            raise Exception('Multi nodes find by uncert')
        ri = ii
        break
    if ri is None:
        raise Exception('Cannot find uncert node')
    return E.func(';', [nel] + repls[ri + 1:] + [el])
Exemplo n.º 11
0
def _insert(el, uncert):
    if type(el) in [list, tuple]:
        if len(el) == 0:
            return (False, el)
        res = [_insert(e, uncert) for e in el]
        if not max(e[0] for e in res):
            return (False, el)
        res = [e[1] for e in res]
        if type(el) == tuple:
            res = tuple(res)
        return (True, res)
    if not isinstance(el, E):
        return (False, el)
    if el.t != 'f':
        return (False, el)
    if el.v == '≻' and el[0] == uncert.obj[0]:
        return (True, uncert.args[0])
    if len(el.args) == 0:
        return (False, el)
    args = [_insert(e, uncert) for e in el.args]
    if not max(e[0] for e in args):
        return (False, el)
    nel = E.func(el.v, [e[1] for e in args])
    return (True, nel)
Exemplo n.º 12
0
 def findnext(lvars, lstat, d):
     i = 0
     lv = v.dictm[1 if d else 0]
     while True:
         if v.dictf is None:
             fv = lv
         else:
             fv = walk_t_apply(E.func('`apply', [v.dictf, lv]), lvars,
                               lstat)
         # TODO handle None?
         fv = fv.copy()
         fv.n = el[2]
         rv = walk_exc(el[3], lvars + [fv], lstat)
         rv = match_cast(AE.gettype('bool'), rv, el)[1]
         lv.value += 1 if d else -1
         if rv.value:
             v.dict[v.dictm[3 if d else 2]] = fv
             v.dictm[3 if d else 2] += 1 if d else -1
             return
         i += 1
         if i > OVERITER:
             raise AError(
                 'Over %d iterations for %s duration' %
                 (OVERITER, 'right' if d else 'left'), el)
Exemplo n.º 13
0
def _walk(el, repls):
    if type(el) in [list, tuple]:
        if len(el) == 0:
            return (NOCONST, el)
        res = []
        for e in el:
            (c, e) = _walk(e, repls)
            if c == CONST:
                (c, e) = _run((c, e), repls)
                assert c == CONST
            res.append(e)
        if type(el) == tuple:
            res = tuple(res)
        return (NOCONST, res)
    if not isinstance(el, E):
        return (NOCONST, el)
    if _isConst(el):
        return (CONST, el)
    if el.t != 'f':
        return (NOCONST, el)
    if el.v == '`apply':
        if len(el.args) > 1:
            return _walk(
                E.func('`pipely', [E.func('`apply', el[:1])] + el[1:]), repls)
        res = _find_repl(el[0], repls)
        if res is None:
            return (DIFFCONST, el)
        if res[0] == CONST and len(res[1][1]) == 0:
            return (CONST, res[1][2])
        return (res[0], el)
    if el.v == 'msub':
        return _walk(E.func('`apply', [el]), repls)
    if el.v == '`repl':
        subrepls = repls + [(DIFFCONST, E.func('`repl', [e, [], None]))
                            for e in el[1]]
        (resC, resE) = _walk(el[2], subrepls)
        if resC == CONST:
            (resC, resE) = _run((CONST, resE), subrepls)
        return (resC, E.func('`repl', el[:2] + [resE] + el[3:]))
    if el.v == ';':
        subrepls = repls[:]
        for e in el[:-1]:
            subrepls.append(_walk(e, subrepls))
        res = _walk(el[-1], subrepls)
        return (res[0],
                E.func(';', [e[1] for e in subrepls[len(repls):]] + [res[1]]))
    res = [_walk(e, repls) for e in el.args]
    resE = E.func(el.v, [])
    if el.v == '`pipely':
        resF = res[0]
        res = res[1:]
        resE.args.append(resF[1])
    resC = min(e[0] for e in res)
    for (c, e) in res:
        if c == resC:
            resE.args.append(e)
            continue
        if c == CONST:
            (c, e) = _run((CONST, e), repls)
            assert c == CONST
            resE.args.append(e)
            continue
        resE.args.append(e)
    if el.v == '`pipely':
        # t2(t1), t3 is type of t2
        t1 = resC
        t2 = resF[0]
        ARG_t2 = 0
        REPL_t2 = 1
        TREE_t2 = 2
        t3 = TREE_t2
        if resF[1].isFunc('`apply'):
            replF = _find_repl(resF[1][0], repls)
            if replF is None:
                t3 = REPL_t2
            elif replF[1][2] is None:
                t3 = ARG_t2
            else:
                t3 = REPL_t2
        if t2 == DIFFCONST:
            if t3 == REPL_t2:
                if t1 == CONST:
                    return _run((DIFFCONST, resE), repls)
                if t1 == NOCONST:
                    return (NOCONST, resE)
            return (DIFFCONST, resE)
        if t3 == ARG_t2:
            raise Exception('Inpossible')
        if t2 == CONST and t3 == REPL_t2:
            return (CONST, replF[1][2])
        if t1 == CONST:
            return _run((t2, resE), repls)
        return (t1, resE)
    return (resC, resE)
Exemplo n.º 14
0
def cody(e, t, f, n=None):
    cache = {}

    def load(t, p):
        p = path.sep.join(p)
        if p in cache:
            return cache[p]
        if t == 'py':
            g = loadPy(p)
        elif t == 'gn':
            g = loadGn(p)
        else:
            raise PbTranslatorError('Unknown gen type <%s>' % t)
        cache[p] = g
        return g

    def loadPy(p):
        s = util.spec_from_file_location("some_case", p)
        if s is None:
            raise PbTranslatorError('Wrong gen file <%s>' % p)
        m = util.module_from_spec(s)
        try:
            s.loader.exec_module(m)
        except Exception:
            raise PbTranslatorError('Exception while load gen file <%s>' % p)
        if 'case' not in m.__dict__:
            raise PbTranslatorError(
                'Gen file do not contains function `case(el, cody, gen)` <%s>'
                % p
            )
        return m.case

    def loadGn(p):
        if not path.isfile(p):
            raise PbTranslatorError('No gen file <%s>' % p)
        try:
            with open(p, 'r', encoding='utf8') as f:
                s = f.readlines()
        except Exception:
            raise PbTranslatorError(
                'Cannot read gen file <%s> (utf8 required)'
                % p
            )
        i = -1
        parts = []
        while True:
            i += 1
            if i == len(s):
                break
            if s[i][0:3] == '# \\':
                continue
            if s[i][0:5] == '# > \\' or s[i][0:5] == '# < \\':
                cd = []
                for j in s[i+1:]:
                    if j[0:3] == '# \\':
                        break
                    cd.append(j[:-1])
                parts.append((s[i][2], i, '\n'.join(cd)))
                i += len(cd) + 1
            if s[i][0:3] == '# >' or s[i][0:3] == '# <':
                parts.append((s[i][2], i, s[i][3:-1]))
        cd = []
        for i in range(0, len(parts), 2):
            (si, ni, cdi) = parts[i]
            if len(parts) == i+1:
                raise PbTranslatorError(
                    'Unexpected end of gen file <%s>' % p
                )
            (so, no, cdo) = parts[i+1]
            if si != '>':
                raise PbTranslatorError(
                    'Part on <%s:%d> must be contidion'
                    % (p, ni + 1)
                )
            if so != '<':
                raise PbTranslatorError(
                    'Part on <%s:%d> must be template'
                    % (p, no + 1)
                )
            cdo = cdo.strip().replace('\\', '\\\\').split('#%')
            for j in range(1, len(cdo), 2):
                if j == len(cdo) - 1:
                    raise PbTranslatorError(
                        'Template on <%s:%d> has unclosed inserts'
                        % (p, no + 1)
                    )
                cdo[j] = '""" + (%s) + """' % cdo[j]
            cd += [
                'if (%s):' % cdi,
                '\treturn """%s"""' % ''.join(cdo)
            ]
        cd = 'def case(e, r, g):\n%s\n' % '\n'.join('\t' + s for s in cd)
        return loadPyCode(p, cd)

    class PbGen(PbError):
        def __init__(self, r):
            self.r = r

    def loadPyCode(p, cd):
        m = {}
        try:
            exec(cd, m)
        except Exception:
            try:
                raise PbTranslatorError('Error in compiled template <%s>' % p)
            except Exception:
                raise PbCodeHelper(cd)

        def wrap(e, r, g):
            try:
                return m['case'](e, r, g)
            except PbError as e:
                raise e
            except Exception:
                raise PbCodeHelper(cd)
        return wrap

    def gen(ps, e, t, f):
        ps = ps + f.split('/')[:-1]
        f = f.split('/')[-1]
        m = load(t, ps + [f])
        try:
            r = m(e, rec, lambda t, f: gen(ps, e, t, f))
        except PbError as e:
            raise e
        except Exception:
            raise PbTranslatorError(
                'Error while apply gen file <%s>'
                % '/'.join(ps + [f])
            )
        if r is not None:
            raise PbGen(r)

    def wrap(e, r, g):
        if type(e) != E:
            raise PbTranslatorError('Tree error: unknown %s' % str(e))
        g(t, f)
        raise PbTranslatorError('Tree error: unmathed %s' % str(e))

    def rec(e):
        try:
            r = wrap(e, rec, lambda t, f: gen([], e, t, f))
        except PbGen as e:
            return e.r
        return r

    if n is None:
        n = '_main'
    e = E.func('`codywrap', [e, n])
    return rec(e)
Exemplo n.º 15
0
 def _bind(el, vars, repls, faker):
     if type(el) == list:
         return [Unclosure._bind(e, vars, repls, faker) for e in el]
     if type(el) != E or el.t != 'f':
         return el
     if el.v == '≺':
         return el
     if el.v == '`repl':
         subvars = el[1]
         r = Unclosure._bind(el[2], subvars, repls, faker)
         repl = E.func('`repl', [el[0], subvars, r] + el[3:])
         return repl
     if el.v == ';':
         args = el.args[:]
         i = -1
         while True:
             i += 1
             if i == len(args):
                 break
             subrepls = []
             r = Unclosure._bind(args[i], vars, subrepls, faker)
             args = args[:i] + subrepls + [r] + args[i+1:]
             i += len(subrepls)
         repl = E.func('`repl', [
             faker.fake(),
             vars,
             E.func(';', args)
         ])
         repls.append(repl)
         apply = E.func('`apply', [repl[0]] + [
             E.func('`apply', [var])
             for var in vars
         ])
         return apply
     if el.v == '`pipely':
         n = faker.fake()
         return Unclosure._bind(
             E.func(';', [
                 E.func('`repl', [
                     n,
                     [],
                     el[0]
                 ]),
                 E.func('`apply', [
                     n
                 ] + el[1:])
             ]),
             vars, repls, faker
         )
     if el.v in ['`series', '`matrix', '`inject']:
         nf = faker.fake()
         ns = faker.fake()
         subvars = vars[:]
         if el.v == '`series':
             if isinstance(el[2], E):
                 subvars += [el[2]]
             elif type(el[2]) in [list, tuple]:
                 subvars += el[2]
             else:
                 raise Exception('Wrong series vars ' + str(el))
         repl = E.func('`repl', [
             nf,
             vars,
             E.func(';', [
                 E.func('`repl', [
                     ns,
                     [],
                     E.func(el.v, [
                         Unclosure._bind(e, subvars, repls, faker)
                         for e in el.args
                     ])
                 ]),
                 E.func('`apply', [ns])
             ])
         ])
         repls.append(repl)
         apply = E.func('`apply', [nf] + [
             E.func('`apply', [var])
             for var in vars
         ])
         return apply
     return E.func(el.v, [
         Unclosure._bind(e, vars, repls, faker)
         for e in el.args
     ])
Exemplo n.º 16
0
 def iff(e):
     return (E.isFunc(e, '`apply') and e[0].t == 'const' and e[0].v == '?'
             and e[1].t == 'string')