@@ -167,7 +167,15 @@ export class BaseCompiler {
167167
168168 // Handle special constructs
169169 if ( h === 'Function' ) {
170- // Anonymous function
170+ // Dispatch to target-specific handler if available (e.g. GPU throws)
171+ const fnFn = target . functions ?.( h ) ;
172+ if ( typeof fnFn === 'function' )
173+ return fnFn (
174+ args ,
175+ ( expr ) => BaseCompiler . compile ( expr , target ) ,
176+ target
177+ ) ;
178+ // Default: JavaScript arrow function
171179 const params = args . slice ( 1 ) . map ( ( x ) => ( isSymbol ( x ) ? x . symbol : '_' ) ) ;
172180 return `((${ params . join ( ', ' ) } ) => ${ BaseCompiler . compile (
173181 args [ 0 ] . canonical ,
@@ -191,7 +199,16 @@ export class BaseCompiler {
191199 if ( h === 'Break' ) return 'break' ;
192200 if ( h === 'Continue' ) return 'continue' ;
193201
194- if ( h === 'Loop' ) return BaseCompiler . compileForLoop ( args , target ) ;
202+ if ( h === 'Loop' ) {
203+ const loopFn = target . functions ?.( h ) ;
204+ if ( typeof loopFn === 'function' )
205+ return loopFn (
206+ args ,
207+ ( expr ) => BaseCompiler . compile ( expr , target ) ,
208+ target
209+ ) ;
210+ return BaseCompiler . compileForLoop ( args , target ) ;
211+ }
195212
196213 if ( h === 'If' ) {
197214 if ( args . length !== 3 ) throw new Error ( 'If: wrong number of arguments' ) ;
@@ -296,17 +313,43 @@ export class BaseCompiler {
296313 return BaseCompiler . compile ( args [ 0 ] , target ) ;
297314 }
298315
316+ // Infer GPU type hints for Declare+Assign pairs (complex → vec2/vec2f)
317+ const typeHints : Record < string , string | undefined > = { } ;
318+ if ( target . declare && target . language ) {
319+ const isWGSL = target . language === 'wgsl' ;
320+ for ( const local of locals ) {
321+ for ( const arg of args ) {
322+ if ( isFunction ( arg , 'Assign' ) && isSymbol ( arg . ops [ 0 ] , local ) ) {
323+ if ( BaseCompiler . isComplexValued ( arg . ops [ 1 ] ) ) {
324+ typeHints [ local ] = isWGSL ? 'vec2f' : 'vec2' ;
325+ }
326+ break ;
327+ }
328+ }
329+ }
330+ }
331+
332+ const localTarget : CompileTarget < Expression > = {
333+ ...target ,
334+ var : ( id ) => {
335+ if ( locals . includes ( id ) ) return id ;
336+ return target . var ( id ) ;
337+ } ,
338+ } ;
339+
299340 const result = args
300341 . filter ( ( a ) => ! isSymbol ( a , 'Nothing' ) )
301- . map ( ( arg ) =>
302- BaseCompiler . compile ( arg , {
303- ...target ,
304- var : ( id ) => {
305- if ( locals . includes ( id ) ) return id ;
306- return target . var ( id ) ;
307- } ,
308- } )
309- )
342+ . map ( ( arg ) => {
343+ // For Declare, pass inferred type hint to the target hook
344+ if (
345+ isFunction ( arg , 'Declare' ) &&
346+ isSymbol ( arg . ops [ 0 ] ) &&
347+ target . declare
348+ ) {
349+ return target . declare ( arg . ops [ 0 ] . symbol , typeHints [ arg . ops [ 0 ] . symbol ] ) ;
350+ }
351+ return BaseCompiler . compile ( arg , localTarget ) ;
352+ } )
310353 . filter ( ( s ) => s !== '' ) ;
311354
312355 if ( result . length === 0 ) return '' ;
0 commit comments