2000: compound: 2001: | LBRACE statement_aster RBRACE { rstoken $1 $3, $2 } 2002:
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!
2003: call: 2004: | expr SEMI 2005: { 2006: let sr = 2007: let sr1 = src_of_expr $1 in 2008: rsrange sr1 (slift $2) 2009: in 2010: match $1 with 2011: | `AST_apply (_,(proc, arg)) -> 2012: `AST_call (sr, proc, arg) 2013: 2014: | proc -> 2015: let u = `AST_tuple (slift $2, []) in 2016: `AST_call (sr, proc, u) 2017: } 2018: 2019: | CALL expr SEMI 2020: { 2021: let sr = rstoken $1 $3 in 2022: match $2 with 2023: | `AST_apply (sr,(proc, arg)) -> 2024: `AST_call (sr, proc, arg) 2025: 2026: | proc -> 2027: let u = `AST_tuple (slift $3, []) in 2028: `AST_call (rstoken $1 $3, proc, u) 2029: } 2030: 2031: | JUMP expr SEMI 2032: { 2033: let sr = rstoken $1 $3 in 2034: match $2 with 2035: | `AST_apply (sr,(proc, arg)) -> 2036: `AST_jump (sr, proc, arg) 2037: 2038: | proc -> 2039: let u = `AST_tuple (slift $3, []) in 2040: `AST_call (sr, proc, u) 2041: } 2042: 2043: | LOOP expr SEMI { 2044: let sr = rstoken $1 $3 in 2045: let u = `AST_tuple (slift $3, []) in 2046: match $2 with 2047: | `AST_apply (_,(`AST_name (_,name,[]), arg)) -> 2048: `AST_loop (sr, name, arg) 2049: 2050: | `AST_name (s,name,[]) -> 2051: `AST_loop (sr, name, u) 2052: 2053: | _ -> failwith "Loop requires unqualified name" 2054: } 2055: 2056: 2057: assignop: 2058: | EQUAL { $1,"_set" } 2059: | COLONEQUAL { $1,"_init" } 2060: 2061: rmwop: 2062: | PLUSEQUAL { $1,"pluseq" } 2063: | MINUSEQUAL { $1,"minuseq" } 2064: | STAREQUAL { $1,"muleq" } 2065: | SLASHEQUAL { $1,"diveq" } 2066: | PERCENTEQUAL { $1,"modeq" } 2067: | LEFTSHIFTEQUAL { $1,"leftshifteq" } 2068: | RIGHTSHIFTEQUAL { $1,"rightshifteq" } 2069: | CARETEQUAL { $1,"bxoreq" } 2070: | VBAREQUAL { $1,"boreq" } 2071: | AMPEREQUAL { $1,"bandeq" } 2072: | TILDEEQUAL { $1,"tildeeq" } 2073: 2074: swapop: 2075: | LEFTRIGHTARROW { $1,"_swap" } 2076: 2077: incrop: 2078: | PLUSPLUS { $1,"incr" } 2079: | MINUSMINUS { $1, "decr" } 2080: 2081: lelement: 2082: | VAL NAME { `Val (rstoken $1 (fst $2), snd $2) } 2083: | VAR NAME { `Var (rstoken $1 (fst $2), snd $2) } 2084: | NAME { `Name (slift (fst $1), snd $1) } 2085: | UNDERSCORE { `Skip (rstoken $1 $1) } 2086: | LPAR lexprs RPAR { `List $2 } 2087: 2088: tlelement: 2089: | lelement COLON factor { $1,Some (typecode_of_expr $3) } 2090: | lelement { $1,None } 2091: 2092: lexprs: 2093: | tlelement COMMA lexprs { $1 :: $3 } 2094: | tlelement { [$1] } 2095: 2096: lexpr: 2097: | lexprs 2098: { 2099: match $1 with 2100: | [lv,t] -> lv,t 2101: | _ -> `List $1, None 2102: } 2103: 2104: assignment: 2105: | VAR NAME LEFTARROW NEW expr SEMI 2106: { 2107: let sr = rstoken $1 $6 in 2108: let name = snd $2 in 2109: let f,a= match $5 with 2110: | `AST_apply(_,(f,a)) -> f,a 2111: | f -> f,`AST_tuple (sr,[]) 2112: in 2113: `AST_apply_ctor (sr,name,f,a) 2114: } 2115: 2116: | expr LEFTARROW expr SEMI 2117: { 2118: let sr = rsrange (src_of_expr $1) (slift $4) in 2119: let lsym = $1 in 2120: match $3 with 2121: | `AST_apply (sr2,(f,a)) -> 2122: begin match a with 2123: | `AST_tuple (sr3,ls) -> 2124: `AST_call (sr,f,`AST_tuple (sr3,lsym::ls)) 2125: | _ -> 2126: `AST_call (sr,f,`AST_tuple (sr2,[lsym;a])) 2127: end 2128: | _ as f -> 2129: `AST_call (sr,f,lsym) 2130: } 2131: 2132: | expr swapop expr SEMI 2133: { 2134: let srop,sname = $2 in 2135: let sr = rsrange (src_of_expr $1) (slift $4) in 2136: call2 sname sr srop $1 $3 2137: } 2138: 2139: | DEF lexpr EQUAL expr SEMI 2140: { 2141: let sr = rstoken $1 $5 in 2142: `AST_assign (sr,"_set",$2, $4) 2143: } 2144: 2145: 2146: | expr assignop expr SEMI 2147: { 2148: let srop,sname = $2 in 2149: let sr = rsrange (src_of_expr $1) (slift $4) in 2150: `AST_assign (sr,sname,(`Expr (sr,$1),None), $3) 2151: } 2152: 2153: | expr rmwop expr SEMI 2154: { 2155: let srop,sname = $2 in 2156: let sr = rsrange (src_of_expr $1) (slift $4) in 2157: `AST_assign (sr,sname,(`Expr (sr,$1),None), $3) 2158: } 2159: 2160: | expr incrop SEMI 2161: { 2162: let srop,sname = $2 in 2163: let sr = rsrange (src_of_expr $1) (slift $3) in 2164: call1 ("post_" ^ sname) sr srop $1 2165: } 2166: | incrop expr SEMI 2167: { 2168: let srop,sname = $1 in 2169: let sr = rsrange (slift srop) (slift $3) in 2170: call1 ("pre_" ^ sname) sr srop $2 2171: } 2172: 2173: