Пример #1
0
def value_at(m, k):
    """Make an AST node for m[k]."""
    if isinstance(m, target_syntax.EMakeMap2):
        return syntax.ECond(syntax.EIn(k, m.e), m.value.apply_to(k),
                            construct_value(m.type.v)).with_type(m.type.v)
    if isinstance(m, syntax.ECond):
        return syntax.ECond(m.cond, value_at(m.then_branch, k),
                            value_at(m.else_branch, k)).with_type(m.type.v)
    return target_syntax.EMapGet(m, k).with_type(m.type.v)
Пример #2
0
 def visit_EGetField(self, e):
     ee = self.visit(e.e)
     res = syntax.EGetField(ee, e.f).with_type(e.type)
     if e.e.type == t and e.f == "val":
         res = syntax.ECond(syntax.EEq(ee, ptr), new_value,
                            res).with_type(e.type)
     return res
Пример #3
0
def value_at(m, k):
    """
    Assuming k is in EMapKeys(m), produce the value at k.
    """
    if isinstance(m, target_syntax.EMakeMap2):
        return m.value.apply_to(k)
    if isinstance(m, syntax.ECond):
        return syntax.ECond(m.cond, value_at(m.then_branch, k),
                            value_at(m.else_branch, k)).with_type(m.type.v)
    return target_syntax.EMapGet(m, k).with_type(m.type.v)
Пример #4
0
def mutate(e: syntax.Exp, op: syntax.Stm) -> syntax.Exp:
    """Return the new value of `e` after executing `op`."""
    if isinstance(op, syntax.SNoOp):
        return e
    elif isinstance(op, syntax.SAssign):
        return _do_assignment(op.lhs, op.rhs, e)
    elif isinstance(op, syntax.SCall):
        if op.func == "add":
            return mutate(
                e,
                syntax.SCall(op.target, "add_all", (syntax.ESingleton(
                    op.args[0]).with_type(op.target.type), )))
        elif op.func == "add_all":
            return mutate(
                e,
                syntax.SAssign(
                    op.target,
                    syntax.EBinOp(op.target, "+",
                                  op.args[0]).with_type(op.target.type)))
        elif op.func == "remove":
            return mutate(
                e,
                syntax.SCall(op.target, "remove_all", (syntax.ESingleton(
                    op.args[0]).with_type(op.target.type), )))
        elif op.func == "remove_all":
            return mutate(
                e,
                syntax.SAssign(
                    op.target,
                    syntax.EBinOp(op.target, "-",
                                  op.args[0]).with_type(op.target.type)))
        else:
            raise Exception("Unknown func: {}".format(op.func))
    elif isinstance(op, syntax.SIf):
        then_branch = mutate(e, op.then_branch)
        else_branch = mutate(e, op.else_branch)
        if alpha_equivalent(then_branch, else_branch):
            return then_branch
        return syntax.ECond(op.cond, then_branch,
                            else_branch).with_type(e.type)
    elif isinstance(op, syntax.SSeq):
        if isinstance(op.s1, syntax.SSeq):
            return mutate(e, syntax.SSeq(op.s1.s1,
                                         syntax.SSeq(op.s1.s2, op.s2)))
        e2 = mutate(mutate(e, op.s2), op.s1)
        if isinstance(op.s1, syntax.SDecl):
            e2 = subst(e2, {op.s1.id: op.s1.val})
        return e2
    elif isinstance(op, syntax.SDecl):
        return e
    else:
        raise NotImplementedError(type(op))
Пример #5
0
def _update_handle(e: syntax.Exp, handle: syntax.EVar, change):
    if isinstance(e.type, syntax.TBag) or isinstance(e.type, syntax.TList):
        return target_syntax.EMap(
            e, mk_lambda(
                e.type.t,
                lambda x: _update_handle(x, handle, change))).with_type(e.type)
    elif isinstance(e.type, syntax.THandle):
        if e.type == handle.type:
            return syntax.ECond(syntax.EEq(e, handle), change(e),
                                e).with_type(e.type)
        else:
            return e
    elif isinstance(e.type, syntax.TTuple):
        return syntax.ETuple(
            tuple(
                _update_handle(
                    syntax.ETupleGet(e, i).with_type(e.type.ts[i]), handle,
                    change) for i in range(len(e.type.ts)))).with_type(e.type)
    elif e.type == syntax.INT or e.type == syntax.LONG or e.type == syntax.BOOL or e.type == syntax.STRING or isinstance(
            e.type, syntax.TNative) or isinstance(e.type, syntax.TEnum):
        return e
    else:
        raise NotImplementedError(repr(e.type))
