@@ -890,50 +890,6 @@ partial def translate_statement_core
890890 -- output: init break flag, init statements, then a loop statement
891891 (ctx1, [initBreakFlag] ++ initStmts ++ [ .loop combinedCondition none none loopBody])
892892
893- | .TS_SwitchStatement switchStmt =>
894- -- Handle switch statement: switch discriminant { cases }
895-
896- -- Process all cases in their original order, separating regular from default
897- let allCases := switchStmt.cases.toList
898- let (regularCaseStmts, defaultStmts) := allCases.foldl (fun (regCases, defStmts) case =>
899- match case.test with
900- | some expr =>
901- -- Regular case
902- let discrimExpr := translate_expr switchStmt.discriminant
903- let caseValue := translate_expr expr
904- let testExpr := Heap.HExpr.app (Heap.HExpr.app (Heap.HExpr.deferredOp "Int.Eq" none) discrimExpr) caseValue
905- let (caseCtx, stmts) := case.consequent.foldl (fun (accCtx, accStmts) stmt =>
906- let (newCtx, newStmts) := translate_statement_core stmt accCtx
907- (newCtx, accStmts ++ newStmts)) (ctx, [])
908- (regCases ++ [(testExpr, stmts)], defStmts)
909- | none =>
910- -- Default case
911- let (defaultCtx, stmts) := case.consequent.foldl (fun (accCtx, accStmts) stmt =>
912- let (newCtx, newStmts) := translate_statement_core stmt accCtx
913- (newCtx, accStmts ++ newStmts)) (ctx, [])
914- (regCases, stmts)
915- ) ([], [])
916-
917- -- Build nested if-then-else structure for regular cases
918- let rec build_cases (cases: List (Heap.HExpr × List TSStrataStatement)) (defaultStmts: List TSStrataStatement) : TSStrataStatement :=
919- match cases with
920- | [] =>
921- -- No regular cases, just execute default if it exists
922- let defaultBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := defaultStmts }
923- .block "default" defaultBlock
924- | [(test, stmts)] =>
925- let thenBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := stmts }
926- let elseBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := defaultStmts }
927- .ite test thenBlock elseBlock
928- | (test, stmts) :: rest =>
929- let thenBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := stmts }
930- let elseBlock := build_cases rest defaultStmts
931- let elseBlockWrapped : Imperative.Block TSStrataExpression TSStrataCommand := { ss := [elseBlock] }
932- .ite test thenBlock elseBlockWrapped
933-
934- let switchStructure := build_cases regularCaseStmts defaultStmts
935- (ctx, [switchStructure])
936-
937893 | .TS_ContinueStatement cont =>
938894 let tgt :=
939895 match ct.continueLabel? with
@@ -958,7 +914,98 @@ partial def translate_statement_core
958914 | none => "__unbound_break"
959915 (ctx, [ .goto tgt ])
960916
961- | _ => panic! s! "Unimplemented statement: { repr s} "
917+ | .TS_SwitchStatement switchStmt =>
918+ -- Handle switch statement with fallthrough and break semantics
919+ dbg_trace s! "[DEBUG] Translating switch statement at loc { switchStmt.start_loc} -{ switchStmt.end_loc} "
920+
921+ -- Variables for storing control variables
922+ let loc := switchStmt.start_loc
923+ let discriminantVar := s! "switch_discriminant_{ loc} " -- Stores the switch expression value
924+ let fallthroughVar := s! "switch_fallthrough_{ loc} " -- Stores fallthrough state
925+ let breakFlagVar := s! "switch_break_{ loc} " -- Stores break state
926+
927+ -- Initialize control variables
928+ let initDiscriminant : TSStrataStatement := .cmd (.init discriminantVar (infer_type_from_expr switchStmt.discriminant) (translate_expr switchStmt.discriminant))
929+ let initFallthrough : TSStrataStatement := .cmd (.init fallthroughVar Heap.HMonoTy.bool Heap.HExpr.false )
930+ let initBreakFlag : TSStrataStatement := .cmd (.init breakFlagVar Heap.HMonoTy.bool Heap.HExpr.false )
931+
932+ -- Helper: split statements at break
933+ let splitAtBreak (stmts : List TS_Statement) : List TS_Statement × Bool :=
934+ let rec loop acc rest :=
935+ match rest with
936+ | [] => (acc.reverse, false )
937+ | .TS_BreakStatement _ :: _ => (acc.reverse, true )
938+ | s :: tail => loop (s :: acc) tail
939+ loop [] stmts
940+
941+ -- Helper: translate case body
942+ let translateCaseBody (stmts : List TS_Statement) (caseCtx : TranslationContext) : TranslationContext × List TSStrataStatement :=
943+ stmts.foldl (fun (c, acc) stmt =>
944+ let (c2, ss) := translate_statement_core stmt c ct
945+ (c2, acc ++ ss)) (caseCtx, [])
946+
947+ -- Helper: build case statements with optional break and fallthrough
948+ let buildCaseStmts (caseStmts : List TSStrataStatement) (hasBreak : Bool) (isDefault : Bool) : List TSStrataStatement :=
949+ let setFallthrough := .cmd (.set fallthroughVar Heap.HExpr.true )
950+ let setBreak := .cmd (.set breakFlagVar Heap.HExpr.true )
951+ let stmts := if isDefault then caseStmts else setFallthrough :: caseStmts
952+ if hasBreak then stmts ++ [setBreak] else stmts
953+
954+ -- Flag references
955+ let breakFlagRef := Heap.HExpr.lambda (.fvar breakFlagVar none)
956+ let discriminantRef := Heap.HExpr.lambda (.fvar discriminantVar none)
957+ let fallthroughRef := Heap.HExpr.lambda (.fvar fallthroughVar none)
958+
959+ -- Helper: create condition (if break then false else baseCondition)
960+ let mkCondition (baseCondition : Heap.HExpr) : Heap.HExpr :=
961+ Heap.HExpr.deferredIte breakFlagRef Heap.HExpr.false baseCondition
962+
963+ -- Helper: build case condition for regular case
964+ let mkCaseCondition (testExpr : TS_Expression) : Heap.HExpr :=
965+ let testVal := translate_expr testExpr
966+ let matchCond := Heap.HExpr.app (Heap.HExpr.app (Heap.HExpr.deferredOp "Int.Eq" none) discriminantRef) testVal
967+ let matchOrFallthrough := Heap.HExpr.app (Heap.HExpr.app (Heap.HExpr.deferredOp "Bool.Or" none) fallthroughRef) matchCond
968+ mkCondition matchOrFallthrough
969+
970+ -- Recursive case builder
971+ let rec buildCases (remainingCases : List TS_SwitchCase) (accCtx : TranslationContext) : TranslationContext × TSStrataStatement :=
972+ let emptyBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := [] }
973+
974+ match remainingCases with
975+ | [] => (accCtx, .ite Heap.HExpr.false emptyBlock emptyBlock)
976+
977+ | [singleCase] =>
978+ -- Last case: no rest to chain
979+ let (stmtsBeforeBreak, hasBreak) := splitAtBreak singleCase.consequent.toList
980+ let (caseCtx, caseStmts) := translateCaseBody stmtsBeforeBreak accCtx
981+ let isDefault := singleCase.test.isNone
982+ let finalStmts := buildCaseStmts caseStmts hasBreak isDefault
983+
984+ let condition := match singleCase.test with
985+ | none => mkCondition Heap.HExpr.true -- Default: if !break then true
986+ | some testExpr => mkCaseCondition testExpr
987+
988+ (caseCtx, .ite condition { ss := finalStmts } emptyBlock)
989+
990+ | currentCase :: restCases =>
991+ -- Non-last case: chain with rest
992+ let (stmtsBeforeBreak, hasBreak) := splitAtBreak currentCase.consequent.toList
993+ let (caseCtx, caseStmts) := translateCaseBody stmtsBeforeBreak accCtx
994+ let isDefault := currentCase.test.isNone
995+ let finalStmts := buildCaseStmts caseStmts hasBreak isDefault
996+ let (restCtx, restStmt) := buildCases restCases caseCtx
997+
998+ let condition := match currentCase.test with
999+ | none => mkCondition Heap.HExpr.true -- Default: if !break then true
1000+ | some testExpr => mkCaseCondition testExpr
1001+
1002+ (restCtx, .ite condition { ss := finalStmts ++ [restStmt] } { ss := [restStmt] })
1003+
1004+ let (finalCtx, switchBody) := buildCases switchStmt.cases.toList ctx
1005+ dbg_trace s! "[DEBUG] Switch statement translated with { switchStmt.cases.size} cases (with break support)"
1006+ (finalCtx, [initDiscriminant, initFallthrough, initBreakFlag, switchBody])
1007+
1008+ | _ => panic! s! "Unimplemented statement: { repr s} "
9621009
9631010-- Translate TypeScript statements to TypeScript-Strata statements
9641011partial def translate_statement (s: TS_Statement) (ctx : TranslationContext) : TranslationContext × List TSStrataStatement :=
0 commit comments