H2JVM – 用于编写 JVM 字节码的 Haskell 库
H2JVM – A Haskell Library for Writing JVM Bytecode

原始链接: https://discourse.haskell.org/t/h2jvm-a-haskell-library-for-writing-jvm-bytecode/14182

审阅者针对 JVM 代码实现提出了以下改进建议: * **错误预防**:在生成标签时,应使用 `MonadFix` 配合 `mdo` 或 `rec`,以避免出现 `UnmarkedLabel` 错误。 * **性能优化**:将 `CodeState` 中的列表存储方式替换为 `DList`,以提升效率。 * **数据建模**:重构重复的 `IfCond` 数据类型,改为组合式的 `If` 类型(例如 `data If = If Cond Label`),以减少非规范化数据。同时使用 `COMPLETE` 编译指示以保持向后兼容性。 * **代码美化**:在 `Pretty` 实例中使用 `ViewPatterns` 来清理冗余代码,增强可读性。审阅者还建议使用分组组合子(如 `sep` 或 `fillSep`)代替硬编码的水平/垂直布局,从而实现更灵活、自适应的格式化效果。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 H2JVM – 用于编写 JVM 字节码的 Haskell 库 (haskell.org) 4 积分,由 rowbin 于 1 小时前发布 | 隐藏 | 过往 | 收藏 | 讨论 | 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Looks good and plainly written, I’ll bookmark it for next time I do something with the JVM

Browsed around and reviewed a little, have a few random suggestions


You can avoid the possibility of an UnmarkedLabel error using a MonadFix instance and rec or mdo

emitNewLabel = do
  label <- newLabel
  emit $ JVM.Label label
  pure label
mdo
  emit $ JVM.IfICmp (IfGt trueLabel)
  emit JVM.IConst0
  emit $ Goto endLabel
  emit JVM.IConst1
  trueLabel <- emitNewLabel
  emit JVM.IConst1
  endLabel <- emitNewLabel
  pure ()

I’d rather use rec to spell out the scope, but this case is better with mdo because the labels are used throughout


In CodeState instead of storing a list in reverse order you can use a DList Instruction

Code that uses IfCond is repetitive because it’s denormalised

data IfCond label = IfEq label | IfNe label | IfLt label | IfGe label | IfGt label | IfLe label

Instead you can factor:

  1x+1x+1x+1x+1x+1x
= (1+1+1+1+1+1)x
= 6x

data If label = If Cond label
data Cond = Eq | Ne | Lt | Ge | Gt | Le

Can also keep the current patterns with synonyms like pattern IfEq label = If Eq label and a {-# COMPLETE #-} pragma


In clauses of Pretty instances like this

pretty (InvokeSpecial c n d) =
  "invokespecial" <+> pretty c <> "." <> pretty n <> pretty d

I like to use ViewPatterns (or a synonym) so the shape of the output is less cluttered by calls to pretty, and it’s only called once if used more than once

pretty (InvokeSpecial (pretty -> c) (pretty -> n) (pretty -> d)) =
  "invokespecial" <+> c <> "." <> n <> d

I dunno how “pretty” you actually want for the pretty-printing to be, but I find that Pretty instances in general tend to overuse the explicit non-breaking horizontal (hcat, hsep, <>, <+>) and vertical (vcat, vsep) layouts without enough grouping, and should rather use the grouped combinators that allow breaks between all (cat, sep, surround softline', surround softline) or between any (fillCat, fillSep)

联系我们 contact @ memedata.com