@@ -553,6 +553,90 @@ pub fn (mut g Gen) if_expr(ifexpr ast.IfExpr, expected ast.Type, existing_rvars
553553 g.if_branch (ifexpr, expected, params, 0 , existing_rvars)
554554}
555555
556+ pub fn (mut g Gen) match_expr (node ast.MatchExpr, expected ast.Type, existing_rvars []Var) {
557+ results := if expected == ast.void_type {
558+ []wasm.ValType{}
559+ } else if existing_rvars.len == 0 {
560+ g.unpack_type (expected).map (g.get_wasm_type (it ))
561+ } else {
562+ g.unpack_type (expected).filter (! g.is_param_type (it )).map (g.get_wasm_type (it ))
563+ }
564+ g.match_branch (node, expected, results, 0 , existing_rvars)
565+ }
566+
567+ fn (mut g Gen) match_branch (node ast.MatchExpr, expected ast.Type, unpacked_params []wasm.ValType, branch_idx int , existing_rvars []Var) {
568+ if branch_idx > = node.branches.len {
569+ return
570+ }
571+
572+ branch := node.branches[branch_idx]
573+ mut is_last_branch := branch_idx + 1 > = node.branches.len
574+ mut has_else := branch.is_else
575+
576+ if has_else {
577+ if branch.stmts.len > 0 {
578+ g.rvar_expr_stmts (branch.stmts, expected, existing_rvars)
579+ }
580+ return
581+ }
582+
583+ if branch.exprs.len > 0 {
584+ g.match_branch_exprs (node, expected, unpacked_params, branch_idx, 0 , existing_rvars,
585+ branch)
586+ } else {
587+ if branch.stmts.len > 0 {
588+ g.rvar_expr_stmts (branch.stmts, expected, existing_rvars)
589+ }
590+ if ! is_last_branch {
591+ g.match_branch (node, expected, unpacked_params, branch_idx + 1 , existing_rvars)
592+ }
593+ }
594+ }
595+
596+ fn (mut g Gen) match_branch_exprs (node ast.MatchExpr, expected ast.Type, unpacked_params []wasm.ValType, branch_idx int , expr_idx int , existing_rvars []Var, branch ast.MatchBranch) {
597+ if expr_idx > = branch.exprs.len {
598+ return
599+ }
600+
601+ mut is_last_branch := branch_idx + 1 > = node.branches.len
602+ mut is_last_expr := expr_idx + 1 > = branch.exprs.len
603+
604+ wasm_type := g.as_numtype (g.get_wasm_type (node.cond_type))
605+
606+ expr := branch.exprs[expr_idx]
607+
608+ if expr is ast.RangeExpr {
609+ is_signed := node.cond_type.is_signed ()
610+
611+ g.expr (node.cond, node.cond_type)
612+ g.expr (expr.high, node.cond_type)
613+ g.func.le (wasm_type, is_signed)
614+ } else {
615+ g.expr (node.cond, node.cond_type)
616+ g.expr (expr, node.cond_type)
617+ g.func.eq (wasm_type)
618+ }
619+
620+ blk := g.func.c_if ([], unpacked_params)
621+ {
622+ if branch.stmts.len > 0 {
623+ g.rvar_expr_stmts (branch.stmts, expected, existing_rvars)
624+ }
625+ }
626+ {
627+ g.func.c_else (blk)
628+ if is_last_expr {
629+ if ! is_last_branch {
630+ g.match_branch (node, expected, unpacked_params, branch_idx + 1 , existing_rvars)
631+ }
632+ } else {
633+ g.match_branch_exprs (node, expected, unpacked_params, branch_idx, expr_idx + 1 ,
634+ existing_rvars, branch)
635+ }
636+ }
637+ g.func.c_end (blk)
638+ }
639+
556640pub fn (mut g Gen) call_expr (node ast.CallExpr, expected ast.Type, existing_rvars []Var) {
557641 mut wasm_ns := ? string (none )
558642 mut name := node.name
@@ -850,7 +934,7 @@ pub fn (mut g Gen) expr(node ast.Expr, expected ast.Type) {
850934 g.cast (node.typ, expected)
851935 }
852936 ast.MatchExpr {
853- g.w_error ( 'wasm backend does not support match expressions yet' )
937+ g.match_expr (node, expected, [] )
854938 }
855939 ast.EnumVal {
856940 type_name := g.table.get_type_name (node.typ)
0 commit comments