Пример #1
0
class Pen(Struct('points count box start end')):
    # XXX maybe make this (except for `points`) all an optional field in Conn
    def build(self, env):
        # XXX Should we require len(points) to be 2?
        #     Or work over each pair of successive points?
        #     It looks like real IDEAL requires at least 2 but ignores any left over.
        assert len(
            self.points) == 2, "'conn using' must connect exactly two points"
        zero, one = self.points

        # XXX The true semantics is problematic for us in requiring
        #  count to be evaluated to a number before we can instantiate
        #  the boxes -- so far we've never interleaved creating
        #  objects with solving constraints. I think we could do this
        #  without a massive overhaul, but I'm not gonna try
        #  tonight. Instead, require `count` to be a literal.
        assert isinstance(self.count,
                          Literal), "XXX crude implementation restriction"
        assert self.count.value.imag == 0
        n = self.count.value.real
        assert n == int(n)
        n = int(n)
        ps = [
            Relatively(Div(Literal(i), self.count), zero, one)
            for i in range(n + 1)
        ]
        for a_exp, b_exp in zip(ps[:-1], ps[1:]):
            segment = Put(
                None,
                self.box.prepend((Equate(
                    (self.start, a_exp)), Equate((self.end, b_exp)))))
            segment.build(env)
Пример #2
0
class Constraints(Struct('equations')):
    def build(self, env):
        for lhs, rhs in self.equations:
            LC.equate(lhs.evaluate(env), rhs.evaluate(env))

    def draw(self, env):
        pass
Пример #3
0
class Text(Struct('justified string where')):
    def build(self, env):
        env.add_drawer(self)

    def draw(self, env):
        at = self.where.evaluate(env).get_value()
        renderer.text(self.string, self.justified, to_coords(at))
Пример #4
0
class Path(Struct('points')):
    def build(self, env):
        env.add_drawer(self)

    def draw(self, env):
        points = [p.evaluate(env).get_value() for p in self.points]
        self.render(map(to_coords, points))
Пример #5
0
class Box(Struct('name stmts')):
    def make(self, env):
        for stmt in self.stmts:
            stmt.build(env)

    def prepend(self, stmts):
        return Box(self.name, stmts + self.stmts)
Пример #6
0
class Tuple(Struct('exprs')):
    def evaluate(self, env):
        type_ = tuple_types[len(self.exprs)]
        inst = type_.instantiate(env)
        for v, expr in zip(type_.fields, self.exprs):
            LC.equate(inst.mapping[v], expr.evaluate(env))
        return inst
Пример #7
0
class Draw(Struct('drawables')):
    def build(self, env):
        pass

    def draw(self, env):
        for drawable in self.drawables:
            drawable.draw(env)
Пример #8
0
class Div(Struct('arg1 arg2', supertype=(Expr, ))):
    def evaluate(self):
        combo1 = self.arg1.evaluate()
        combo2 = self.arg2.evaluate()
        terms2 = combo2.expand()
        if varies(terms2):
            raise Nonlinear()
        return combo1.scale(1 / constant(terms2))
Пример #9
0
class Relatively(Struct('coord zero one')):
    """Linear interpolate/extrapolate, i.e. `coord` in the coordinate
    system that places 0 at `zero` and 1 at `one`."""
    def evaluate(self, env):
        coord = self.coord.evaluate(env)
        zero = self.zero.evaluate(env)
        one = self.one.evaluate(env)
        return zero + (one - zero) * coord
Пример #10
0
class Ref(Struct('name')):
    def evaluate(self, env):
        for frame in reversed(env.frames):
            try:
                return frame[self.name]
            except KeyError:
                pass
        raise KeyError("Unbound name", self.name)
Пример #11
0
class Put(Struct('opt_name box')):
    def build(self, env):
        name = self.opt_name or gensym(
        )  # (The default name's just for debugging.)
        subenv = env.spawn(name)
        env.types[self.box.name].make(subenv)
        define(env.frames[-1], name, subenv.frames[-1])
        self.box.make(subenv)
Пример #12
0
class TupleType(Struct('fields')):
    def instantiate(self, env):
        inst = Instance(self)
        for f in self.fields:
            inst.mapping[f] = NumberInstance()
        return inst

    def draw(self, env):
        pass
Пример #13
0
class Compass(Struct('center boundary_point')):
    def build(self, env):
        env.add_drawer(self)

    def draw(self, env):
        points = [
            p.evaluate(env).get_value()
            for p in (self.center, self.boundary_point)
        ]
        renderer.circle(*map(to_coords, points))
Пример #14
0
class NonlinearFn(Struct('fn arg', supertype=(Expr, ))):
    def evaluate(self):
        combo = self.arg.evaluate()
        terms = combo.expand()
        if varies(terms):
            raise Nonlinear()
        value = constant(terms)
        assert isinstance(value, (int, float, complex)), \
            'type: %s, value: %r' % (type(value), value)
        return make_constant(self.fn(value))
