Skip to content

Commit 655756a

Browse files
committed
spec: v0.2
spec/tooling: add default case in `build_signature` spec/tooling: fix hidden global variable spec/tooling: fix silent side effect spec/tooling: context manage file reads spec: fix precedence Swap precedence of ADD and SUB and treat the first subexpression of a SUB differently
1 parent 46b4024 commit 655756a

2 files changed

Lines changed: 23 additions & 12 deletions

File tree

spec/expr.typ

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656
"div": 5, // /
5757
"sum": 6, // Σ
5858
"not": 7, // not
59-
"add": 8, // +
60-
"sub": 9, // -
59+
"sub": 8, // -
60+
"add": 9, // +
6161
"eq": 10, // = and :=
6262
"MAX": 11, // <the void outside every expression>
6363
)
@@ -187,7 +187,10 @@
187187
mwrap($-#rec(PREC.neg, e.at(1))$, pp < PREC.neg)
188188
} else {
189189
// Subtraction
190-
mwrap($#e.slice(1).map(rec.with(PREC.sub)).join($-$)$, pp < PREC.sub)
190+
mwrap(
191+
$#rec(PREC.add, e.at(1))-#e.slice(2).map(rec.with(PREC.sub)).join($-$)$,
192+
pp <= PREC.sub
193+
)
191194
}
192195
},
193196
"cast": (pp, rec, e) => {

spec/tooling/chip.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import sys
23
import tomllib
34
from collections.abc import Callable, Iterable
@@ -390,7 +391,7 @@ def typecheck[T](
390391
yield from callback(env.with_val(self.name, Range.const(i)))
391392

392393

393-
def iters_of(obj: dict, name=None) -> list[Iter]:
394+
def iters_of(obj: dict, config, name=None) -> list[Iter]:
394395
"""Return a list of iterators needed by `obj`. Taken from `iters` or `iter`.
395396
Prepend `name` to every iterator, if given.
396397
Adapted from the corresponding typst implementation."""
@@ -538,7 +539,8 @@ def __init__(self, data: dict):
538539
@classmethod
539540
def from_file(cls, filename: str | Path) -> Self:
540541
reporter.update_location(str(filename))
541-
return cls(tomllib.load(open(filename, "rb")))
542+
with open(filename, "rb") as fp:
543+
return cls(tomllib.load(fp))
542544

543545
@classmethod
544546
def from_string(cls, s: str) -> Self:
@@ -607,14 +609,14 @@ def __init__(self, config: Config, name: str, tp: Type, data: dict):
607609
idx = data.get("idx", None)
608610
self.defs = [
609611
PolyWithIters(
610-
build_expr(config, data["poly"]), iters_of(data, name=idx)
612+
build_expr(config, data["poly"]), iters_of(data, config, name=idx)
611613
)
612614
]
613615
elif "polys" in data:
614616
idx = data.get("idx", None)
615617
self.defs = [
616618
PolyWithIters(
617-
build_expr(config, poly["poly"]), iters_of(poly, name=idx)
619+
build_expr(config, poly["poly"]), iters_of(poly, config, name=idx)
618620
)
619621
for poly in data["polys"]
620622
]
@@ -629,6 +631,7 @@ class VirtualVariable(Variable):
629631
def __init__(self, config: Config, category: str, data: dict):
630632
assert_no_unexpected(data, (set(Variable.__annotations__.keys()) | {"def"}) - {"pad"})
631633
reporter.asserts("def" in data, f"Missing def for virtual column: {data!r}")
634+
data = copy.deepcopy(data)
632635
def_ = data.pop("def", {})
633636
super().__init__(config, category, data)
634637
self.def_ = VirtualDef(config, self.name, self.type, def_)
@@ -753,7 +756,7 @@ def __init__(self, config: Config, data: dict):
753756
data, set(self.__annotations__.keys()) | {"iter", "iters", "ref"}
754757
)
755758
self.desc = data["desc"]
756-
self.iters = iters_of(data)
759+
self.iters = iters_of(data, config)
757760

758761

759762
@dataclass
@@ -778,7 +781,7 @@ def __init__(self, config: Config, data: dict):
778781
isinstance(self.desc, str), f"desc is not a string: {self.desc!r}"
779782
)
780783
self.poly = build_expr(config, data["poly"])
781-
self.iters = iters_of(data)
784+
self.iters = iters_of(data, config)
782785

783786
def typecheck(self, env: Environment) -> Iterable[Never]:
784787
# TODO? Should we check that there's no overflow of the modulus?
@@ -873,7 +876,7 @@ def __init__(self, config: Config, data: dict):
873876
f"Missing {self.conditional_name}: {data!r}",
874877
)
875878
self.conditional = None
876-
self.iters = iters_of(data)
879+
self.iters = iters_of(data, config)
877880

878881
def typecheck(self, env: Environment) -> Iterable[Signature]:
879882
def callback(e: Environment) -> Iterable[Signature]:
@@ -974,7 +977,8 @@ def __init__(self, config: Config, data: dict):
974977
@classmethod
975978
def from_file(cls, config: Config, filename: str | Path) -> Self:
976979
reporter.update_location(str(filename))
977-
return cls(config, tomllib.load(open(filename, "rb")))
980+
with open(filename, "rb") as fp:
981+
return cls(config, tomllib.load(fp))
978982

979983
@classmethod
980984
def from_string(cls, config: Config, s: str) -> Self:
@@ -1015,6 +1019,9 @@ def build_signature(config: Config, data: dict) -> Signature:
10151019
"cond" not in data, f"Template signature with cond: {data!r}"
10161020
)
10171021
Sig = InteractionSignature
1022+
case other:
1023+
reporter.error(f"Signature of invalid kind '{other}': {data!r}")
1024+
Sig = Signature
10181025
tag = data["tag"]
10191026
reporter.asserts(isinstance(tag, str), f"Signature tag not a string: {tag!r}")
10201027
input = [build_type(config, inp) for inp in data["input"]]
@@ -1026,7 +1033,8 @@ def build_signature(config: Config, data: dict) -> Signature:
10261033

10271034

10281035
def read_signatures(config, filename) -> list[Signature]:
1029-
data = tomllib.load(open(filename, "rb"))
1036+
with open(filename, "rb") as fp:
1037+
data = tomllib.load(fp)
10301038
assert_no_unexpected(data, {"signatures"})
10311039
return [build_signature(config, sig) for sig in data["signatures"]]
10321040

0 commit comments

Comments
 (0)