{"id":16315596,"url":"https://github.com/andreasabel/java-adt","last_synced_at":"2025-10-26T16:10:01.580Z","repository":{"id":56844712,"uuid":"74970736","full_name":"andreasabel/java-adt","owner":"andreasabel","description":"A tool to create immutable algebraic data structures and visitors for Java (such as abstract syntax trees).","archived":false,"fork":false,"pushed_at":"2024-03-22T02:20:55.000Z","size":31,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-11T21:57:58.316Z","etag":null,"topics":["ast","java"],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/java-adt","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreasabel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-28T12:26:21.000Z","updated_at":"2024-05-04T20:51:20.000Z","dependencies_parsed_at":"2024-03-22T03:28:58.339Z","dependency_job_id":"b25d5e60-ad34-445b-aaef-567b22943715","html_url":"https://github.com/andreasabel/java-adt","commit_stats":{"total_commits":15,"total_committers":1,"mean_commits":15.0,"dds":0.0,"last_synced_commit":"e4905d4c4082718c27d04237888950afe0448f03"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasabel%2Fjava-adt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasabel%2Fjava-adt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasabel%2Fjava-adt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasabel%2Fjava-adt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreasabel","download_url":"https://codeload.github.com/andreasabel/java-adt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244703590,"owners_count":20496147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","java"],"created_at":"2024-10-10T21:57:57.118Z","updated_at":"2025-10-26T16:10:01.484Z","avatar_url":"https://github.com/andreasabel.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"java-adt\n========\n\nA tool to create immutable algebraic data structures and visitors for Java\n(such as abstract syntax trees).  The input syntax is similar to Haskell data types,\nand they will be compiled to Java class hierarchies.\n\nInstallation\n------------\n\nWith a running [Haskell installation](https://www.haskell.org/ghcup/), simply type into your shell\n```\ncabal install java-adt\n```\nand make sure your `.cabal/bin/` (or similar) is part of your system PATH.\n\nExample 1: Immutable linked lists with default visitor\n------------------------------------------------------\n\nInput: List.hs\n```haskell\ndata List A = Nil | Cons { head :: A, tail :: List A }\n```\nInvocation `java-adt List.hs` prints to standard output:\n```java\nabstract class List\u003cA\u003e {\n}\n\nclass Nil\u003cA\u003e extends List\u003cA\u003e {\n    public Nil () {\n    }\n}\n\nclass Cons\u003cA\u003e extends List\u003cA\u003e {\n    public A head;\n    public List\u003cA\u003e tail;\n    public Cons (A head, List\u003cA\u003e tail) {\n        this.head = head;\n        this.tail = tail;\n    }\n}\n```\nInvocation: `java-adt -o List.java List.hs` leaves output in `List.java`.\n\nInvocation: `java-adt -d List.hs` outputs same but with default visitor on standard output:\n```java\nabstract class List\u003cA\u003e {\n    public abstract \u003cR\u003e R accept (ListVisitor\u003cR,A\u003e v);\n}\n\nclass Nil\u003cA\u003e extends List\u003cA\u003e {\n    public Nil () {\n    }\n    public \u003cR\u003e R accept (ListVisitor\u003cR,A\u003e v) {\n        return v.visit (this);\n    }\n}\n\nclass Cons\u003cA\u003e extends List\u003cA\u003e {\n    public A head;\n    public List\u003cA\u003e tail;\n    public Cons (A head, List\u003cA\u003e tail) {\n        this.head = head;\n        this.tail = tail;\n    }\n    public \u003cR\u003e R accept (ListVisitor\u003cR,A\u003e v) {\n        return v.visit (this);\n    }\n}\n\ninterface ListVisitor\u003cR,A\u003e {\n    public R visit (Nil\u003cA\u003e l);\n    public R visit (Cons\u003cA\u003e l);\n}\n```\n\nExample 2: A simple AST with custom visitor\n-------------------------------------------\n\nInput file `Exp.hs`:  (Note the use of Haskell lists in `[Exp]`)\n```haskell\ndata Exp\n  = EInt  { i :: Integer }\n  | EAdd  { e1 :: Exp, e2 :: Exp }\n  | ECall { f :: String, es :: [Exp] }\n--visitor Integer EvalVisitor\n```\nInvocation `java-ast -o Exp.java Exp.hs` outputs into `Exp.java`:\n```java\nimport java.util.List;\n\nabstract class Exp {\n    public abstract Integer accept (EvalVisitor v);\n}\n\nclass EInt extends Exp {\n    public Integer i;\n    public EInt (Integer i) {\n        this.i = i;\n    }\n    public Integer accept (EvalVisitor v) {\n        return v.visit (this);\n    }\n}\n\nclass EAdd extends Exp {\n    public Exp e1;\n    public Exp e2;\n    public EAdd (Exp e1, Exp e2) {\n        this.e1 = e1;\n        this.e2 = e2;\n    }\n    public Integer accept (EvalVisitor v) {\n        return v.visit (this);\n    }\n}\n\nclass ECall extends Exp {\n    public String f;\n    public List\u003cExp\u003e es;\n    public ECall (String f, List\u003cExp\u003e es) {\n        this.f = f;\n        this.es = es;\n    }\n    public Integer accept (EvalVisitor v) {\n        return v.visit (this);\n    }\n}\n\ninterface EvalVisitor {\n    public Integer visit (EInt e);\n    public Integer visit (EAdd e);\n    public Integer visit (ECall e);\n}\n\n```\n\nInput file grammar\n------------------\n\nThe input file format is similar to Haskell data type declarations,\nwith the special comment `--visitor`.\n```\n  datadecl    ::= 'data' uppername '=' constructors visitors\n\n  constructor ::= uppername ['{' fieldlist '}']\n\n  fieldlist   ::= fieldlist ',' field\n                | field\n\n  field       ::= lowername '::' type\n\n  type        ::= type atom\n                | atom\n\n  atom        ::= name\n                | '[' type ']'\n                | '(' type ')'\n\n  visitor     ::= '--visitor' type name\n```\n\nLimitations\n-----------\n\n- Visitors do not support mutually recursive data types.\n- Record types with same constructor name as record name do not produce valid Java. E.g.\n  ```haskell\n  data R = R { f :: A }\n  ```\n  creates two classes with name `R` and subsequent Java compilation errors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreasabel%2Fjava-adt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreasabel%2Fjava-adt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreasabel%2Fjava-adt/lists"}