예제 #1
0
def trans_ty(tname):
  _tname = util.sanitize_ty(tname.strip())
  array_regex = r"([^ \[\]]+)((\[\])+)"
  m = re.match(array_regex, _tname)

  global _ty
  r_ty = _tname
  # to avoid primitive types that Sketch doesn't support
  if _tname == C.J.z: r_ty = C.SK.z
  elif _tname in [C.J.b, C.J.s, C.J.j]: r_ty = C.J.i
  # unboxing primitive Classes, e.g., Character -> char
  elif _tname in C.autoboxing: r_ty = util.unboxing(_tname)
  # TODO: parameterize len?
  elif _tname in [C.J.c+"[]"]: r_ty = u"{}[51]".format(C.J.c)
  elif _tname in [C.J.B, C.J.S, C.J.J, C.J.I]: r_ty = C.J.i
  # array bounds
  elif m:
    r_ty = trans_ty(m.group(1)) + \
        "[{}]".format(len(methods())) * len(re.findall(r"\[\]", m.group(2)))
  # use memoized type conversion
  elif _tname in _ty: r_ty = _ty[_tname]
  # convert Java collections into an appropriate struct name
  # Map<K,V> / List<T> / ... -> Map_K_V / List_T / ...
  elif util.is_collection(_tname):
    r_ty = '_'.join(util.of_collection(_tname))
    logging.debug("{} => {}".format(_tname, r_ty))
    _ty[_tname] = r_ty

  return r_ty
예제 #2
0
def trans_ty(tname):
  _tname = util.sanitize_ty(tname.strip())
  array_regex = r"([^ \[\]]+)((\[\])+)"
  m = re.match(array_regex, _tname)

  global _ty
  r_ty = _tname
  # to avoid primitive types that Sketch doesn't support
  if _tname == C.J.z: r_ty = C.SK.z
  elif _tname in [C.J.b, C.J.s, C.J.j]: r_ty = C.J.i
  # unboxing primitive Classes, e.g., Character -> char
  elif _tname in C.autoboxing: r_ty = util.unboxing(_tname)
  # TODO: parameterize len?
  elif _tname in [C.J.c+"[]"]: r_ty = u"{}[51]".format(C.J.c)
  elif _tname in [C.J.B, C.J.S, C.J.J, C.J.I]: r_ty = C.J.i
  # array bounds
  elif m:
    r_ty = trans_ty(m.group(1)) + \
        "[{}]".format(len(methods())) * len(re.findall(r"\[\]", m.group(2)))
  # use memoized type conversion
  elif _tname in _ty: r_ty = _ty[_tname]
  # convert Java collections into an appropriate struct name
  # Map<K,V> / List<T> / ... -> Map_K_V / List_T / ...
  elif util.is_collection(_tname):
    r_ty = '_'.join(util.of_collection(_tname))
    logging.debug("{} => {}".format(_tname, r_ty))
    _ty[_tname] = r_ty

  return r_ty
예제 #3
0
def trans_s(mtd, s):
  curried_e = partial(trans_e, mtd)
  curried_s = partial(trans_s, mtd)
  buf = cStringIO.StringIO()

  if s.kind == C.S.IF:
    e = curried_e(s.e)
    t = '\n'.join(map(curried_s, s.t))
    f = '\n'.join(map(curried_s, s.f))
    buf.write("if (" + e + ") {\n" + t + "\n}")
    if f: buf.write("\nelse {\n" + f + "\n}")

  elif s.kind == C.S.WHILE:
    e = curried_e(s.e)
    b = '\n'.join(map(curried_s, s.b))
    buf.write("while (" + e + ") {\n" + b + "\n}")

  elif s.kind == C.S.REPEAT:
    e = curried_e(s.e)
    b = '\n'.join(map(curried_s, s.b))
    if e == "??": buf.write("minrepeat {\n" + b + "\n}")
    else: buf.write("repeat (" + e + ") {\n" + b + "\n}")

  elif s.kind == C.S.MINREPEAT:
    b = '\n'.join(map(curried_s, s.b))
    buf.write("minrepeat {\n" + b + "\n}")

  elif s.kind == C.S.FOR:
    # assume "for" is used for List<T> and LinkedList<T> only
    col = mtd.vars[s.init.id]
    if not util.is_collection(col) or \
        util.of_collection(col)[0] not in [C.J.LST, C.J.LNK]:
      raise Exception("not iterable type", col)

    # if this is about observers, let sketch choose iteration direction
    is_obs = hasattr(class_lookup(util.of_collection(col)[1]), "obs")
    s_init = curried_e(s.init)

    if is_obs: init = "{{| 0 | {}.idx - 1 |}}".format(s_init)
    else: init = '0'
    buf.write("  int idx = {};".format(init))

    s_i_typ = trans_ty(s.i.ty)
    buf.write("""
      while (0 <= idx && idx < S && {s_init}.elts[idx] != null) {{
        {s_i_typ} {s.i.id} = {s_init}.elts[idx];
    """.format(**locals()))

    buf.write('\n'.join(map(curried_s, s.b)))

    if is_obs: upd = "{| idx (+ | -) 1 |}"
    else: upd = "idx + 1"
    buf.write("""
        idx = {};
      }}
    """.format(upd))

  elif s.kind == C.S.TRY:
    # NOTE: no idea how to handle catch blocks
    # at this point, just walk through try/finally blocks
    buf.write('\n'.join(map(curried_s, s.b + s.fs)))

  else: buf.write(s.__str__(curried_e))
  return buf.getvalue()
