1716: compound: 1717: | LBRACE statement_aster RBRACE { rstoken $1 $3, $2 } 1718:
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!
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: