fakenickels / fakenickels-blog

fakenickels - Hi, I'm fakenickels
https://blog.fakenickels.dev
5 stars 1 forks source link

Reason/OCaml AST nodes cheat sheet #13

Open fakenickels opened 3 years ago

fakenickels commented 3 years ago

I think that for brevity reasons the AST nodes from OCaml parsetree and Cia are a bit confusing and a bit unintelligible at first. I mean, what does Pexp_apply, Pexp_construct + Pexp_tuple, Pexp_poly even mean? And a list [1, 2, 3] will be represented as a bunch Pexp_construct and Pexp_tuple what? So what I missed at first when I started writing my own PPXs or other AST consuming projects was some sort of cheat sheet to help aid this pain. ppx_tools/dumpast kinda helps and https://astexplorer.net/ too but their output doesn't map 1:1 to the actual AST nodes you end up consuming in the code. Also I wished I knew about @opam/ppx_tools_versioned earlier and the sweet ppx_metaquot.

I plan on to keep on updating this post

expressions; everything is an expression

let value; let a = 12

let function; let a = () => 12;

function labels

function body

function call or apply; a(1, 2, 3)

function call with labeled params; a(~b=12, ~c=2);

jsx

switch or pattern matching; switch(a) { | true => false | false => true}

pattern matching branches

records; {a: 1, b: 2, c: 3}

modules

functors

array; let a = [|1, 2, 3|]

list; let a= [1, 2, 3]

in

let favNumbers = [1, 2, 3]

out

{
 pexp_desc: Pexp_construct(_dontCare, Some(items)),
 pexp_loc: dontCare,
 pexp_attributes: only_care_if_you_want_to_read_annotations
}: Parsetree.expression

items: Parsetree.expression

suggested way to consume the items as a list of them:

let rec itemsToList = (items: Parsetree.expression) => {
  switch(items) {
    | {
      pexp_desc: Pexp_tuple([prop, construct])  
    } => 
      [prop, ...mapItems(construct)]
    | {
      pexp_desc: Pexp_construct(_, Some(items))  
    } => 
      mapItems(items)
    | _ => []
  }
}; 

types

record types; type r = {a: int, b: int, c: int};

module types