@kernlang/python 3.5.9-canary.220.1.c398cd95 → 4.0.1-canary.222.1.f06f1a51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codegen-body-python.d.ts +86 -0
- package/dist/codegen-body-python.js +894 -28
- package/dist/codegen-body-python.js.map +1 -1
- package/dist/codegen-helpers.d.ts +1 -0
- package/dist/codegen-helpers.js +19 -6
- package/dist/codegen-helpers.js.map +1 -1
- package/dist/codegen-python.d.ts +1 -1
- package/dist/codegen-python.js +6 -2
- package/dist/codegen-python.js.map +1 -1
- package/dist/core/expr/helpers.d.ts +1 -0
- package/dist/core/expr/helpers.js +109 -2
- package/dist/core/expr/helpers.js.map +1 -1
- package/dist/core/expr/index.d.ts +1 -1
- package/dist/core/expr/index.js +214 -87
- package/dist/core/expr/index.js.map +1 -1
- package/dist/core/expr/list-ops.d.ts +81 -0
- package/dist/core/expr/list-ops.js +228 -0
- package/dist/core/expr/list-ops.js.map +1 -0
- package/dist/core/handlers/index.js +1 -0
- package/dist/core/handlers/index.js.map +1 -1
- package/dist/fastapi-portable.js +1 -0
- package/dist/fastapi-portable.js.map +1 -1
- package/dist/fastapi-route.js +132 -24
- package/dist/fastapi-route.js.map +1 -1
- package/dist/generators/data.d.ts +2 -0
- package/dist/generators/data.js +417 -14
- package/dist/generators/data.js.map +1 -1
- package/dist/generators/ground.js +52 -14
- package/dist/generators/ground.js.map +1 -1
- package/dist/targets/python.js +10 -0
- package/dist/targets/python.js.map +1 -1
- package/dist/type-map.d.ts +15 -0
- package/dist/type-map.js +46 -0
- package/dist/type-map.js.map +1 -1
- package/package.json +2 -2
|
@@ -51,6 +51,15 @@ export interface BodyEmitOptions {
|
|
|
51
51
|
* the KERN-form `userId` resolves to the snake_cased Python parameter.
|
|
52
52
|
* Identifiers not in the map pass through unchanged. */
|
|
53
53
|
symbolMap?: Record<string, string>;
|
|
54
|
+
/** When true, the handler is a class member body: identifier `super`
|
|
55
|
+
* lowers to Python `super()` (so `super.m()` -> `super().m()`) and a
|
|
56
|
+
* direct `super(...)` call lowers to `super().__init__(...)`. Paired with
|
|
57
|
+
* a `symbolMap` entry `this -> self` by the class generator. */
|
|
58
|
+
inClassBody?: boolean;
|
|
59
|
+
/** When true, the handler is specifically a constructor body, so a direct
|
|
60
|
+
* `super(...)` call lowers to `super().__init__(...)`. Outside a constructor
|
|
61
|
+
* `super(...)` is not a parent-constructor call and is left untouched. */
|
|
62
|
+
inConstructor?: boolean;
|
|
54
63
|
/** Slice 4a review fix (Gemini #5) — how to lower the `?` propagation
|
|
55
64
|
* hoist's err-branch return:
|
|
56
65
|
* - 'value' (default for `fn`): `return __k_tN` so the caller sees
|
|
@@ -75,6 +84,16 @@ export interface BodyEmitOptions {
|
|
|
75
84
|
forIterNext?: boolean;
|
|
76
85
|
letAssign?: boolean;
|
|
77
86
|
};
|
|
87
|
+
/** Coercion-slice opt-out for the helper-less Ground/React declarative
|
|
88
|
+
* layer. Defaults to `true` (native KERN bodies + expression unit tests
|
|
89
|
+
* get full JS value→string coercion, injecting helpers function-locally).
|
|
90
|
+
* The Ground generators (`coalesce`/`firstDefined`/`firstTruthy`/`objectMerge`
|
|
91
|
+
* /…) emit module-level statements via `emitPyExpression` and have no
|
|
92
|
+
* channel to define `_kern_fmt`/`__kern_add`/`_KERN_UNDEFINED`, so they pass
|
|
93
|
+
* `false` to keep the pre-slice output (zero regression). Extending coercion
|
|
94
|
+
* to the Ground layer needs module-level (single-definition) helper
|
|
95
|
+
* injection — a separate follow-up. */
|
|
96
|
+
coerceJsValues?: boolean;
|
|
78
97
|
/** Outer-scope names the body INHERITS — typically function parameters and
|
|
79
98
|
* module-level globals the wrapper has bound. Pre-populated as the
|
|
80
99
|
* outermost `localScopes` map so an inner-block `let` that shadows ANY of
|
|
@@ -108,6 +127,11 @@ export interface BodyEmitResult {
|
|
|
108
127
|
usedPropagation: boolean;
|
|
109
128
|
helpers: Set<string>;
|
|
110
129
|
}
|
|
130
|
+
export interface PyExpressionEmitResult {
|
|
131
|
+
code: string;
|
|
132
|
+
imports: Set<string>;
|
|
133
|
+
helpers: Set<string>;
|
|
134
|
+
}
|
|
111
135
|
interface BodyEmitContext {
|
|
112
136
|
gensymCounter: number;
|
|
113
137
|
imports: Set<string>;
|
|
@@ -116,6 +140,8 @@ interface BodyEmitContext {
|
|
|
116
140
|
* `each` pair-mode). Consumer emits each entry at module scope. */
|
|
117
141
|
helpers: Set<string>;
|
|
118
142
|
symbolMap: Record<string, string>;
|
|
143
|
+
inClassBody: boolean;
|
|
144
|
+
inConstructor: boolean;
|
|
119
145
|
shadowedSymbols: Set<string>;
|
|
120
146
|
localScopes: Array<Map<string, 'const' | 'let' | 'cell'>>;
|
|
121
147
|
regexScopes: Array<Map<string, Extract<ValueIR, {
|
|
@@ -146,6 +172,65 @@ interface BodyEmitContext {
|
|
|
146
172
|
* override pending control flow, so it gets a finally-specific error. */
|
|
147
173
|
finallyDepth: number;
|
|
148
174
|
standaloneExpression: boolean;
|
|
175
|
+
/** When true, helper-dependent JS value→string coercion is emitted
|
|
176
|
+
* (`__kern_add`, `_kern_fmt`-wrapped templates, the `_KERN_UNDEFINED`
|
|
177
|
+
* sentinel + sentinel-aware `??`/`typeof`). Native KERN bodies inject the
|
|
178
|
+
* required helpers function-locally, so the default is true. The Ground/
|
|
179
|
+
* React declarative layer (`coalesce`/`firstDefined`/etc.) emits module-
|
|
180
|
+
* level statements through `emitPyExpression` with NO per-statement helper
|
|
181
|
+
* channel, so it opts out and keeps the pre-coercion-slice forms (raw `+`,
|
|
182
|
+
* raw f-string interpolation, `None` for undefined, None-only `??`).
|
|
183
|
+
* See BodyEmitOptions.coerceJsValues. */
|
|
184
|
+
coerceJsValues: boolean;
|
|
185
|
+
/** Slices 0+1 — block-bodied arrow closure lowering. When `emitLambdaPy`
|
|
186
|
+
* lowers a block arrow it pushes a hoisted local `def __kern_closure_N(...)`
|
|
187
|
+
* (a block of source lines) here and returns the def's NAME as the
|
|
188
|
+
* expression string. `emitChildrenPy`'s per-child loop flushes the buffer
|
|
189
|
+
* IMMEDIATELY BEFORE the statement that referenced it (at the current
|
|
190
|
+
* indent), so the def precedes its use even inside if/else/loop bodies. A
|
|
191
|
+
* buffer left non-empty when a handler body finishes is a BUG (defensive
|
|
192
|
+
* throw at the body-emit entry point). */
|
|
193
|
+
pendingHoists: string[][];
|
|
194
|
+
/** Monotonic gensym counter for hoisted closure def names. Separate from
|
|
195
|
+
* `gensymCounter` so closure names stay stable/independent of other
|
|
196
|
+
* gensym usage. */
|
|
197
|
+
closureSeq: number;
|
|
198
|
+
/** Slice-2 loop-variable pinning. Each entry is the INDEX into `localScopes`
|
|
199
|
+
* of a scope that is a loop BODY (an `each`/`for`/`while` body). A captured
|
|
200
|
+
* name is pinned (JS per-iteration capture → Python default arg) IFF its
|
|
201
|
+
* binding resolves at an index `>= loopScopeIndexes[0]` — i.e. at or inside
|
|
202
|
+
* the OUTERMOST enclosing loop body. Bindings declared OUTSIDE every loop
|
|
203
|
+
* (function params, accumulators, a `while` condition var) resolve below
|
|
204
|
+
* `loopScopeIndexes[0]` and stay late-bound (already JS-parity-correct).
|
|
205
|
+
* Pushed on loop-body entry, popped on exit (LIFO, mirrors `localScopes`). */
|
|
206
|
+
loopScopeIndexes: number[];
|
|
207
|
+
/** Slice-2 fix (agon review, claude 0.7) — one frame per active loop body,
|
|
208
|
+
* parallel to `loopScopeIndexes`. `assignLast` maps a bare assign-target
|
|
209
|
+
* name to the LAST top-level child index (within that loop body) whose
|
|
210
|
+
* subtree assigns it; `current` is the child index the loop body is
|
|
211
|
+
* emitting right now. The default-arg pin freezes a capture at def time,
|
|
212
|
+
* but JS captures BY REFERENCE — so a pinned per-iteration binding that is
|
|
213
|
+
* REASSIGNED in a LATER sibling statement diverges (JS sees the mutation,
|
|
214
|
+
* the frozen default does not). Such captures fail closed at emission
|
|
215
|
+
* instead of emitting silently wrong values. Because within-child statement
|
|
216
|
+
* order is NOT tracked (the whole top-level child shares one index), the
|
|
217
|
+
* reject is `>=` (not `>`): a reassignment in the SAME top-level child as the
|
|
218
|
+
* closure also fails closed (it cannot be proven to run before the closure).
|
|
219
|
+
* `assignLast` covers both `assign` (incl. compound/postfix `op=` forms, same
|
|
220
|
+
* node type) and `set` (a bare-name cell write).
|
|
221
|
+
*
|
|
222
|
+
* Mutation-v1 note: this sibling-reassignment check applies ONLY to PINNED
|
|
223
|
+
* candidates (per-iteration loop-locals that pin via a default arg). A
|
|
224
|
+
* free-variable WRITE inside a closure body (`emitBlockClosurePy`'s
|
|
225
|
+
* `nonlocal` path) targets an OUTER binding declared below the outermost
|
|
226
|
+
* loop scope, so it is never a pin candidate and never enters this frame —
|
|
227
|
+
* the `>=` reject cannot misfire on a nonlocal-written capture. (A write to a
|
|
228
|
+
* binding that IS a per-iteration capture is rejected earlier as
|
|
229
|
+
* `closure-pinned-write`, so the two paths stay disjoint.) */
|
|
230
|
+
loopLaterAssignFrames: Array<{
|
|
231
|
+
assignLast: Map<string, number>;
|
|
232
|
+
current: number;
|
|
233
|
+
}>;
|
|
149
234
|
}
|
|
150
235
|
/** PR-4 — Python helpers that normalize `each` pair-mode iteration sources.
|
|
151
236
|
* Co-located with the codegen so the production emitter and the differential
|
|
@@ -213,6 +298,7 @@ export declare function emitNativeKernBodyPythonWithImports(handlerNode: IRNode,
|
|
|
213
298
|
* `emitPyExprCtx` which threads the live ctx (and therefore the live
|
|
214
299
|
* imports set) end-to-end. */
|
|
215
300
|
export declare function emitPyExpression(node: ValueIR, options?: BodyEmitOptions): string;
|
|
301
|
+
export declare function emitPyExpressionWithImports(node: ValueIR, options?: BodyEmitOptions): PyExpressionEmitResult;
|
|
216
302
|
export declare function lowerBitwiseAndModuloAST(node: ValueIR): ValueIR;
|
|
217
303
|
export declare function registerHelpers(node: ValueIR, ctx: BodyEmitContext): void;
|
|
218
304
|
export {};
|