예제 #4
0
def col_to_struct(cls):
  buf = cStringIO.StringIO()
  cname = cls.name
  sname = trans_ty(cname)
  global _collections
  if sname in _collections:
    logging.debug("collection: {} (duplicated)".format(cname))
    return u''
  else:
    _collections.add(sname)
    logging.debug("collection: " + cname)

  buf.write("struct ${sname} {\n  int idx;\n")

  if C.J.MAP in cname:
    _, k, v = util.of_collection(cname)
    k = trans_ty(k)
    v = trans_ty(v)

    # Map<K,V> -> struct Map_K_V { int idx; K[S] key; V[S] val; }
    buf.write("  ${k}[S] key;\n  ${v}[S] val;\n}\n")

    # Map<K,V>.containsKey -> containsKey_Map_K_V
    buf.write("""
      bit {} (${{sname}} map, ${{k}} k) {{
        int i;
        for (i = 0; map.val[i] != null && i < S; i++) {{
          if (map.key[i] == k) return 1;
        }}
        return 0;
      }}
    """.format(trans_mname(cname, u"containsKey", [k])))

    # Map<K,V>.get -> get_Map_K_V
    buf.write("""
      ${{v}} {} (${{sname}} map, ${{k}} k) {{
        int i;
        for (i = 0; map.val[i] != null && i < S; i++) {{
          if (map.key[i] == k) return map.val[i];
        }}
        return null;
      }}
    """.format(trans_mname(cname, u"get", [k])))

    # Map<K,V>.put -> put_Map_K_V
    buf.write("""
      void {} (${{sname}} map, ${{k}} k, ${{v}} v) {{
        map.key[map.idx] = k;
        map.val[map.idx] = v;
        map.idx = (map.idx + 1) % S;
      }}
    """.format(trans_mname(cname, u"put", [k, v])))

    # Map<K,V>.clear -> clear_Map_K_V
    if util.is_class_name(k): default_k = "null"
    else: default_k = "0"
    buf.write("""
      void {} (${{sname}} map) {{
        map.idx = 0;
        for (int i = 0; i < S; i++) {{
          map.key[i] = {};
          map.val[i] = null;
        }}
      }}
    """.format(trans_mname(cname, u"clear", []), default_k))

  else:
    collection, t = util.of_collection(cname)
    t = trans_ty(t)

    if C.J.QUE in collection: buf.write("  int head;\n")
    # Collection<T> -> struct Collection_T { int idx; T[S] elts; }
    buf.write("  ${t}[S] elts;\n}\n")

    if C.J.STK in collection:
      # Stack<T>.peek -> peek_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk) {{
          if (stk.idx == 0) return null;
          ${{t}} top = stk.elts[stk.idx - 1];
          return top;
        }}
      """.format(trans_mname(cname, u"peek", [])))

      # Stack<T>.push -> push_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk, ${{t}} elt) {{
          stk.elts[stk.idx] = elt;
          stk.idx = (stk.idx + 1) % S;
          return elt;
        }}
      """.format(trans_mname(cname, u"push", [t])))

      # Stack<T>.pop -> pop_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk) {{
          if (stk.idx == 0) return null;
          stk.idx = stk.idx - 1;
          ${{t}} top = stk.elts[stk.idx];
          stk.elts[stk.idx] = null;
          return top;
        }}
      """.format(trans_mname(cname, u"pop", [])))

    elif C.J.QUE in collection:
      # Queue<T>.add -> add_Queue_T
      buf.write("""
        bit {} (${{sname}} que, ${{t}} elt) {{
          que.elts[que.idx] = elt;
          que.idx = (que.idx + 1) % S;
          return true;
        }}
      """.format(trans_mname(cname, u"add", [t])))

      # Queue<T>.remove -> remove_Queue_T
      buf.write("""
        ${{t}} {} (${{sname}} que) {{
          if (que.head == que.idx) return null;
          ${{t}} top = que.elts[que.head];
          que.elts[que.head] = null;
          que.head = (que.head + 1) % S;
          return top;
        }}
      """.format(trans_mname(cname, u"remove", [])))

      # Queue<T>.isEmpty -> isEmpty_Queue_T
      buf.write("""
        bit {} (${{sname}} que) {{
          return que.head == que.idx;
        }}
      """.format(trans_mname(cname, u"isEmpty", [])))

    elif C.J.LST in collection:
      # List<T>.add -> add_List_T
      buf.write("""
        bit {} (${{sname}} lst, ${{t}} elt) {{
          lst.elts[lst.idx] = elt;
          lst.idx = (lst.idx + 1) % S;
          return true;
        }}
      """.format(trans_mname(cname, u"add", [t])))

      # List<T>.remove(T) -> remove_List_T_T
      buf.write("""
        bit {} (${{sname}} lst, ${{t}} elt) {{
          int i;
          for (i = 0; lst.elts[i] != null && i < S; i++) {{
            if (lst.elts[i] == elt) {{
              lst.elts[i] = null;
              int j;
              for (j = i + 1; lst.elts[j] != null && j < lst.idx; j++) {{
                lst.elts[j-1] = lst.elts[j];
              }}
              lst.idx = (lst.idx - 1) % S;
              return true;
            }}
          }}
          return false;
        }}
      """.format(trans_mname(cname, u"remove", [t])))

      # List<T>.remove(int) -> remove_List_T_int
      buf.write("""
        ${{t}} {} (${{sname}} lst, int index) {{
          ${{t}} res = null;
          if (0 <= index && index < lst.idx) {{
            res = lst.elts[index];
            lst.elts[index] = null;
            int i;
            for (i = index + 1; lst.elts[i] != null && i < lst.idx; i++) {{
              lst.elts[i-1] = lst.elts[i];
            }}
            lst.idx = (lst.idx - 1) % S;
          }}
          return res;
        }}
      """.format(trans_mname(cname, u"remove", [C.J.i])))

      # List<T>.get -> get_List_T
      buf.write("""
        ${{t}} {} (${{sname}} lst, int index) {{
          ${{t}} res = null;
          if (0 <= index && index < lst.idx) {{
            res = lst.elts[index];
          }}
          return res;
        }}
      """.format(trans_mname(cname, u"get", [C.J.i])))

      # List<T>.isEmpty -> isEmpty_List_T
      buf.write("""
        bit {} (${{sname}} lst) {{
          return lst.idx == 0;
        }}
      """.format(trans_mname(cname, u"isEmpty", [])))

  return T(buf.getvalue()).safe_substitute(locals())
예제 #5
0
def trans_s(mtd, s):
  curried_e = partial(trans_e, mtd)
  curried_s = partial(trans_s, mtd)
  buf = cStringIO.StringIO()

  if s.kind == C.S.IF:
    e = curried_e(s.e)
    t = '\n'.join(map(curried_s, s.t))
    f = '\n'.join(map(curried_s, s.f))
    buf.write("if (" + e + ") {\n" + t + "\n}")
    if f: buf.write("\nelse {\n" + f + "\n}")

  elif s.kind == C.S.WHILE:
    e = curried_e(s.e)
    b = '\n'.join(map(curried_s, s.b))
    buf.write("while (" + e + ") {\n" + b + "\n}")

  elif s.kind == C.S.REPEAT:
    e = curried_e(s.e)
    b = '\n'.join(map(curried_s, s.b))
    if e == "??": buf.write("minrepeat {\n" + b + "\n}")
    else: buf.write("repeat (" + e + ") {\n" + b + "\n}")

  elif s.kind == C.S.MINREPEAT:
    b = '\n'.join(map(curried_s, s.b))
    buf.write("minrepeat {\n" + b + "\n}")

  elif s.kind == C.S.FOR:
    # assume "for" is used for List<T> and LinkedList<T> only
    col = mtd.vars[s.init.id]
    if not util.is_collection(col) or \
        util.of_collection(col)[0] not in [C.J.LST, C.J.LNK]:
      raise Exception("not iterable type", col)

    # if this is about observers, let sketch choose iteration direction
    is_obs = hasattr(class_lookup(util.of_collection(col)[1]), "obs")
    s_init = curried_e(s.init)

    if is_obs: init = "{{| 0 | {}.idx - 1 |}}".format(s_init)
    else: init = '0'
    buf.write("  int idx = {};".format(init))

    s_i_typ = trans_ty(s.i.ty)
    buf.write("""
      while (0 <= idx && idx < S && {s_init}.elts[idx] != null) {{
        {s_i_typ} {s.i.id} = {s_init}.elts[idx];
    """.format(**locals()))

    buf.write('\n'.join(map(curried_s, s.b)))

    if is_obs: upd = "{| idx (+ | -) 1 |}"
    else: upd = "idx + 1"
    buf.write("""
        idx = {};
      }}
    """.format(upd))

  elif s.kind == C.S.TRY:
    # NOTE: no idea how to handle catch blocks
    # at this point, just walk through try/finally blocks
    buf.write('\n'.join(map(curried_s, s.b + s.fs)))

  else: buf.write(s.__str__(curried_e))
  return buf.getvalue()
예제 #6
0
def col_to_struct(cls):
  buf = cStringIO.StringIO()
  cname = cls.name
  sname = trans_ty(cname)
  global _collections
  if sname in _collections:
    logging.debug("collection: {} (duplicated)".format(cname))
    return u''
  else:
    _collections.add(sname)
    logging.debug("collection: " + cname)

  buf.write("struct ${sname} {\n  int idx;\n")

  if C.J.MAP in cname:
    _, k, v = util.of_collection(cname)
    k = trans_ty(k)
    v = trans_ty(v)

    # Map<K,V> -> struct Map_K_V { int idx; K[S] key; V[S] val; }
    buf.write("  ${k}[S] key;\n  ${v}[S] val;\n}\n")

    # Map<K,V>.containsKey -> containsKey_Map_K_V
    buf.write("""
      bit {} (${{sname}} map, ${{k}} k) {{
        int i;
        for (i = 0; map.val[i] != null && i < S; i++) {{
          if (map.key[i] == k) return 1;
        }}
        return 0;
      }}
    """.format(trans_mname(cname, u"containsKey", [k])))

    # Map<K,V>.get -> get_Map_K_V
    buf.write("""
      ${{v}} {} (${{sname}} map, ${{k}} k) {{
        int i;
        for (i = 0; map.val[i] != null && i < S; i++) {{
          if (map.key[i] == k) return map.val[i];
        }}
        return null;
      }}
    """.format(trans_mname(cname, u"get", [k])))

    # Map<K,V>.put -> put_Map_K_V
    buf.write("""
      void {} (${{sname}} map, ${{k}} k, ${{v}} v) {{
        map.key[map.idx] = k;
        map.val[map.idx] = v;
        map.idx = (map.idx + 1) % S;
      }}
    """.format(trans_mname(cname, u"put", [k, v])))

    # Map<K,V>.clear -> clear_Map_K_V
    if util.is_class_name(k): default_k = "null"
    else: default_k = "0"
    buf.write("""
      void {} (${{sname}} map) {{
        map.idx = 0;
        for (int i = 0; i < S; i++) {{
          map.key[i] = {};
          map.val[i] = null;
        }}
      }}
    """.format(trans_mname(cname, u"clear", []), default_k))

  else:
    collection, t = util.of_collection(cname)
    t = trans_ty(t)

    if C.J.QUE in collection: buf.write("  int head;\n")
    # Collection<T> -> struct Collection_T { int idx; T[S] elts; }
    buf.write("  ${t}[S] elts;\n}\n")

    if C.J.STK in collection:
      # Stack<T>.peek -> peek_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk) {{
          if (stk.idx == 0) return null;
          ${{t}} top = stk.elts[stk.idx - 1];
          return top;
        }}
      """.format(trans_mname(cname, u"peek", [])))

      # Stack<T>.push -> push_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk, ${{t}} elt) {{
          stk.elts[stk.idx] = elt;
          stk.idx = (stk.idx + 1) % S;
          return elt;
        }}
      """.format(trans_mname(cname, u"push", [t])))

      # Stack<T>.pop -> pop_Stack_T
      buf.write("""
        ${{t}} {} (${{sname}} stk) {{
          if (stk.idx == 0) return null;
          stk.idx = stk.idx - 1;
          ${{t}} top = stk.elts[stk.idx];
          stk.elts[stk.idx] = null;
          return top;
        }}
      """.format(trans_mname(cname, u"pop", [])))

    elif C.J.QUE in collection:
      # Queue<T>.add -> add_Queue_T
      buf.write("""
        bit {} (${{sname}} que, ${{t}} elt) {{
          que.elts[que.idx] = elt;
          que.idx = (que.idx + 1) % S;
          return true;
        }}
      """.format(trans_mname(cname, u"add", [t])))

      # Queue<T>.remove -> remove_Queue_T
      buf.write("""
        ${{t}} {} (${{sname}} que) {{
          if (que.head == que.idx) return null;
          ${{t}} top = que.elts[que.head];
          que.elts[que.head] = null;
          que.head = (que.head + 1) % S;
          return top;
        }}
      """.format(trans_mname(cname, u"remove", [])))

      # Queue<T>.isEmpty -> isEmpty_Queue_T
      buf.write("""
        bit {} (${{sname}} que) {{
          return que.head == que.idx;
        }}
      """.format(trans_mname(cname, u"isEmpty", [])))

    elif C.J.LST in collection:
      # List<T>.add -> add_List_T
      buf.write("""
        bit {} (${{sname}} lst, ${{t}} elt) {{
          lst.elts[lst.idx] = elt;
          lst.idx = (lst.idx + 1) % S;
          return true;
        }}
      """.format(trans_mname(cname, u"add", [t])))

      # List<T>.remove(T) -> remove_List_T_T
      buf.write("""
        bit {} (${{sname}} lst, ${{t}} elt) {{
          int i;
          for (i = 0; lst.elts[i] != null && i < S; i++) {{
            if (lst.elts[i] == elt) {{
              lst.elts[i] = null;
              int j;
              for (j = i + 1; lst.elts[j] != null && j < lst.idx; j++) {{
                lst.elts[j-1] = lst.elts[j];
              }}
              lst.idx = (lst.idx - 1) % S;
              return true;
            }}
          }}
          return false;
        }}
      """.format(trans_mname(cname, u"remove", [t])))

      # List<T>.remove(int) -> remove_List_T_int
      buf.write("""
        ${{t}} {} (${{sname}} lst, int index) {{
          ${{t}} res = null;
          if (0 <= index && index < lst.idx) {{
            res = lst.elts[index];
            lst.elts[index] = null;
            int i;
            for (i = index + 1; lst.elts[i] != null && i < lst.idx; i++) {{
              lst.elts[i-1] = lst.elts[i];
            }}
            lst.idx = (lst.idx - 1) % S;
          }}
          return res;
        }}
      """.format(trans_mname(cname, u"remove", [C.J.i])))

      # List<T>.get -> get_List_T
      buf.write("""
        ${{t}} {} (${{sname}} lst, int index) {{
          ${{t}} res = null;
          if (0 <= index && index < lst.idx) {{
            res = lst.elts[index];
          }}
          return res;
        }}
      """.format(trans_mname(cname, u"get", [C.J.i])))

      # List<T>.isEmpty -> isEmpty_List_T
      buf.write("""
        bit {} (${{sname}} lst) {{
          return lst.idx == 0;
        }}
      """.format(trans_mname(cname, u"isEmpty", [])))

  return T(buf.getvalue()).safe_substitute(locals())