@@ -427,7 +427,41 @@ static MASObject *builtin_input_num(Interpreter *interp, MASObject **args, int a
427427 case AST_ASSIGN :
428428 {
429429 MASObject * value = evaluate (node -> data .assign .value , interp );
430- symbol_table_set (interp -> locals , node -> data .assign .name , value );
430+
431+ if (node -> data .assign .index == NULL ) {
432+ // Plain variable assignment
433+ symbol_table_set (interp -> locals , node -> data .assign .name , value );
434+ } else {
435+ // Indexed assignment: a[i] = value
436+
437+ // 1. Find the list variable
438+ MASObject * list_obj = symbol_table_get (interp -> locals , node -> data .assign .name );
439+ if (!list_obj ) {
440+ list_obj = symbol_table_get (interp -> globals , node -> data .assign .name );
441+ }
442+ if (!list_obj || list_obj -> type != AST_LIST ) {
443+ fprintf (stderr , "Error: '%s' is not a list\n" , node -> data .assign .name );
444+ exit (1 );
445+ }
446+
447+ // 2. Evaluate index
448+ MASObject * index_obj = evaluate (node -> data .assign .index , interp );
449+ if (index_obj -> type != AST_NUMBER ) {
450+ fprintf (stderr , "List index must be a number\n" );
451+ exit (1 );
452+ }
453+ int idx = (int )index_obj -> data .number ;
454+
455+ // 3. Bounds check
456+ if (idx < 0 || idx >= list_obj -> data .list .count ) {
457+ fprintf (stderr , "Index %d out of bounds\n" , idx );
458+ exit (1 );
459+ }
460+
461+ // 4. Assign (replace item)
462+ // In pure GC, just overwrite — old item may become unreachable
463+ list_obj -> data .list .items [idx ] = value ;
464+ }
431465 return value ;
432466 }
433467 case AST_BINOP :
@@ -669,6 +703,36 @@ static MASObject *builtin_input_num(Interpreter *interp, MASObject **args, int a
669703 case AST_FUNCDEF :
670704 interpreter_add_function (interp , node -> data .funcdef .name , node );
671705 return create_null ();
706+ case AST_INDEX :
707+ {
708+ // Look up the list variable
709+ MASObject * list_obj = symbol_table_get (interp -> locals , node -> data .index .target );
710+ if (!list_obj ) {
711+ list_obj = symbol_table_get (interp -> globals , node -> data .index .target );
712+ }
713+ if (!list_obj || list_obj -> type != AST_LIST ) {
714+ fprintf (stderr , "Error: '%s' is not a list (line %d)\n" ,
715+ node -> data .index .target , node -> line );
716+ exit (1 );
717+ }
718+
719+ // Evaluate index expression
720+ MASObject * index_obj = evaluate (node -> data .index .index , interp );
721+ if (index_obj -> type != AST_NUMBER ) {
722+ fprintf (stderr , "List index must be a number (line %d)\n" , node -> line );
723+ exit (1 );
724+ }
725+ int idx = (int )index_obj -> data .number ;
726+
727+ // Bounds check
728+ if (idx < 0 || idx >= list_obj -> data .list .count ) {
729+ fprintf (stderr , "Index %d out of bounds (line %d)\n" , idx , node -> line );
730+ exit (1 );
731+ }
732+
733+ // Return the item (no incref — GC handles it)
734+ return list_obj -> data .list .items [idx ];
735+ }
672736 default :
673737 fprintf (stderr , "Unknown AST node type: %d\n" , node -> type );
674738 exit (1 );
0 commit comments