5.16.7.19. Procedure Call

Start data section to src/flx_parse.mly[26 /35 ] Next Prev First Last
  2000: compound:
  2001:   | LBRACE statement_aster RBRACE  { rstoken $1 $3, $2 }
  2002: 
End data section to src/flx_parse.mly[26]
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[27 /35 ] Next Prev First Last
  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: 
End data section to src/flx_parse.mly[27]
Note that a block is an anonymous procedure defintion together with a call to that procedure with the unit argument.