Parameter Passing: Difference between revisions

no edit summary
No edit summary
Line 141:
 
Trying to modify an argument with ''intent in'' triggers an error at compile time.
 
===Example [[M2000 Interpreter]]===
All parameters are passed by value is a stack of values. This stack is a collection of values, and that collection is passed from a module to a module as is, at also return back. Functions start with a fresh stack of values, and at that stack all the parameters from the call stored there. To read parameters from start of values we use Read. A definition Function a(k as integer) {code here} is identical with that: Function a {read j as integer : code here}. Because we can use read at any point of a module or function we can handle parameters with many ways before actually pop them from the stack, like we can check type, we can rearrange and use the stack of values for any use.
 
We can pass by reference values, although actually we store a weak reference and at the Read statement this reference change to normal if it is valid (or an error occur). So call thisModule &Z pass a string as a weak reference, and at the thisModule we have the Read &t which make t to hold the same memory as the Z.
 
Some objects are passed by value but because we pass the pointer to object we can change it. If we pass an array with parenthesis like thisModule A() we pass a pointer but the interpreter knows that this is a by value pass so at read statement the Read K() copy the A() to K(). If we wish to pass by reference then we use this thisModule &A() but the Read statement has to be prepared to get the reference like this Read &K(). So we can't use the same parameter by value and by reference at will, we have to make the code at read statement to be by value or by reference. We can use code to examine the type of parameter in the stack of values and then decide which read statement to use. So there is always a way to program a stack handler, to cope with by parameter types, although there is no automatic except for those which is always by reference and those which is always by value.
 
We can pass by reference functions. This is a copy of function code (as string) inside a block {} so the Read statement if we setup like this Read &A() expect to find a string which have a block of code {}.
 
A reference can't get as second reference. But we can use temporary block using For This { } so anything we make there just deleted after exit from block, so the next time we enter the block we may define a new reference (because the name which take the reference is new). Some times we use a special call, the "call local" which place the current scope to a module or function (which its called as module), so there we use Read New to make any local name as a new name, including by reference passing values (to shadow same names from same scope module). This used for event service functions.
 
This show how we can make a function reference (just a copy of code), and a second function which use the same scope. We can use lazy$() which make this automatic for a function k() as lazy$(&k()) which put the module and the module name to code of k(). Here we see only the way we do this simply by using strings. Module$ return the internal compact name of module. Use module.name$ to print the expanded named.
 
<syntaxhighlight lang="m2000 interpreter">
module kappa {
push "{read x, y:=x**y}"
read &a()
print a(2, 3)=8
long m
push "{module "+module$+" : m++}"
read &b()
call b()
print m=1
}
call kappa
</syntaxhighlight>
 
 
 
 
===Example [[Z80 Assembly]]===
404

edits