@@ -11,7 +11,7 @@ import qualified Text.PrettyPrint.Leijen as PP
12import qualified AST.Expression.General as Expr
12import qualified AST.Expression.General as Expr
13import AST.Expression.Optimized as Opt
13import AST.Expression.Optimized as Opt
14−import AST.Literal
14+import qualified AST.Literal as L
15import qualified AST.Module as Module
15import qualified AST.Module as Module
16import qualified AST.Module.Name as ModuleName
16import qualified AST.Module.Name as ModuleName
17import qualified AST.Variable as Var
17import qualified AST.Variable as Var
@@ -195,8 +195,8 @@ generateCode expr =
195 If branches finally ->
195 If branches finally ->
196 generateIf branches finally
196 generateIf branches finally
198− Case expr decisionTree branches ->
198+ Case root decisionTree branches ->
199− generateCase expr decisionTree branches
199+ JsBlock <$> generateCase root decisionTree branches
201 ExplicitList elements ->
201 ExplicitList elements ->
202 do jsElements <- mapM generateJsExpr elements
202 do jsElements <- mapM generateJsExpr elements
@@ -215,7 +215,7 @@ generateCode expr =
215 jsExpr $ DotRef () jsDataExpr (var ("_" ++ show index))
215 jsExpr $ DotRef () jsDataExpr (var ("_" ++ show index))
217 GLShader _uid src _tipe ->
217 GLShader _uid src _tipe ->
218− jsExpr $ ObjectLit () [(PropString () "src", Literal.literal (Str src))]
218+ jsExpr $ ObjectLit () [(PropString () "src", Literal.literal (L.Str src))]
220 Port impl ->
220 Port impl ->
221 case impl of
221 case impl of
@@ -319,7 +319,7 @@ crushIfsHelp visitedBranches unvisitedBranches finally =
320 (reverse visitedBranches, finally)
320 (reverse visitedBranches, finally)
322− (Literal (Boolean True), branch) : _ ->
322+ (Literal (L.Boolean True), branch) : _ ->
323 crushIfsHelp visitedBranches [] branch
323 crushIfsHelp visitedBranches [] branch
325 visiting : unvisited ->
325 visiting : unvisited ->
@@ -329,12 +329,117 @@ crushIfsHelp visitedBranches unvisitedBranches finally =
329-- CASE EXPRESSIONS
329-- CASE EXPRESSIONS
331generateCase
331generateCase
332− :: Opt.Expr
332+ :: String
333 -> DT.DecisionTree Opt.Jump
333 -> DT.DecisionTree Opt.Jump
334 -> [(Int, Opt.Branch)]
334 -> [(Int, Opt.Branch)]
335− -> State Int Code
335+ -> State Int [Statement ()]
336−generateCase expr decisionTree branches =
336+generateCase root decisionTree jumpBranches =
337− error "TODO"
337+ do decider <- generateDecisionTree root decisionTree
338+ foldM (goto root) decider jumpBranches
341+goto :: String -> [Statement ()] -> (Int, Opt.Branch) -> State Int [Statement ()]
342+goto root decider (target, branch) =
346+ (targetLabel root target)
347+ (DoWhileStmt () (BlockStmt () decider) (BoolLit () False))
349+ do stmts <- generateBranch root branch
350+ return (deciderStmt : stmts)
353+targetLabel :: String -> Int -> Id ()
354+targetLabel root target =
355+ Id () (root ++ "_" ++ show target)
358+generateDecisionTree :: String -> DT.DecisionTree Opt.Jump -> State Int [Statement ()]
359+generateDecisionTree root decisionTree =
360+ case decisionTree of
361+ DT.Match (Opt.Inline branch) ->
362+ generateBranch root branch
364+ DT.Match (Opt.Jump target) ->
365+ return [ BreakStmt () (Just (targetLabel root target)) ]
367+ DT.Decision testPath edges fallback ->
368+ do accessExpr <- generateJsExpr (pathToExpr root testPath)
371+ case fst (head edges) of
373+ DotRef () accessExpr (Id () "ctor")
378+ caseClauses <- mapM (edgeToCaseClause root) edges
379+ caseDefault <- fallbackToDefault root fallback
381+ return [ SwitchStmt () testExpr (caseClauses ++ caseDefault) ]
384+edgeToCaseClause :: String -> (DT.Test, DT.DecisionTree Opt.Jump) -> State Int (CaseClause ())
385+edgeToCaseClause root (test, subTree) =
386+ CaseClause () (testToExpr test) <$> generateDecisionTree root subTree
389+testToExpr :: DT.Test -> Expression ()
392+ DT.Constructor (Var.Canonical _ tag) ->
395+ DT.Literal (L.Chr char) ->
402+fallbackToDefault :: String -> Maybe (DT.DecisionTree Opt.Jump) -> State Int [CaseClause ()]
403+fallbackToDefault root fallback =
409+ do stmts <- generateDecisionTree root subTree
410+ return [ CaseDefault () stmts ]
413+generateBranch :: String -> Opt.Branch -> State Int [Statement ()]
414+generateBranch root (Opt.Branch substitutions expr) =
415+ do subts <- mapM (loadPath root) substitutions
416+ code <- generateCode expr
417+ return (subts ++ toStatementList code)
420+loadPath :: String -> (String, DT.Path) -> State Int (Statement ())
421+loadPath root (name, path) =
422+ do jsAccessExpr <- generateJsExpr (pathToExpr root path)
423+ return $ VarDeclStmt () [ varDecl name jsAccessExpr ]
426+pathToExpr :: String -> DT.Path -> Opt.Expr
427+pathToExpr root fullPath =
428+ go (Opt.Var (Var.local root)) fullPath
432+ DT.Position index subpath ->
433+ go (Opt.DataAccess expr index) subpath
435+ DT.Field field subpath ->
436+ go (Opt.Access expr field) subpath
340-- BINARY OPERATORS
445-- BINARY OPERATORS