Externals, Functions and Procedures
Externals, Functions and Procedures
I have been faffing around trying to understand, within my SMSQE/SMS2/Qlib systems, Externals, Functions and Procedures.
I have written many more test programs that fail than test programs that work, in a not completely futile attempt to learn by experiment. I have, of course read the instruction manuals concerning these concepts, but can understand only about 70% of the documentation and thus cannot workout by myself what I am doing wrong.
An example of my problem is note 4, page 154 of the BASIC ref. manual:-
"Although a sub-set of a simple string (what is a complex string?) is an expression (what is an expression?) and therefore will not be altered within a function, a sub-set of a string array (my translation of DIM string) is not treated as an expression and will therefore be altered!!"
What does the above mean? In my opinion coded examples are the best way to explain the use of an instruction.
My problem is that I use the ancient programming environment of SMS2 adapted for SMSQE and so I have to navigate around references to Interpreted BASIC and programming with line numbers to create my own method of creating test programs.
I am developing a standard way of testing BASIC instructions within a moveable windowing environment as can be seen in my JPG.
The four programs use a procedure compiled as an external that generates the image (EP_Mkw that takes a string parameter that is displayed in the title box). The programs then test passing an integer, a floating point number, a string and an array to a function called F_doit.
One can see that my attempt to pass and return an integer fails and my attempt to pass and return an array produces a strange result. The two others work correctly.
What am I doing wrong?
I have written many more test programs that fail than test programs that work, in a not completely futile attempt to learn by experiment. I have, of course read the instruction manuals concerning these concepts, but can understand only about 70% of the documentation and thus cannot workout by myself what I am doing wrong.
An example of my problem is note 4, page 154 of the BASIC ref. manual:-
"Although a sub-set of a simple string (what is a complex string?) is an expression (what is an expression?) and therefore will not be altered within a function, a sub-set of a string array (my translation of DIM string) is not treated as an expression and will therefore be altered!!"
What does the above mean? In my opinion coded examples are the best way to explain the use of an instruction.
My problem is that I use the ancient programming environment of SMS2 adapted for SMSQE and so I have to navigate around references to Interpreted BASIC and programming with line numbers to create my own method of creating test programs.
I am developing a standard way of testing BASIC instructions within a moveable windowing environment as can be seen in my JPG.
The four programs use a procedure compiled as an external that generates the image (EP_Mkw that takes a string parameter that is displayed in the title box). The programs then test passing an integer, a floating point number, a string and an array to a function called F_doit.
One can see that my attempt to pass and return an integer fails and my attempt to pass and return an array produces a strange result. The two others work correctly.
What am I doing wrong?
Re: Externals, Functions and Procedures
Code: Select all
3 DIM A_x$(0,5)
5 A_x$(0,1)="a"
6 A_x$(0,2)="p"
9 :
17 :
20 b$=F_doit$ ("querty")
25 PRINT b$
27 :
28 B_x$=A_x$(0,TO 2)
30 c_x$=G_doit$ (B_x$)
35 PRINT A_x$(0,TO 2),c_x$
37 :
40 b% =doit%(3)
45 PRINT b%
47 :
50 b%= doit(4)
55 PRINT b%
57 :
99 :
100 DEFine FuNction F_doit$ (x$)
110 x$=x$&"12345"
120 RETurn x$
130 END DEFine
140 :
200 DEFine FuNction G_doit$ (z$)
210 z$=z$&"1234"
220 RETurn z$
230 END DEFine
240 :
300 DEFine FuNction doit% (x%)
310 x%=x%*10
320 RETurn x%
330 END DEFine
340 :
400 DEFine FuNction doit (x)
410 x=x*10
420 RETurn x
430 END DEFine
Hope it helps
Greetings from Switzerland
Markus
Re: Externals, Functions and Procedures
Thank you Markus,
When I get home this evening I will go through your code and see if I can test it on my system.
When I get home this evening I will go through your code and see if I can test it on my system.
-
- Aurora
- Posts: 874
- Joined: Mon Nov 24, 2014 2:03 pm
Re: Externals, Functions and Procedures
Hi TinyFpga,
Be wary when using float, integer% or string$ variables, parameters , procedures or functions under QDOS.
They were never properly implemented until SMSQ/E came along:
Take a look at the parameters_bug program attatched : Just Unzip it and LRUN it on your system.
Under QDOS you get an error at line 110, whereas under SMSQ/E the error is correctly at 100 as you would expect...
Under QDOS, the routine parameter's type depends on the calling variable's type !
This was hardly ever explained in documentation... Steve.
_______________________________________________________
Be wary when using float, integer% or string$ variables, parameters , procedures or functions under QDOS.
They were never properly implemented until SMSQ/E came along:
Take a look at the parameters_bug program attatched : Just Unzip it and LRUN it on your system.
Under QDOS you get an error at line 110, whereas under SMSQ/E the error is correctly at 100 as you would expect...
Under QDOS, the routine parameter's type depends on the calling variable's type !
This was hardly ever explained in documentation... Steve.
_______________________________________________________
Re: Externals, Functions and Procedures
No, under SMSQ/E it says "At line 150:4 error in expression" and shows "1" at #1.stevepoole wrote: Fri Feb 28, 2025 2:46 pm Under QDOS you get an error at line 110, whereas under SMSQ/E the error is correctly at 100 as you would expect...
But I don't understand the error message.
7000 4E75
-
- Aurora
- Posts: 874
- Joined: Mon Nov 24, 2014 2:03 pm
Re: Externals, Functions and Procedures
Hi again,
Yes, under SMSQ the floats parameter is defined as floating-point. So when the calling variable is 'e'', SMSQ/E signals an error line 150.
But, under QDOS, floats accepts that the variable 'e' is sring-type, and tries to pass the value to the local variable f, which is by default a floating point type. Without delving into (expressions), the interpreter cannot convert 'e' to floating point, so signals an error on line 160....!
As mentioned last time, under QDOS this is a bug, in that routine parameters get their type from the calling expression.
Corrected under SMSQ/E, the error is correctly signalled on line 150... All rather confusing under QDOS, so prefer SMSQ/E every time ! Steve.
_____________________________
Yes, under SMSQ the floats parameter is defined as floating-point. So when the calling variable is 'e'', SMSQ/E signals an error line 150.
But, under QDOS, floats accepts that the variable 'e' is sring-type, and tries to pass the value to the local variable f, which is by default a floating point type. Without delving into (expressions), the interpreter cannot convert 'e' to floating point, so signals an error on line 160....!
As mentioned last time, under QDOS this is a bug, in that routine parameters get their type from the calling expression.
Corrected under SMSQ/E, the error is correctly signalled on line 150... All rather confusing under QDOS, so prefer SMSQ/E every time ! Steve.
_____________________________
-
- QL Wafer Drive
- Posts: 1048
- Joined: Sat Oct 25, 2014 9:53 am
Re: Externals, Functions and Procedures
Hi Tinyfpga!
Probably a moot point now, but taking one of your earlier questions, in case you still had any doubts:
An expression is a compound, literal or computed value, like a$ & '_bas', a$ & b$, or just '_bas'
Technically, the example above a$(1 TO 5) is such a computed value or expression and, as such, is passed to the FN/PROC call by 'value' instead of by 'reference.' Being passed by value, any changes made to the 'formal' variable (what it's called within the scope of the procedure) during the procedure is dropped on return to the calling code (after all, how can you assign a value back to an expression?)
What that explanation is trying to highlight is that, when instead passing a sub-range of a DIMensioned array, e.g. a$(1 TO 5), where a$ was previously dimensioned as, say, DIM a$(5,10), then it is instead passed by reference and thus, any changes made to the formal parameter during the procedure will be reflected back to the original 'actual' array variable, a$() on return from the procedure call.
Thus, you can't readily tell whether passing a$(1 TO 5) will be treated as 'by-reference' or 'by-value', without knowing whether or not a$ was previously DIM'd.
Not sure that's any clearer than the original text
S*BASIC tends to default to passing parameters by reference, except in the case of expressions. This point often catches-out programmers starting-out with the TURBO compiler, which will always pass by value unless you explicitly state by REFERENCE - and, as arrays MUST be passed by reference, any passed arrays need to have the REFERENCE keyword added ahead of the relevant FN/PROC... But I digress...
Enjoy the journey!
Probably a moot point now, but taking one of your earlier questions, in case you still had any doubts:
A 'simple string' is an un-DIMensioned string, e.g. a$, and a 'sub-set' (more properly, a 'sub-string') might be a$(1 TO 5). The term 'complex string' isn't used, but is, as you imagine, a DIMensioned string array (or 'vector' vs 'scalar', to use alternative terms for the same things.)An example of my problem is note 4, page 154 of the BASIC ref. manual:-
"Although a sub-set of a simple string (what is a complex string?) is an expression (what is an expression?) and therefore will not be altered within a function, a sub-set of a string array (my translation of DIM string) is not treated as an expression and will therefore be altered!!"
An expression is a compound, literal or computed value, like a$ & '_bas', a$ & b$, or just '_bas'
Technically, the example above a$(1 TO 5) is such a computed value or expression and, as such, is passed to the FN/PROC call by 'value' instead of by 'reference.' Being passed by value, any changes made to the 'formal' variable (what it's called within the scope of the procedure) during the procedure is dropped on return to the calling code (after all, how can you assign a value back to an expression?)
What that explanation is trying to highlight is that, when instead passing a sub-range of a DIMensioned array, e.g. a$(1 TO 5), where a$ was previously dimensioned as, say, DIM a$(5,10), then it is instead passed by reference and thus, any changes made to the formal parameter during the procedure will be reflected back to the original 'actual' array variable, a$() on return from the procedure call.
Thus, you can't readily tell whether passing a$(1 TO 5) will be treated as 'by-reference' or 'by-value', without knowing whether or not a$ was previously DIM'd.
Not sure that's any clearer than the original text

S*BASIC tends to default to passing parameters by reference, except in the case of expressions. This point often catches-out programmers starting-out with the TURBO compiler, which will always pass by value unless you explicitly state by REFERENCE - and, as arrays MUST be passed by reference, any passed arrays need to have the REFERENCE keyword added ahead of the relevant FN/PROC... But I digress...
Enjoy the journey!
Re: Externals, Functions and Procedures
It's not moot as you have answered my question and I find it useful. My experience with the forum is that if I ask a number of questions in a single post, I generally do not receive responses to all of them. It seems better to post one problem at a time. (see next post!)Probably a moot point now
Re: Externals, Functions and Procedures
I have modified your code to suit my environment and have then interpreted and compiled your code.Hope it helps. Greetings from Switzerland. Markus
The interpreted result is in the window to the left of the screen and the compiled result is on the right.
One can see that there is a difference. The compiled code produces erroneous results.
-
- QL Wafer Drive
- Posts: 1048
- Joined: Sat Oct 25, 2014 9:53 am
Re: Externals, Functions and Procedures
Hi again Tinyfpga
Out of interest, which compiler did you use to generate the executable with output on the right?
[Scratch that - you mentioned QLib previously in this thread]
Which version of QLib? Seems you're running this latest test in SMS2 - I wonder if there is some compatibility issue between the two - or rather, between QLib and the SBASIC interpreter version you're running in SMS2.
Bear in mind that QLib continued to be developed long after the first (only?) release of SMS2 and, likely as not, was tested primarily on QDOS and later SMSQe, so any potential incompatibilities with SMS2 are unlikely to have been spotted (until now...)
The second numeric error looks to be some Maths stack error within the compiled code, but what is causing the first string error isn't at all clear.
What happens if you replace the sub-string range with (1 TO 2)?
Out of interest, which compiler did you use to generate the executable with output on the right?
[Scratch that - you mentioned QLib previously in this thread]
Which version of QLib? Seems you're running this latest test in SMS2 - I wonder if there is some compatibility issue between the two - or rather, between QLib and the SBASIC interpreter version you're running in SMS2.
Bear in mind that QLib continued to be developed long after the first (only?) release of SMS2 and, likely as not, was tested primarily on QDOS and later SMSQe, so any potential incompatibilities with SMS2 are unlikely to have been spotted (until now...)
The second numeric error looks to be some Maths stack error within the compiled code, but what is causing the first string error isn't at all clear.
What happens if you replace the sub-string range with (1 TO 2)?