Пример #6
0
 def p_exp(p):
     """exp : NUM
            | FLOAT
            | WORD
            | WORD OP_OPEN_PAREN exp_list OP_CLOSE_PAREN
            | KW_TRUE
            | KW_FALSE
            | exp OP_PLUS  exp
            | exp OP_MINUS exp
            | exp OP_TIMES exp
            | exp OP_EQ exp
            | exp OP_NE exp
            | exp OP_LT exp
            | exp OP_LE exp
            | exp OP_GT exp
            | exp OP_GE exp
            | exp KW_AND exp
            | exp KW_OR exp
            | exp OP_IMPLIES exp
            | exp OP_QUESTION exp OP_COLON exp
            | exp OP_OPEN_BRACKET slice OP_CLOSE_BRACKET
            | KW_NOT exp
            | OP_MINUS exp
            | exp KW_IN exp
            | KW_UNIQUE exp
            | KW_DISTINCT exp
            | KW_EMPTY exp
            | KW_THE exp
            | KW_MIN exp
            | KW_MAX exp
            | KW_ARGMIN lambda exp
            | KW_ARGMAX lambda exp
            | KW_SUM exp
            | KW_LEN exp
            | KW_ANY exp
            | KW_ALL exp
            | KW_EXISTS exp
            | KW_REVERSED exp
            | exp OP_DOT NUM
            | exp OP_DOT WORD
            | OP_OPEN_PAREN exp_list OP_CLOSE_PAREN
            | OP_OPEN_BRACE record_fields OP_CLOSE_BRACE
            | OP_OPEN_BRACKET exp OP_CLOSE_BRACKET
            | OP_OPEN_BRACKET exp OP_VBAR comprehension_body OP_CLOSE_BRACKET"""
     if len(p) == 2:
         if type(p[1]) is syntax.ENum:
             p[0] = p[1]
         elif p[1] == "true":
             p[0] = syntax.EBool(True)
         elif p[1] == "false":
             p[0] = syntax.EBool(False)
         else:
             p[0] = syntax.EVar(p[1])
     elif len(p) == 3:
         if p[1] == "min":
             p[0] = syntax.EArgMin(
                 p[2], syntax.ELambda(syntax.EVar("x"), syntax.EVar("x")))
         elif p[1] == "max":
             p[0] = syntax.EArgMax(
                 p[2], syntax.ELambda(syntax.EVar("x"), syntax.EVar("x")))
         else:
             p[0] = syntax.EUnaryOp(p[1], p[2])
     elif len(p) == 4:
         if p[1] == "(":
             exps = p[2]
             if len(exps) == 0:
                 raise Exception("illegal ()")
             elif len(exps) == 1:
                 p[0] = exps[0]
             elif len(exps) > 1:
                 p[0] = syntax.ETuple(tuple(exps))
         elif p[1] == "[":
             p[0] = syntax.ESingleton(p[2])
         elif p[1] == "{":
             p[0] = syntax.EMakeRecord(p[2])
         elif p[2] == ".":
             if isinstance(p[3], syntax.ENum):
                 p[0] = syntax.ETupleGet(p[1], p[3].val)
             else:
                 p[0] = syntax.EGetField(p[1], p[3])
         elif p[1] == "argmin":
             p[0] = syntax.EArgMin(p[3], p[2])
         elif p[1] == "argmax":
             p[0] = syntax.EArgMax(p[3], p[2])
         else:
             p[0] = syntax.EBinOp(p[1], p[2], p[3])
     else:
         if p[2] == "?":
             p[0] = syntax.ECond(p[1], p[3], p[5])
         elif p[2] == "[":
             if isinstance(p[3], syntax.Exp):
                 p[0] = syntax.EListGet(p[1], p[3])
             elif isinstance(p[3], tuple):
                 start = p[3][0]
                 end = p[3][1]
                 if start is None:
                     start = syntax.ZERO
                 if end is None:
                     end = syntax.ELen(p[1])
                 p[0] = syntax.EListSlice(p[1], start, end)
         elif p[1] == "[":
             p[0] = syntax.EListComprehension(p[2], p[4])
         elif p[2] == "(":
             p[0] = syntax.ECall(p[1], p[3])
         else:
             assert False, "unknown case: {}".format(repr(p[1:]))
Пример #7
0
def _delta_form(res: {str: syntax.Exp}, op: syntax.Stm) -> {str: syntax.Exp}:
    if isinstance(op, syntax.SNoOp):
        pass
    elif isinstance(op, syntax.SCall):
        update = _rewriter(op.target)
        if op.func == "add":
            update(
                res, lambda old: syntax.EBinOp(
                    old, "+",
                    syntax.ESingleton(op.args[0]).with_type(old.type)).
                with_type(old.type))
        elif op.func == "add_back":
            update(
                res, lambda old: syntax.EBinOp(
                    old, "+",
                    syntax.ESingleton(op.args[0]).with_type(old.type)).
                with_type(old.type))
        elif op.func == "add_front":
            update(
                res, lambda old: syntax.EBinOp(
                    syntax.ESingleton(op.args[0]).with_type(old.type), "+", old
                ).with_type(old.type))
        elif op.func == "remove_back":
            update(
                res,
                lambda old: target_syntax.EDropBack(old).with_type(old.type))
        elif op.func == "remove_front":
            update(
                res,
                lambda old: target_syntax.EDropFront(old).with_type(old.type))
        elif op.func == "remove":
            update(
                res, lambda old: syntax.EBinOp(
                    old, "-",
                    syntax.ESingleton(op.args[0]).with_type(old.type)).
                with_type(old.type))
        elif op.func == "remove_all":
            update(
                res, lambda old: syntax.EBinOp(old, "-", op.args[0]).with_type(
                    old.type))
        else:
            raise Exception("Unknown func: {}".format(op.func))
    elif isinstance(op, syntax.SAssign):
        update = _rewriter(op.lhs)
        update(res, lambda old: op.rhs)
    elif isinstance(op, syntax.SIf):
        res_then = res.copy()
        _delta_form(res_then, op.then_branch)
        res_else = res.copy()
        _delta_form(res_else, op.else_branch)

        for key in res:
            then_val = res_then[key]
            else_val = res_else[key]

            if then_val == else_val:
                res[key] = then_val
            else:
                # Substatements differ; need to defer to ECond evaluation.
                res[key] = syntax.ECond(op.cond, then_val,
                                        else_val).with_type(then_val.type)
    elif isinstance(op, syntax.SSeq):
        _delta_form(res, op.s1)
        _delta_form(res, subst(op.s2, res))
    else:
        raise NotImplementedError(type(op))

    return res