@@ -48,16 +48,16 @@ private def isBareContinueStmt (s : TS_Statement) : Bool :=
4848private def isIfWithBareContinue (s : TS_Statement) : Option TS_IfStatement :=
4949 match s with
5050 | .TS_IfStatement ifs =>
51- let conseqIsBare :=
52- match ifs.consequent with
53- | .TS_ContinueStatement _ => true
54- | .TS_BlockStatement b =>
55- -- exactly one statement and it is `continue`
56- match b.body.toList with
57- | [one] => isBareContinueStmt one
58- | _ => false
59- | _ => false
60- if conseqIsBare && ifs.alternate.isNone then some ifs else none
51+ let conseqIsBare :=
52+ match ifs.consequent with
53+ | .TS_ContinueStatement _ => true
54+ | .TS_BlockStatement b =>
55+ -- exactly one statement and it is `continue`
56+ match b.body.toList with
57+ | [one] => isBareContinueStmt one
58+ | _ => false
59+ | _ => false
60+ if conseqIsBare && ifs.alternate.isNone then some ifs else none
6161 | _ => none
6262
6363def TS_type_to_HMonoTy (ty: String) : Heap.HMonoTy :=
@@ -224,19 +224,19 @@ partial def translate_statement_core
224224 (ct: ControlTargets := {}) : TranslationContext × List TSStrataStatement :=
225225 match s with
226226 | .TS_FunctionDeclaration funcDecl =>
227- -- Translate function definition
228- dbg_trace s! "[DEBUG] Translating TypeScript function definition: { funcDecl.id.name} "
229- dbg_trace s! "[DEBUG] Function parameters: { funcDecl.params.toList.map (·.name)} "
230- dbg_trace s! "[DEBUG] Function body has statements"
227+ -- Translate function definition
228+ dbg_trace s! "[DEBUG] Translating TypeScript function definition: { funcDecl.id.name} "
229+ dbg_trace s! "[DEBUG] Function parameters: { funcDecl.params.toList.map (·.name)} "
230+ dbg_trace s! "[DEBUG] Function body has statements"
231231
232- let (bodyCtx, funcBody) := match funcDecl.body with
232+ let (bodyCtx, funcBody) := match funcDecl.body with
233233 | .TS_BlockStatement blockStmt =>
234234 -- Thread context through function body to handle nested functions
235235 blockStmt.body.toList.foldl
236236 (fun (accCtx, accStmts) stmt =>
237237 let (newCtx, stmts) := translate_statement_core stmt accCtx ct
238- (newCtx, accStmts ++ stmts))
239- (ctx, [])
238+ (newCtx, accStmts ++ stmts))
239+ (ctx, [])
240240 | _ => panic! s! "Expected block statement as function body, got: { repr funcDecl.body} "
241241
242242 dbg_trace s! "[DEBUG] Translated function body to { funcBody.length} Strata statements"
@@ -454,28 +454,28 @@ partial def translate_statement_core
454454
455455 let isIfWithBareContinue : TS_Statement → Option TS_IfStatement
456456 | .TS_IfStatement ifs =>
457- let conseqIsBare :=
458- match ifs.consequent with
459- | .TS_ContinueStatement _ => true
460- | .TS_BlockStatement b =>
461- match b.body.toList with
462- | [one] => isBareContinueStmt one
463- | _ => false
464- | _ => false
465- if conseqIsBare && ifs.alternate.isNone then some ifs else none
457+ let conseqIsBare :=
458+ match ifs.consequent with
459+ | .TS_ContinueStatement _ => true
460+ | .TS_BlockStatement b =>
461+ match b.body.toList with
462+ | [one] => isBareContinueStmt one
463+ | _ => false
464+ | _ => false
465+ if conseqIsBare && ifs.alternate.isNone then some ifs else none
466466 | _ => none
467467
468468 let isIfWithBareBreak : TS_Statement → Option TS_IfStatement
469469 | .TS_IfStatement ifs =>
470- let conseqIsBare :=
471- match ifs.consequent with
472- | .TS_BreakStatement _ => true
473- | .TS_BlockStatement b =>
474- match b.body.toList with
475- | [one] => isBareBreakStmt one
476- | _ => false
477- | _ => false
478- if conseqIsBare && ifs.alternate.isNone then some ifs else none
470+ let conseqIsBare :=
471+ match ifs.consequent with
472+ | .TS_BreakStatement _ => true
473+ | .TS_BlockStatement b =>
474+ match b.body.toList with
475+ | [one] => isBareBreakStmt one
476+ | _ => false
477+ | _ => false
478+ if conseqIsBare && ifs.alternate.isNone then some ifs else none
479479 | _ => none
480480
481481 -- when we hit the pattern (in a loop), guard the tail with `else`
@@ -493,8 +493,8 @@ partial def translate_statement_core
493493 let (tailCtx, tailStmts) :=
494494 tail.foldl
495495 (fun (p, accS) stmt =>
496- let (p2, ss2) := translate_statement_core stmt p ct
497- (p2, accS ++ ss2))
496+ let (p2, ss2) := translate_statement_core stmt p ct
497+ (p2, accS ++ ss2))
498498 (accCtx, [])
499499 let cond := translate_expr ifs.test
500500 let thenBlk : Imperative.Block TSStrataExpression TSStrataCommand := { ss := [] }
@@ -506,8 +506,8 @@ partial def translate_statement_core
506506 let (tailCtx, tailStmts) :=
507507 tail.foldl
508508 (fun (p, accS) stmt =>
509- let (p2, ss2) := translate_statement_core stmt p ct
510- (p2, accS ++ ss2))
509+ let (p2, ss2) := translate_statement_core stmt p ct
510+ (p2, accS ++ ss2))
511511 (accCtx, [])
512512 let cond := translate_expr ifs.test
513513 let setBreakFlag : TSStrataStatement := .cmd (.set breakFlagVar Heap.HExpr.true )
@@ -558,8 +558,8 @@ partial def translate_statement_core
558558 (bodyCtx, [ initBreakFlag, .loop combinedCondition none none bodyBlock ])
559559
560560 | .TS_ForStatement forStmt =>
561-
562561 dbg_trace s! "[DEBUG] Translating for statement at loc { forStmt.start_loc} -{ forStmt.end_loc} "
562+
563563 let continueLabel := s! "for_continue_{ forStmt.start_loc} "
564564 let breakLabel := s! "for_break_{ forStmt.start_loc} "
565565 let breakFlagVar := s! "for_break_flag_{ forStmt.start_loc} "
@@ -571,12 +571,10 @@ partial def translate_statement_core
571571 let (_, initStmts) := translate_statement_core (.TS_VariableDeclaration forStmt.init) ctx
572572 -- guard (test)
573573 let guard := translate_expr forStmt.test
574-
575574 -- body (first translate loop body with break support)
576575 let (ctx1, bodyStmts) :=
577576 translate_statement_core forStmt.body ctx
578577 { continueLabel? := some continueLabel, breakLabel? := some breakLabel, breakFlagVar? := some breakFlagVar }
579-
580578 -- update (translate expression into statements following ExpressionStatement style)
581579 let (_, updateStmts) :=
582580 translate_statement_core
@@ -599,31 +597,75 @@ partial def translate_statement_core
599597 -- output: init break flag, init statements, then a loop statement
600598 (ctx1, [initBreakFlag] ++ initStmts ++ [ .loop combinedCondition none none loopBody])
601599
602- | .TS_ContinueStatement cont =>
603- let tgt :=
604- match ct.continueLabel? with
605- | some lab => lab
606- | none =>
607- dbg_trace "[WARN] `continue` encountered outside of a loop; emitting goto to __unbound_continue" ;
608- "__unbound_continue"
609- (ctx, [ .goto tgt ])
610-
611- | .TS_BreakStatement brk =>
612- -- Handle break statement if loop context fails to handle it
613- dbg_trace "[WARN] `break` statement not handled by pattern matching" ;
614- match ct.breakFlagVar? with
615- | some flagVar =>
616- -- Set break flag to true as fallback
617- (ctx, [ .cmd (.set flagVar Heap.HExpr.true ) ])
618- | none =>
619- dbg_trace "[WARN] `break` encountered outside of a loop; using fallback goto" ;
600+ | .TS_SwitchStatement switchStmt =>
601+ -- Handle switch statement: switch discriminant { cases }
602+
603+ -- Process all cases in their original order, separating regular from default
604+ let allCases := switchStmt.cases.toList
605+ let (regularCaseStmts, defaultStmts) := allCases.foldl (fun (regCases, defStmts) case =>
606+ match case.test with
607+ | some expr =>
608+ -- Regular case
609+ let discrimExpr := translate_expr switchStmt.discriminant
610+ let caseValue := translate_expr expr
611+ let testExpr := Heap.HExpr.app (Heap.HExpr.app (Heap.HExpr.deferredOp "Int.Eq" none) discrimExpr) caseValue
612+ let (caseCtx, stmts) := case.consequent.foldl (fun (accCtx, accStmts) stmt =>
613+ let (newCtx, newStmts) := translate_statement_core stmt accCtx
614+ (newCtx, accStmts ++ newStmts)) (ctx, [])
615+ (regCases ++ [(testExpr, stmts)], defStmts)
616+ | none =>
617+ -- Default case
618+ let (defaultCtx, stmts) := case.consequent.foldl (fun (accCtx, accStmts) stmt =>
619+ let (newCtx, newStmts) := translate_statement_core stmt accCtx
620+ (newCtx, accStmts ++ newStmts)) (ctx, [])
621+ (regCases, stmts)
622+ ) ([], [])
623+
624+ -- Build nested if-then-else structure for regular cases
625+ let rec build_cases (cases: List (Heap.HExpr × List TSStrataStatement)) (defaultStmts: List TSStrataStatement) : TSStrataStatement :=
626+ match cases with
627+ | [] =>
628+ -- No regular cases, just execute default if it exists
629+ let defaultBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := defaultStmts }
630+ .block "default" defaultBlock
631+ | [(test, stmts)] =>
632+ let thenBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := stmts }
633+ let elseBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := defaultStmts }
634+ .ite test thenBlock elseBlock
635+ | (test, stmts) :: rest =>
636+ let thenBlock : Imperative.Block TSStrataExpression TSStrataCommand := { ss := stmts }
637+ let elseBlock := build_cases rest defaultStmts
638+ let elseBlockWrapped : Imperative.Block TSStrataExpression TSStrataCommand := { ss := [elseBlock] }
639+ .ite test thenBlock elseBlockWrapped
640+
641+ let switchStructure := build_cases regularCaseStmts defaultStmts
642+ (ctx, [switchStructure])
643+
644+ | .TS_ContinueStatement cont =>
620645 let tgt :=
621- match ct.breakLabel ? with
646+ match ct.continueLabel ? with
622647 | some lab => lab
623- | none => "__unbound_break"
648+ | none =>
649+ dbg_trace "[WARN] `continue` encountered outside of a loop; emitting goto to __unbound_continue" ;
650+ "__unbound_continue"
624651 (ctx, [ .goto tgt ])
625652
626- | _ => panic! s! "Unimplemented statement: { repr s} "
653+ | .TS_BreakStatement brk =>
654+ -- Handle break statement if loop context fails to handle it
655+ dbg_trace "[WARN] `break` statement not handled by pattern matching" ;
656+ match ct.breakFlagVar? with
657+ | some flagVar =>
658+ -- Set break flag to true as fallback
659+ (ctx, [ .cmd (.set flagVar Heap.HExpr.true ) ])
660+ | none =>
661+ dbg_trace "[WARN] `break` encountered outside of a loop; using fallback goto" ;
662+ let tgt :=
663+ match ct.breakLabel? with
664+ | some lab => lab
665+ | none => "__unbound_break"
666+ (ctx, [ .goto tgt ])
667+
668+ | _ => panic! s! "Unimplemented statement: { repr s} "
627669
628670-- Translate TypeScript statements to TypeScript-Strata statements
629671partial def translate_statement (s: TS_Statement) (ctx : TranslationContext) : TranslationContext × List TSStrataStatement :=
0 commit comments