Page 75
efficient because the code is just compiled once. With a macro, the entire macro body would be placed at each point where it was called.
The RCX imposes three crippling restrictions on subroutines. First, you can't call another subroutine from within a subroutine. As a consequence, a subroutine also cannot call itself. Second, you
can't pass parameters to a subroutine or get a return value. Third, no more than eight subroutines can be defined for a single program. These limitations are imposed by the RCX's bytecode
interpreter, which is defined in the firmware. To get around restrictions like these, you'll need to use a different firmware, like legOS or pbForth.
Inlines
NQC does offer another interesting option, the inline subroutine. In source code, it looks a lot like a subroutine except with a C-style return type (always void):
void wiggle() {
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(20);
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(20);
Off(OUT_A + OUT_C);
}
Inlines are called the same way as subroutines. The compiler actually places the code of the inline wherever it is called, almost like a macro or constant definition. This actually makes inlines
appear a little more capable than subroutines: they can call other inlines or even subroutines. In NQC version 2.0, for example, you can define inlines with a parameter, like this:
void wiggleTime(int waitTime) {
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(waitTime);
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(waitTime);
Off(OUT_A + OUT_C);
}
You can have more than one argument, if you wish. Just remember that inlines are really an example of syntactic sugar, something that makes your source code look pretty but doesn't necessarily
result in better efficiency.
Arguments to inlines can be passed in four different ways. Table 4-7 summarizes the options.
Page 76
Table 4-7. Argument Passing for Inlines
Type By Value or By Reference? Temporary Variable Used?
int
by value yes
const int
by value no
int&
by reference no
const int&
by reference no