CLANGER's integration with the operating system is achieved through the ability to invoke methods on interfaces. A full method invocation is a statement a bit like this:
[ res1, res2, res3 ] <- iref$method[ arg1, arg2, arg3 ];
On parsing this statement, the interpreter finds the variable whose name is iref and checks that it is an interface reference whose type has an operation called method. It then checks that the operation has three arguments, that the types of arguments arg1, arg2 and arg3 can be narrowed to the appropriate argument types, and that the operation returns at least three results.
The interpreter then actually synthesizes a Nemesis method invocation on the interface and binds to the names res1, res2 and res3 the first three results, changing the types of res1 etc. in the process to reflect their new values. Extra results are discarded.
Various shorthands exist. Intermediate results from the call can also be discarded, for example in the statement:
[ res1,,, res4 ] <- iref$method2[ arg1, arg2, arg3 ];
All results (if they exist) can be ignored with a statement like:
iref$method3[ arg1, arg2, arg3 ];
A single result can be extracted. The value of the expression:
iref$method4[ arg1, arg2 ].result3
is the result whose formal parameter name is result3.
Finally, to invoke a method with no arguments and discard all its results, one can just use the syntax:
Exceptions raised by method invocation calls are caught and translated into CLANGER exceptions.