metasepi / idiomaticca

Translate IDIOMATIC C into human-readable ATS
http://metasepi.org/
GNU Affero General Public License v3.0
3 stars 0 forks source link

Support switch case #35

Closed master-q closed 5 years ago

master-q commented 5 years ago

I want to use case expr of in ATS for switch/case in C.

master-q commented 5 years ago

If we translate following...

int switch_case(char c) {
    int ret;

    switch (c) {
    case '1':
    case '2':
    case '3':
        ret = 1;
        break;
    case ' ':
        ret = 2;
        break;
    default:
        ret = 3;
        break;
    }

    return ret;
}
master-q commented 5 years ago

ret := 1 codes are duplicated...

fun switch_case (c: char): int =
  let
    var ret: int
    val () = case c of
      | '1' => ret := 1
      | '2' => ret := 1
      | '3' => ret := 1
      | ' ' => ret := 2
      | _   => ret := 3
  in
    ret
  end
master-q commented 5 years ago

Following is better translation?

fun switch_case (c: char): int =
  let
    var ret: int
    val () = case c of
      | _ when c = '1' || c = '2' || c = '3' => ret := 1
      | ' ' => ret := 2
      | _   => ret := 3
  in
    ret
  end
master-q commented 5 years ago

The case's AST is:

$ cat ~/tmp/ats/idiomaticca/main.dats
#include "share/atspre_staload.hats"

fun switch_case (c: char): int =
  let
    var ret: int
    val () = case c of
      | _ when c = '1' || c = '2' || c = '3' => ret := 1
      | ' ' => ret := 2
      | _   => ret := 3
  in
    ret
  end

implement main () =
  let
    var num: int
    var space: int
    var other: int
    val () = num := switch_case('1')
    val () = space := switch_case(' ')
    val () = other := switch_case('Q')
  in
    num * 100 + space * 10 + other - 123
  end
$ stack run dumpats ~/tmp/ats/idiomaticca/main.dats
ATS {unATS = [
  Include "\"share/atspre_staload.hats\"",
  Func {pos = AlexPn 38 3 1, _fun = Fun {_preF = PreF {fname = Unqualified "switch_case", sig = Just "", preUniversals = [], universals = [], args = Just [Arg (Both "c" (Named (Unqualified "char")))], returnType = Just (Named (Unqualified "int")), termetric = Nothing, _expression = Just (Let (AlexPn 73 4 3) (ATS {unATS = [
    Var {varT = Just (Named (Unqualified "int")), varPat = UniversalPattern (AlexPn 85 5 9) "ret" [] Nothing, _varExpr1 = Nothing, _varExpr2 = Nothing},
    Val {add = None, valT = Nothing, valPat = Just (PLiteral (VoidLiteral (AlexPn 102 6 9))), _valExpression = Just (
      Case {posE = AlexPn 114 6 21, kind = None,
        val = NamedVal (Unqualified "c"),
        _arms = [
          (PName (Unqualified "_") [],Plain (AlexPn 210 9 13),Binary Mutate (NamedVal (Unqualified "ret")) (IntLit 3)),
          (PLiteral (CharLit ' '),Plain (AlexPn 186 8 13),Binary Mutate (NamedVal (Unqualified "ret")) (IntLit 2)),
          (Guarded
            (AlexPn 127 7 11)
            (Binary Equal (NamedVal (Unqualified "c")) (Binary LogicalOr (CharLit '1') (Binary Equal (NamedVal (Unqualified "c")) (Binary LogicalOr (CharLit '2') (Binary Equal (NamedVal (Unqualified "c")) (CharLit '3'))))))
            (PName (Unqualified "_") []),
            Plain (AlexPn 162 7 46),
            Binary Mutate (NamedVal (Unqualified "ret")) (IntLit 1)
          )]
      })}
  ]}) (Just (NamedVal (Unqualified "ret"))))}}},
  Impl {implArgs = Nothing, _impl = Implement {pos = AlexPn 260 14 19, preUniversalsI = [], implicits = [], universalsI = [], nameI = Unqualified "main", iArgs = Just [], _iExpression = Right (Let (AlexPn 264 15 3) (ATS {unATS = [Var {varT = Just (Named (Unqualified "int")), varPat = UniversalPattern (AlexPn 276 16 9) "num" [] Nothing, _varExpr1 = Nothing, _varExpr2 = Nothing},Var {varT = Just (Named (Unqualified "int")), varPat = UniversalPattern (AlexPn 293 17 9) "space" [] Nothing, _varExpr1 = Nothing, _varExpr2 = Nothing},Var {varT = Just (Named (Unqualified "int")), varPat = UniversalPattern (AlexPn 312 18 9) "other" [] Nothing, _varExpr1 = Nothing, _varExpr2 = Nothing},Val {add = None, valT = Nothing, valPat = Just (PLiteral (VoidLiteral (AlexPn 331 19 9))), _valExpression = Just (Binary Mutate (NamedVal (Unqualified "num")) (Call {callName = Unqualified "switch_case", callImplicits = [], callUniversals = [], callProofs = Nothing, callArgs = [CharLit '1']}))},Val {add = None, valT = Nothing, valPat = Just (PLiteral (VoidLiteral (AlexPn 368 20 9))), _valExpression = Just (Binary Mutate (NamedVal (Unqualified "space")) (Call {callName = Unqualified "switch_case", callImplicits = [], callUniversals = [], callProofs = Nothing, callArgs = [CharLit ' ']}))},Val {add = None, valT = Nothing, valPat = Just (PLiteral (VoidLiteral (AlexPn 407 21 9))), _valExpression = Just (Binary Mutate (NamedVal (Unqualified "other")) (Call {callName = Unqualified "switch_case", callImplicits = [], callUniversals = [], callProofs = Nothing, callArgs = [CharLit 'Q']}))}]}) (Just (Binary Mult (NamedVal (Unqualified "num")) (BinList {_op = Add, _exprs = [IntLit 100,Binary Mult (NamedVal (Unqualified "space")) (BinList {_op = Add, _exprs = [IntLit 10,Binary Sub (NamedVal (Unqualified "other")) (IntLit 123)]})]}))))}}
]}