@@ -7,44 +7,78 @@ description: Enforce SaC code formatting and readability conventions.
77
88Use this skill when editing ` .sac ` files.
99
10- - Use consistent indentation and brace style.
11- - Preserve readability around shapes, signatures, and type-rich declarations.
10+ - Use spaces, not tabs.
11+ - Use 4-space indentation by default.
12+ - Preserve original trailing newline count at EOF.
1213- Keep edits minimal and local, especially in overloaded function families.
13- - Explain style-motivated refactors in one sentence.
14+
15+ ## Formatter-parity rules
16+
17+ Follow these rules exactly to match formatter behavior.
18+
19+ 1 . Guard formatting
20+ - Split multi-guard function signatures into guard lines.
21+ - First guard line starts with ` | ` .
22+ - Additional top-level guards start with ` , ` on following lines.
23+ - Do not split commas inside nested ` () ` , ` [] ` , ` {} ` .
24+ - Keep logical continuations (` || ` , ` && ` ) on same guard line when they continue a guard expression.
25+
26+ 2 . Comments
27+ - Keep ` // ` comments intact; never reinterpret commented code as active code.
28+ - Normalize comment prefix spacing to ` // ` when comment body exists.
29+
30+ 3 . Tensor comprehensions
31+ - Inline tensor comprehensions inside larger expressions should stay inline when already clear.
32+ - For a top-level ` return { ... }; ` tensor block:
33+ - One clause: use one-line form.
34+ - Multiple clauses: one clause per line, align ` -> ` and ` | ` columns.
35+
36+ 4 . With-loop formatting
37+ - Inline ` return with { ... } : genarray(...); ` may be expanded to multiline canonical form.
38+ - Keep ` } : genarray(...) ` arm aligned with the ` with ` keyword column.
39+
40+ 5 . Doc comments
41+ - Keep doc blocks aligned with one leading space before ` * ` lines and closing ` */ ` relative to declaration indentation.
1442
1543## Guard formatting example
1644
17- Use this formatting for multi-line function guards, function signatures, sacDocs, and simple tensor comprehensions .
45+ Use this formatting for multi-line function guards and nested expression continuations .
1846
1947``` sac
2048/**
21- * A rank-polymorphic selection function that returns a sub-array.
22- * It uses type patterns to match dimensionality and a vertical bar (|)
23- * to enforce explicit domain constraints.
24- * The first guard line starts with `| ` and subsequent lines start with `, `.
25- *
26- * @param iv An index vector specifying which elements to select, must be non-negative and within bounds.
27- * @param a The input array from which to select elements, must have compatible shape.
28- * @return A new array containing the selected elements based on the index vector.
49+ * Rank-polymorphic selection with explicit domain checks.
50+ *
51+ * @param iv Index vector.
52+ * @param a Input array.
53+ * @return Selected sub-array.
2954 */
30- int[m:ishp] mySel (int[n] iv, int[n:shp, m:ishp] a)
31- | all (0 <= iv) /* Guard: The index vector must be non-negative */
32- , all (iv < shp) /* Guard: The index must be within the bounds of 'shp' */
55+ int[m:ishp] mySel(int[n] iv, int[n:shp, m:ishp] a)
56+ | all(0 <= iv)
57+ , all(iv < shp)
58+ , ((n > m && ishp == []) || (ishp == shp))
3359{
34- return { jv -> _sel_VxA_(++ (iv, jv), a) | jv < ishp };
60+ return { jv -> _sel_VxA_(++(iv, jv), a) | jv < ishp };
3561}
3662```
3763
38- Use multi-line style for with-loops and complex tensor comprehensions as well.
39-
4064## Big with-loop example
4165
4266``` sac
4367int[m, n] checkerboard(int[m, n] a)
4468{
45- return with {
46- ( . <= [i, j] <= . ) : (a[i, j] + i + j) % 2;
47- } : genarray([m, n], 0);
69+ return with {
70+ (. <= [i, j] <= .) : (a[i, j] + i + j) % 2;
71+ } : genarray([m, n], 0);
72+ }
73+ ```
74+
75+ ## Inline tensor comprehension in expression
76+
77+ ``` sac
78+ int[d:shp] vsum2(int[n, d:shp] a)
79+ {
80+ transposed_a = transpose(a);
81+ return d > 0 ? transpose({ iv -> sum(transposed_a[iv]) | iv < reverse(shp) }) : sum(a);
4882}
4983```
5084
@@ -53,9 +87,18 @@ int[m, n] checkerboard(int[m, n] a)
5387``` sac
5488int[m, n] edgeMask(int[m, n] a)
5589{
56- return {
57- [i, j] -> abs(a[i, j] - a[i, j - 1]) + abs(a[i, j] - a[i - 1, j]) | [14 ] <= [i, j] < [m - 1, n - 1];
58- [i, j] -> 0 | [i, j] < [m, n]
59- };
90+ return {
91+ [i, j] -> abs(a[i, j] - a[i, j - 1]) + abs(a[i, j] - a[i - 1, j]) | [1, 1 ] <= [i, j] < [m - 1, n - 1];
92+ [i, j] -> 0 | [i, j] < [m, n]
93+ };
6094}
61- ```
95+ ```
96+
97+ ## ` .sac-format ` keys
98+
99+ When present, align behavior with these keys:
100+ - ` IndentSize `
101+ - ` TabWidth `
102+ - ` NormalizeGuards `
103+ - ` ExpandInlineWithLoops `
104+ - ` ExpandInlineComprehensions `
0 commit comments