Пример #15
0
class VarDecl(Struct('type_id decls')):
    def build(self, env):
        type_ = env.types[self.type_id]
        for decl in self.decls:
            inst = type_.instantiate(env)
            env.init(decl.id, inst)
            for id, rhs in decl.params:
                LC.equate(inst.mapping[id], rhs.evaluate(env))

    def draw(self, env):
        pass
Пример #16
0
class Equate(Struct('parts')):
    defaulty = False

    def build(self, env):
        env.add_constrainer(self)

    def constrain(self, env):
        def eq(lhs, rhs):
            env.constraints.append(solver.Equate(self.defaulty, lhs, rhs))
            return rhs

        reduce(eq, (expr.evaluate(env) for expr in self.parts))
Пример #17
0
class Environment(
        Struct('types constrainers constraints drawers prefix frames')):
    def spawn(self, name):
        return Environment(self.types, self.constrainers, self.constraints,
                           self.drawers, self.prefix + name + '.',
                           self.frames + ({}, ))

    def add_constrainer(self, constrainer):
        self.constrainers.append((constrainer, self))

    def add_drawer(self, drawer):
        self.drawers.append((drawer, self))
Пример #18
0
class Environment(Struct('types inst')):
    def spawn(self, inst):
        return Environment(self.types, inst)

    def init(self, id, value):
        assert id not in self.inst.mapping, "Multiple def: %s" % id
        self.inst.mapping[id] = value

    def fetch(self, id):
        assert id in self.inst.mapping, \
            "Not found: %r in %r" % (id, self.inst)
        return self.inst.mapping[id]
Пример #19
0
class Definition(Struct('id extends decls')):
    def build(self, env):
        env.types[self.id] = self

    def instantiate(self, env):
        inst = Instance(self)
        subenv = env.spawn(inst)  # XXX won't see global vars; should it?
        self.populate(subenv)
        return inst

    def populate(self, env):
        supe = self.super_definition(env)
        if supe:
            supe.populate(env)
        for decl in self.decls:
            decl.build(env)

    def draw(self, env):
        for drawer in self.pick_drawers(env) or env.inst.get_parts():
            drawer.draw(env)

    def pick_drawers(self, env):
        defn = self
        while defn:
            decls = [decl for decl in defn.decls if isinstance(decl, Draw)]
            if decls: return decls
            defn = defn.super_definition(env)
        return []

    def super_definition(self, env):
        if self.extends:
            supertype = env.types[self.extends]
            assert isinstance(supertype, Definition), \
                "%r is not a definition" % supertype
            return supertype
        else:
            return None
Пример #20
0
class Combine(Struct('arg1 coeff arg2', supertype=(Expr, ))):
    def evaluate(self):
        return self.arg1.evaluate().combine(self.coeff, self.arg2.evaluate())
Пример #21
0
class CallPrim(Struct('fn arg')):
    def evaluate(self, env):
        return self.fn(self.arg.evaluate(env))
Пример #22
0
class Decl(Struct('names')):
    def build(self, env):
        for name in self.names:
            define(env.frames[-1], name,
                   solver.make_variable(env.prefix + name))
Пример #23
0
class Structures:
    MSG_4_STRUCT = Struct('I')    #4
    MSG_2_STRUCT = Struct('H')    #2
Пример #24
0

class VarDecl(Struct('type_id decls')):
    def build(self, env):
        type_ = env.types[self.type_id]
        for decl in self.decls:
            inst = type_.instantiate(env)
            env.init(decl.id, inst)
            for id, rhs in decl.params:
                LC.equate(inst.mapping[id], rhs.evaluate(env))

    def draw(self, env):
        pass


Declarator = Struct('id params', name='Declarator')


class Constraints(Struct('equations')):
    def build(self, env):
        for lhs, rhs in self.equations:
            LC.equate(lhs.evaluate(env), rhs.evaluate(env))

    def draw(self, env):
        pass


class Draw(Struct('drawables')):
    def build(self, env):
        pass
Пример #25
0
class Number(Struct('value')):
    def evaluate(self, env):
        return self.value
Пример #26
0
class Dot(Struct('base field')):
    def evaluate(self, env):
        return self.base.evaluate(env).mapping[self.field]
Пример #27
0
class Name(Struct('id')):
    def evaluate(self, env):
        return env.fetch(self.id)
Пример #28
0
class DrawFunction(Struct('fn_name')):
    def draw(self, env):
        draw_functions[self.fn_name](**env.inst.mapping)
Пример #29
0
class BinaryOp(Struct('arg1 arg2')):
    def evaluate(self, env):
        return self.operate(self.arg1.evaluate(env), self.arg2.evaluate(env))
Пример #30
0
class DrawName(Struct('name')):
    def draw(self, env):
        self.name.evaluate(env).draw(env)