5.16.5.19. Procedure Call

Start data section to src/flx_parse.mly[24 /33 ] Next Prev First Last
  1716: compound:
  1717:   | LBRACE statement_aster RBRACE  { rstoken $1 $3, $2 }
  1718: 
End data section to src/flx_parse.mly[24]
A procedure call looks like a function application, followed by a semicolon:
  p a;
  f1 a1 a2 a3;
are valid procedure calls. Note in the second example, f1 and f1 a1 are functions, whilst the function call f1 a1 a2 must return a procedure which accepts a3.

There is a special case: a single name followed by a semi-colon is considered a call of the designated procedure passing the unit argument, so that the following are equivalent:

  print_eol ();
  print_eol;
Note that there is no ambiguity with passing procedures as arguments: the name always represents a procedure closure in an expression context, never a call.

Note again that this special case only applies to names, not general expressions, but the name doesn't have to be a procedure constant: it could be a variable name.

  val eol = print_eol;
  eol; // means eol()
  sin x; // error: function application
  (sin x); // still an error!

Start data section to src/flx_parse.mly[25 /33 ] Next Prev First Last
  1719: call:
  1720:   | expr SEMI
  1721:     {
  1722:       let sr =
  1723:         let sr1 = src_of_expr $1 in
  1724:         rsrange sr1 (slift $2)
  1725:      in
  1726:       match $1 with
  1727:       | `AST_apply (_,(proc, arg)) ->
  1728:         `AST_call (sr, proc, arg)
  1729: 
  1730:       | proc ->
  1731:        let u = `AST_tuple (slift $2, []) in
  1732:        `AST_call (sr, proc, u)
  1733:     }
  1734: 
  1735:   | CALL expr SEMI
  1736:     {
  1737:       let sr = rstoken $1 $3 in
  1738:       match $2 with
  1739:       | `AST_apply (sr,(proc, arg)) ->
  1740:         `AST_call (sr, proc, arg)
  1741: 
  1742:       | proc ->
  1743:         let u = `AST_tuple (slift $3, []) in
  1744:        `AST_call (rstoken $1 $3, proc, u)
  1745:     }
  1746: 
  1747:   | JUMP expr SEMI
  1748:     {
  1749:       let sr = rstoken $1 $3 in
  1750:       match $2 with
  1751:       | `AST_apply (sr,(proc, arg)) ->
  1752:         `AST_jump (sr, proc, arg)
  1753: 
  1754:       | proc ->
  1755:         let u = `AST_tuple (slift $3, []) in
  1756:        `AST_call (sr, proc, u)
  1757:     }
  1758: 
  1759:   | LOOP expr SEMI {
  1760:     let sr = rstoken $1 $3 in
  1761:     let u = `AST_tuple (slift $3, []) in
  1762:     match $2 with
  1763:     | `AST_apply (_,(`AST_name (_,name,[]), arg)) ->
  1764:       `AST_loop (sr, name, arg)
  1765: 
  1766:     | `AST_name (s,name,[]) ->
  1767:       `AST_loop (sr, name, u)
  1768: 
  1769:     | _ -> failwith "Loop requires unqualified name"
  1770:   }
  1771: 
  1772: 
  1773: assignop:
  1774:   | EQUAL           { $1,"_set" }
  1775:   | COLONEQUAL      { $1,"_init" }
  1776: 
  1777: rmwop:
  1778:   | PLUSEQUAL       { $1,"pluseq" }
  1779:   | MINUSEQUAL      { $1,"minuseq" }
  1780:   | STAREQUAL       { $1,"muleq" }
  1781:   | SLASHEQUAL      { $1,"diveq" }
  1782:   | PERCENTEQUAL    { $1,"modeq" }
  1783:   | LEFTSHIFTEQUAL  { $1,"leftshifteq" }
  1784:   | RIGHTSHIFTEQUAL { $1,"rightshifteq" }
  1785:   | CARETEQUAL      { $1,"bxoreq" }
  1786:   | VBAREQUAL       { $1,"boreq" }
  1787:   | AMPEREQUAL      { $1,"bandeq" }
  1788:   | TILDEEQUAL      { $1,"tildeeq" }
  1789: 
  1790: swapop:
  1791:   | LEFTRIGHTARROW  { $1,"_swap" }
  1792: 
  1793: incrop:
  1794:   | PLUSPLUS        { $1,"incr" }
  1795:   | MINUSMINUS      { $1, "decr" }
  1796: 
  1797: lelement:
  1798:   | VAL NAME { `Val  (rstoken $1 (fst $2), snd $2) }
  1799:   | VAR NAME { `Var  (rstoken $1 (fst $2), snd $2) }
  1800:   | NAME     { `Name (slift (fst $1), snd $1) }
  1801:   | UNDERSCORE { `Skip (rstoken $1 $1) }
  1802:   | LPAR lexprs RPAR { `List $2 }
  1803: 
  1804: tlelement:
  1805:   | lelement COLON factor { $1,Some (typecode_of_expr $3) }
  1806:   | lelement { $1,None }
  1807: 
  1808: lexprs:
  1809:   | tlelement COMMA lexprs { $1 :: $3 }
  1810:   | tlelement { [$1] }
  1811: 
  1812: lexpr:
  1813:   | lexprs
  1814:     {
  1815:       match $1 with
  1816:       | [lv,t] -> lv,t
  1817:       | _ -> `List $1, None
  1818:     }
  1819: 
  1820: assignment:
  1821:   | VAR NAME LEFTARROW NEW expr SEMI
  1822:     {
  1823:       let sr = rstoken $1 $6 in
  1824:       let name = snd $2 in
  1825:       let f,a= match $5 with
  1826:       | `AST_apply(_,(f,a)) -> f,a
  1827:       | f -> f,`AST_tuple (sr,[])
  1828:       in
  1829:       `AST_apply_ctor (sr,name,f,a)
  1830:     }
  1831: 
  1832:   | expr LEFTARROW expr SEMI
  1833:     {
  1834:       let sr = rsrange (src_of_expr $1) (slift $4) in
  1835:       let lsym = $1 in
  1836:       match $3 with
  1837:       | `AST_apply (sr2,(f,a)) ->
  1838:         begin match a with
  1839:         | `AST_tuple (sr3,ls) ->
  1840:           `AST_call (sr,f,`AST_tuple (sr3,lsym::ls))
  1841:         | _ ->
  1842:           `AST_call (sr,f,`AST_tuple (sr2,[lsym;a]))
  1843:         end
  1844:       | _ as f ->
  1845:         `AST_call (sr,f,lsym)
  1846:     }
  1847: 
  1848:   | expr swapop expr SEMI
  1849:     {
  1850:       let srop,sname = $2 in
  1851:       let sr = rsrange (src_of_expr $1) (slift $4) in
  1852:       call2 sname sr srop $1 $3
  1853:     }
  1854: 
  1855:   | DEF lexpr EQUAL expr SEMI
  1856:     {
  1857:       let sr = rstoken $1 $5 in
  1858:       `AST_assign (sr,"_set",$2, $4)
  1859:     }
  1860: 
  1861: 
  1862:   | expr assignop expr SEMI
  1863:     {
  1864:       let srop,sname = $2 in
  1865:       let sr = rsrange (src_of_expr $1) (slift $4) in
  1866:       `AST_assign (sr,sname,(`Expr (sr,$1),None), $3)
  1867:     }
  1868: 
  1869:   | expr rmwop expr SEMI
  1870:     {
  1871:       let srop,sname = $2 in
  1872:       let sr = rsrange (src_of_expr $1) (slift $4) in
  1873:       `AST_assign (sr,sname,(`Expr (sr,$1),None), $3)
  1874:     }
  1875: 
  1876:   | expr incrop SEMI
  1877:     {
  1878:       let srop,sname = $2 in
  1879:       let sr = rsrange (src_of_expr $1) (slift $3) in
  1880:       call1 ("post_" ^ sname) sr srop $1
  1881:     }
  1882:   | incrop expr SEMI
  1883:     {
  1884:       let srop,sname = $1 in
  1885:       let sr = rsrange (slift srop) (slift $3) in
  1886:       call1 ("pre_" ^ sname) sr srop $2
  1887:     }
  1888: 
  1889: 
End data section to src/flx_parse.mly[25]
Note that a block is an anonymous procedure defintion together with a call to that procedure with the unit argument.