@@ -97,11 +97,8 @@ private void initializeImportResolver(UnitNode unit) {
9797 DebugSystem .debug ("IMPORTS" , "Initializing import resolver for unit: " + unit .name );
9898
9999 // UPDATED: Only pre-load imports that were already resolved during AST building
100- // Don't try to resolve new imports here - do it lazily when needed
101100 if (unit .resolvedImports != null && !unit .resolvedImports .isEmpty ()) {
102- DebugSystem .debug (
103- "IMPORTS" ,
104- "Pre-loading " + unit .resolvedImports .size () + " resolved imports from AST" );
101+ DebugSystem .debug ("IMPORTS" , "Pre-loading " + unit .resolvedImports .size () + " resolved imports from AST" );
105102 for (Map .Entry <String , ProgramNode > entry : unit .resolvedImports .entrySet ()) {
106103 String importName = entry .getKey ();
107104 ProgramNode importedProgram = entry .getValue ();
@@ -258,27 +255,15 @@ boolean shouldReturnEarly(
258255 return true ; // All slots in current path are assigned
259256 }
260257
261- public Object evalMethodCall (
262- MethodCallNode call ,
263- ObjectInstance obj ,
264- Map <String , Object > locals ) {
265- DebugSystem .methodEntry ("call:" + call .name , emptyParamMap ());
266-
267- // ADDED: Detailed debugging for method call
268- DebugSystem .debug ("METHOD_CALL" , "=== METHOD CALL ENTERED ===" );
258+ public Object evalMethodCall (MethodCallNode call , ObjectInstance obj , Map <String , Object > locals ) {
259+ DebugSystem .debug ("METHOD_CALL" , "=== METHOD CALL DEBUG ===" );
269260 DebugSystem .debug ("METHOD_CALL" , "call.name: " + call .name );
270261 DebugSystem .debug ("METHOD_CALL" , "call.qualifiedName: " + call .qualifiedName );
271262 DebugSystem .debug ("METHOD_CALL" , "call.slotNames: " + call .slotNames );
272- DebugSystem .debug ("METHOD_CALL" , "call.arguments: " + call .arguments .size ());
273- for (int i = 0 ; i < call .arguments .size (); i ++) {
274- DebugSystem .debug ("METHOD_CALL" , " arg[" + i + "]: " + call .arguments .get (i ).getClass ().getSimpleName ());
275- }
276263 DebugSystem .debug ("METHOD_CALL" , "Current object type: " + obj .type .name );
277- DebugSystem .debug ("METHOD_CALL" , "Current object fields: " + obj .fields .keySet ());
278-
264+
279265 MethodNode method = null ;
280266
281- // First, try to find method in current type
282267 DebugSystem .debug ("METHOD_CALL" , "Searching for local method: '" + call .name + "'" );
283268 for (int i = 0 ; i < obj .type .methods .size (); i ++) {
284269 MethodNode candidate = obj .type .methods .get (i );
@@ -290,19 +275,15 @@ public Object evalMethodCall(
290275 }
291276 }
292277
293- // If not found locally, try to resolve as imported method
294278 if (method == null ) {
295279 DebugSystem .debug ("METHOD_CALL" , "Method not found locally, attempting import resolution" );
296280
297- // FIX: Handle cases where the method name itself might be qualified
298281 String qualifiedMethodName = call .qualifiedName ;
299282
300- // If qualifiedName is null but call.name contains dots, use call.name as qualified
301283 if (qualifiedMethodName == null && call .name .contains ("." )) {
302284 qualifiedMethodName = call .name ;
303285 DebugSystem .debug ("IMPORTS" , "Using call.name as qualified name: " + qualifiedMethodName );
304286 } else if (qualifiedMethodName == null ) {
305- // Fallback: just use the simple name
306287 qualifiedMethodName = call .name ;
307288 DebugSystem .debug ("IMPORTS" , "Using simple name as qualified name: " + qualifiedMethodName );
308289 } else if (qualifiedMethodName != null ) {
@@ -314,49 +295,34 @@ public Object evalMethodCall(
314295
315296 if (method != null ) {
316297 DebugSystem .debug ("IMPORTS" , "Successfully resolved imported method: " + qualifiedMethodName );
317- DebugSystem .debug ("IMPORTS" , "Resolved method details - name: " + method .name +
318- ", params: " + method .parameters .size () +
319- ", slots: " + method .returnSlots .size ()); // This works again!
320298 } else {
321299 DebugSystem .warn ("IMPORTS" , "Failed to resolve imported method: " + qualifiedMethodName );
322-
323- // Additional debugging: show what imports are available
324- Set <String > availableImports = importResolver .getLoadedImports ();
325- DebugSystem .debug ("IMPORTS" , "Available loaded imports: " + availableImports );
326- Set <String > registeredImports = importResolver .getRegisteredImports ();
327- DebugSystem .debug ("IMPORTS" , "Registered imports: " + registeredImports );
328-
329- // Show what methods are available in current type for comparison
330- DebugSystem .debug ("IMPORTS" , "Available local methods:" );
331- for (MethodNode m : obj .type .methods ) {
332- DebugSystem .debug ("IMPORTS" , " - " + m .name );
333- }
334300 }
335301 }
336302
337303 if (method == null ) {
338- DebugSystem .error (
339- "IMPORTS" ,
340- "Method not found: "
341- + (call .qualifiedName != null ? call .qualifiedName : call .name ));
342- // Debug: List available methods in current type
304+ DebugSystem .error ("IMPORTS" , "Method not found: " +
305+ (call .qualifiedName != null ? call .qualifiedName : call .name ));
306+
343307 DebugSystem .debug ("METHODS" , "Available methods in current type:" );
344308 for (MethodNode m : obj .type .methods ) {
345309 DebugSystem .debug ("METHODS" , " - " + m .name );
346310 }
347311
348- // Show import status for debugging
349312 importResolver .debugImportStatus ();
350313
351314 throw new RuntimeException (
352- "Method not found: "
353- + (call .qualifiedName != null ? call .qualifiedName : call .name ));
315+ "Method not found: " +
316+ (call .qualifiedName != null ? call .qualifiedName : call .name ));
317+ }
318+
319+ if (method .isBuiltin ) {
320+ return handleBuiltinMethod (method , call , obj , locals );
354321 }
355322
356323 Map <String , Object > newLocals = new HashMap <String , Object >();
357324 DebugSystem .debug ("METHODS" , "Evaluating " + call .arguments .size () + " arguments" );
358325
359- // Validate parameter count
360326 if (call .arguments .size () != method .parameters .size ()) {
361327 throw new RuntimeException (
362328 "Parameter count mismatch for method " + method .name +
@@ -366,88 +332,86 @@ public Object evalMethodCall(
366332
367333 for (int i = 0 ; i < call .arguments .size (); i ++) {
368334 ParamNode param = method .parameters .get (i );
369- Object argValue =
370- exprEvaluator .evaluate (
371- call .arguments .get (i ), obj , locals );
335+ Object argValue = exprEvaluator .evaluate (call .arguments .get (i ), obj , locals );
372336 newLocals .put (param .name , argValue );
373337 DebugSystem .debug ("MEMORY" , "Bound parameter: " + param .name + " = " + argValue );
374338 }
375339
376- // --- MODIFICATION: Reverted to original, efficient slot initialization ---
377340 Map <String , Object > slotValues = new HashMap <String , Object >();
378341 for (SlotNode s : method .returnSlots ) {
379342 slotValues .put (s .name , null );
380343 DebugSystem .debug ("SLOTS" , "Initialized return slot: " + s .name );
381344 }
382- // --- END MODIFICATION (REMOVED PRE-SCAN LOOP) ---
383-
384345
385- // Execute method body with access to both locals AND slots
386346 Map <String , Object > previousSlots = currentSlots ;
387347 currentSlots = slotValues ;
388348
389- // FIX: Only set up slot path tracking if the called method has slots
390349 Set <String > previousSlotsInPath = slotsInCurrentPath ;
391- boolean calledMethodHasSlots = !method .returnSlots .isEmpty (); // This works again
350+ boolean calledMethodHasSlots = !method .returnSlots .isEmpty ();
392351 if (calledMethodHasSlots ) {
393352 slotsInCurrentPath = new HashSet <>(slotValues .keySet ());
394353 DebugSystem .debug ("SLOTS" , "Called method has " + method .returnSlots .size () + " slots" );
395354 } else {
396- slotsInCurrentPath = new HashSet <>(); // Empty for void methods
355+ slotsInCurrentPath = new HashSet <>();
397356 DebugSystem .debug ("SLOTS" , "Called method has no return slots" );
398357 }
399358
400359 DebugSystem .debug ("METHOD_CALL" , "Executing method body for: " + method .name );
401360 for (StatementNode stmt : method .body ) {
402- stmtEvaluator .evalStmt (
403- stmt , obj , newLocals , slotValues );
404- // Check for early return in called method
361+ stmtEvaluator .evalStmt (stmt , obj , newLocals , slotValues );
405362 if (calledMethodHasSlots && shouldReturnEarly (slotValues )) {
406363 DebugSystem .debug ("SLOTS" , "Early return triggered in called method" );
407364 break ;
408365 }
409366 }
410367
411368 currentSlots = previousSlots ;
412- slotsInCurrentPath = previousSlotsInPath ; // Restore previous slot path
369+ slotsInCurrentPath = previousSlotsInPath ;
413370
414- DebugSystem .methodExit ( " call: " + call .name , slotValues );
371+ DebugSystem .debug ( "METHOD_CALL" , "Method call completed: " + method .name );
415372 return slotValues ;
416373}
417374
418- private MethodNode resolveImportedMethod (String qualifiedMethodName ) {
419- DebugSystem .debug ("IMPORTS" , "resolveImportedMethod called with: " + qualifiedMethodName );
375+ private Object handleBuiltinMethod (MethodNode method , MethodCallNode call , ObjectInstance obj , Map <String , Object > locals ) {
376+ switch (method .name ) {
377+ case "outa" :
378+ return handleSysOuta (call , obj , locals );
379+ default :
380+ throw new RuntimeException ("Unknown builtin method: " + method .name );
381+ }
382+ }
420383
421- try {
422- MethodNode method = importResolver .findMethod (qualifiedMethodName );
423- if (method != null ) {
424- DebugSystem .debug (
425- "IMPORTS" , "Successfully resolved imported method: " + qualifiedMethodName );
426- DebugSystem .debug (
427- "IMPORTS" ,
428- "Method details - params: "
429- + method .parameters .size ()
430- + ", slots: "
431- + method .returnSlots .size ()); // This works again
432- return method ;
433- } else {
434- DebugSystem .warn (
435- "IMPORTS" , "Failed to resolve imported method: " + qualifiedMethodName );
436-
437- // Debug: List available imports
438- Set <String > loadedImports = importResolver .getLoadedImports ();
439- DebugSystem .debug ("IMPORTS" , "Loaded imports in resolver: " + loadedImports );
440- return null ;
441- }
442- } catch (Exception e ) {
443- DebugSystem .error (
444- "IMPORTS" ,
445- "Error resolving imported method "
446- + qualifiedMethodName
447- + ": "
448- + e .getMessage ());
449- e .printStackTrace ();
384+ private Object handleSysOuta (MethodCallNode call , ObjectInstance obj , Map <String , Object > locals ) {
385+ StringBuilder result = new StringBuilder ();
386+ for (int i = 0 ; i < call .arguments .size (); i ++) {
387+ Object value = exprEvaluator .evaluate (call .arguments .get (i ), obj , locals );
388+ result .append (String .valueOf (value ));
389+ }
390+ ioHandler .output (result .toString ());
391+ return null ;
392+ }
393+
394+ private MethodNode resolveImportedMethod (String qualifiedMethodName ) {
395+ DebugSystem .debug ("IMPORTS" , "resolveImportedMethod called with: " + qualifiedMethodName );
396+
397+ try {
398+ MethodNode method = importResolver .findMethod (qualifiedMethodName );
399+ if (method != null ) {
400+ DebugSystem .debug ("IMPORTS" , "Successfully resolved imported method: " + qualifiedMethodName );
401+ DebugSystem .debug ("IMPORTS" , "Method details - params: " + method .parameters .size () + ", slots: " + method .returnSlots .size ());
402+ return method ;
403+ } else {
404+ DebugSystem .warn ("IMPORTS" , "Failed to resolve imported method: " + qualifiedMethodName );
405+
406+ // Debug: List available imports
407+ Set <String > loadedImports = importResolver .getLoadedImports ();
408+ DebugSystem .debug ("IMPORTS" , "Loaded imports in resolver: " + loadedImports );
450409 return null ;
451410 }
411+ } catch (Exception e ) {
412+ DebugSystem .error ("IMPORTS" , "Error resolving imported method " + qualifiedMethodName + ": " + e .getMessage ());
413+ e .printStackTrace ();
414+ return null ;
452415 }
416+ }
453417}
0 commit comments