@@ -240,6 +240,8 @@ public final class LLVMCodeGenerator {
240240 generateMatchStatement ( matchStatement, index: index, errorBlock: errorBlock)
241241 case let forEachLoop as ForEachLoop :
242242 generateForEachLoop ( forEachLoop, index: index, errorBlock: errorBlock)
243+ case let rangeLoop as RangeLoop :
244+ generateRangeLoop ( rangeLoop, index: index, errorBlock: errorBlock)
243245 case let whileLoop as WhileLoop :
244246 generateWhileLoop ( whileLoop, index: index, errorBlock: errorBlock)
245247 case is BreakStatement :
@@ -301,6 +303,10 @@ public final class LLVMCodeGenerator {
301303 // Build object descriptor
302304 let objectDesc = buildObjectDescriptor ( statement. object, prefix: prefix)
303305
306+ // Clear _default_value_ before binding modifiers (mirrors FeatureSetExecutor line 255)
307+ let defaultValueName = ctx. stringConstant ( " _default_value_ " )
308+ _ = ctx. module. insertCall ( externals. variableUnbind, on: [ ctx. currentContextVar!, defaultValueName] , at: ctx. insertionPoint)
309+
304310 // Bind query modifiers if present
305311 bindQueryModifiers ( statement. queryModifiers)
306312
@@ -585,6 +591,17 @@ public final class LLVMCodeGenerator {
585591 at: ip
586592 )
587593 }
594+
595+ // Bind default value if present (for optional retrieve with fallback)
596+ if let defaultExpr = modifiers. defaultValue {
597+ let defaultName = ctx. stringConstant ( " _default_value_ " )
598+ let defaultJSON = ctx. stringConstant ( serializeExpression ( defaultExpr) )
599+ _ = ctx. module. insertCall (
600+ externals. evaluateAndBind,
601+ on: [ ctx. currentContextVar!, defaultName, defaultJSON] ,
602+ at: ip
603+ )
604+ }
588605 }
589606
590607 private func bindRangeModifiers( _ modifiers: RangeModifiers ) {
@@ -846,11 +863,21 @@ public final class LLVMCodeGenerator {
846863 }
847864
848865 private func escapeJSON( _ s: String ) -> String {
849- s. replacingOccurrences ( of: " \\ " , with: " \\ \\ " )
850- . replacingOccurrences ( of: " \" " , with: " \\ \" " )
851- . replacingOccurrences ( of: " \n " , with: " \\ n " )
852- . replacingOccurrences ( of: " \r " , with: " \\ r " )
853- . replacingOccurrences ( of: " \t " , with: " \\ t " )
866+ var result = " "
867+ for scalar in s. unicodeScalars {
868+ switch scalar. value {
869+ case 0x5C : result += " \\ \\ " // backslash
870+ case 0x22 : result += " \\ \" " // double quote
871+ case 0x0A : result += " \\ n " // newline
872+ case 0x0D : result += " \\ r " // carriage return
873+ case 0x09 : result += " \\ t " // tab
874+ case 0x00 ..< 0x20 : // other control characters (incl. ESC 0x1B)
875+ result += String ( format: " \\ u%04x " , scalar. value)
876+ default :
877+ result += String ( scalar)
878+ }
879+ }
880+ return result
854881 }
855882
856883 // MARK: - Control Flow (Stubs)
@@ -995,6 +1022,12 @@ public final class LLVMCodeGenerator {
9951022 for stmt in forEachLoop. body {
9961023 collectBoundVariablesFromStatement ( stmt, into: & variables)
9971024 }
1025+ } else if let rangeLoop = statement as? RangeLoop {
1026+ // Range loop variable and body variables
1027+ variables. insert ( rangeLoop. variable)
1028+ for stmt in rangeLoop. body {
1029+ collectBoundVariablesFromStatement ( stmt, into: & variables)
1030+ }
9981031 } else if let whileLoop = statement as? WhileLoop {
9991032 // While loop variables are in the outer scope — collect them
10001033 for stmt in whileLoop. body {
@@ -1154,6 +1187,88 @@ public final class LLVMCodeGenerator {
11541187 ctx. setInsertionPoint ( atEndOf: endBlock)
11551188 }
11561189
1190+ // MARK: - Range Loop Generation (for <var> from <low> to <high>)
1191+
1192+ private func generateRangeLoop( _ loop: RangeLoop , index: Int , errorBlock: BasicBlock ) {
1193+ let prefix = " range \( index) "
1194+
1195+ // Create loop blocks
1196+ let condBlock = ctx. module. appendBlock ( named: " \( prefix) _cond " , to: ctx. currentFunction!)
1197+ let bodyBlock = ctx. module. appendBlock ( named: " \( prefix) _body " , to: ctx. currentFunction!)
1198+ let incrBlock = ctx. module. appendBlock ( named: " \( prefix) _incr " , to: ctx. currentFunction!)
1199+ let endBlock = ctx. module. appendBlock ( named: " \( prefix) _end " , to: ctx. currentFunction!)
1200+
1201+ // Evaluate `from` and `to` expressions into temp variables
1202+ let fromTempName = ctx. stringConstant ( " _rng_from_ \( index) _ " )
1203+ let toTempName = ctx. stringConstant ( " _rng_to_ \( index) _ " )
1204+
1205+ let fromJSON = ctx. stringConstant ( serializeExpression ( loop. from) )
1206+ _ = ctx. module. insertCall ( externals. evaluateAndBind, on: [ ctx. currentContextVar!, fromTempName, fromJSON] , at: ctx. insertionPoint)
1207+
1208+ let toJSON = ctx. stringConstant ( serializeExpression ( loop. to) )
1209+ _ = ctx. module. insertCall ( externals. evaluateAndBind, on: [ ctx. currentContextVar!, toTempName, toJSON] , at: ctx. insertionPoint)
1210+
1211+ // Extract integer values into stack-allocated i64 storage
1212+ let fromIntPtr = ctx. module. insertAlloca ( ctx. i64Type, at: ctx. insertionPoint)
1213+ let toIntPtr = ctx. module. insertAlloca ( ctx. i64Type, at: ctx. insertionPoint)
1214+ ctx. module. insertStore ( ctx. i64Type. zero, to: fromIntPtr, at: ctx. insertionPoint)
1215+ ctx. module. insertStore ( ctx. i64Type. zero, to: toIntPtr, at: ctx. insertionPoint)
1216+ _ = ctx. module. insertCall ( externals. variableResolveInt, on: [ ctx. currentContextVar!, fromTempName, fromIntPtr] , at: ctx. insertionPoint)
1217+ _ = ctx. module. insertCall ( externals. variableResolveInt, on: [ ctx. currentContextVar!, toTempName, toIntPtr] , at: ctx. insertionPoint)
1218+
1219+ let toInt = ctx. module. insertLoad ( ctx. i64Type, from: toIntPtr, at: ctx. insertionPoint)
1220+ let fromInt = ctx. module. insertLoad ( ctx. i64Type, from: fromIntPtr, at: ctx. insertionPoint)
1221+
1222+ // Allocate loop counter starting at fromInt
1223+ let counterPtr = ctx. module. insertAlloca ( ctx. i64Type, at: ctx. insertionPoint)
1224+ ctx. module. insertStore ( fromInt, to: counterPtr, at: ctx. insertionPoint)
1225+
1226+ // Jump to condition check
1227+ ctx. module. insertBr ( to: condBlock, at: ctx. insertionPoint)
1228+
1229+ // === Condition Block: loop while counter < toInt ===
1230+ ctx. setInsertionPoint ( atEndOf: condBlock)
1231+ let curCount = ctx. module. insertLoad ( ctx. i64Type, from: counterPtr, at: ctx. insertionPoint)
1232+ let done = ctx. module. insertIntegerComparison ( . sge, curCount, toInt, at: ctx. insertionPoint)
1233+ ctx. module. insertCondBr ( if: done, then: endBlock, else: bodyBlock, at: ctx. insertionPoint)
1234+
1235+ // === Body Block ===
1236+ ctx. setInsertionPoint ( atEndOf: bodyBlock)
1237+
1238+ let bodyCount = ctx. module. insertLoad ( ctx. i64Type, from: counterPtr, at: ctx. insertionPoint)
1239+
1240+ // Bind loop variable as boxed integer (unbind first to allow rebinding)
1241+ let varNameStr = ctx. stringConstant ( loop. variable)
1242+ _ = ctx. module. insertCall ( externals. variableUnbind, on: [ ctx. currentContextVar!, varNameStr] , at: ctx. insertionPoint)
1243+ let varValue = ctx. module. insertCall ( externals. valueCreateInt, on: [ bodyCount] , at: ctx. insertionPoint)
1244+ _ = ctx. module. insertCall ( externals. variableBindValue, on: [ ctx. currentContextVar!, varNameStr, varValue] , at: ctx. insertionPoint)
1245+
1246+ // Unbind all body-bound variables to allow rebinding on each iteration
1247+ let bodyVars = collectBoundVariables ( from: loop. body)
1248+ for varName in bodyVars where varName != loop. variable {
1249+ let bodyVarName = ctx. stringConstant ( varName)
1250+ _ = ctx. module. insertCall ( externals. variableUnbind, on: [ ctx. currentContextVar!, bodyVarName] , at: ctx. insertionPoint)
1251+ }
1252+
1253+ // Generate body statements
1254+ for (stmtIndex, stmt) in loop. body. enumerated ( ) {
1255+ generateStatement ( stmt, index: index * 100 + stmtIndex, errorBlock: incrBlock)
1256+ }
1257+
1258+ // Branch to increment
1259+ ctx. module. insertBr ( to: incrBlock, at: ctx. insertionPoint)
1260+
1261+ // === Increment Block ===
1262+ ctx. setInsertionPoint ( atEndOf: incrBlock)
1263+ let nextCount = ctx. module. insertLoad ( ctx. i64Type, from: counterPtr, at: ctx. insertionPoint)
1264+ let incremented = ctx. module. insertAdd ( nextCount, ctx. i64Type. constant ( 1 ) , at: ctx. insertionPoint)
1265+ ctx. module. insertStore ( incremented, to: counterPtr, at: ctx. insertionPoint)
1266+ ctx. module. insertBr ( to: condBlock, at: ctx. insertionPoint)
1267+
1268+ // === End Block ===
1269+ ctx. setInsertionPoint ( atEndOf: endBlock)
1270+ }
1271+
11571272 // MARK: - While Loop Generation (ARO-0131)
11581273
11591274 private func generateWhileLoop( _ loop: WhileLoop , index: Int , errorBlock: BasicBlock ) {
0 commit comments