Tue 19 Jun 2007
Compiling variant function return types in BBC BASIC
Posted by Robert Smallshire under software , computing , .NET , OWL BASICSome significant challenges to compiling BBC BASIC have been raised by Richard Russell, maintainer of BBC Basic for Windows. I have decided to explore the issues he raises through further posts here, rather than through responses to his earlier comments, since they will be quite long.
Today, we will look at the problem of the return type of functions not being known until run-time. Richard presented an example, which by his own admission was somewhat contrived, which nonetheless serves to illustrate the point. Of course, this also applies to the built in function EVAL which may return any of the standard BBC BASIC types.
Richard’s example was for FNunsuretype, reproduced below, which I’ve incorporated into a simple, runnable program:
a% = FNunsuretype b$ = FNunsuretype PRINT FNunsuretype END DEF FNunsuretype : LOCAL R% R% = RND(2) IF R% = 1 THEN = 12345 ELSE = “a string”
As we can see, the function gives a fifty-fifty chance of returning either an integer or a string. Obviously the program has a 25% chance of failing with a Type Mismatch error when run, but we’ll ignore that for now. Let’s take a look at the equivalent code in C#, which is most definitely a compiled language:
using System;
class Program
{
static System.Random rnd = new System.Random();
static void Main(string[] args)
{
int a = (int) UnsureType();
string b = (string) UnsureType();
Console.WriteLine(UnsureType());
}
static object UnsureType()
{
int r = rnd.Next(1);
if (r == 0)
{
return 12345;
}
else
{
return "a string";
}
}
}Here the function UnsureType() also returns either a number or a string with 50% probability, but we use the autoboxing feature of C# to wrap the integer or string in an object, which is what the function returns. Note that to unbox the type, we must use a cast, although not in the case of Console.WriteLine which calls the ToString method on the object, which in turns calls the ToString method on the boxed basic type. Note that this program also has a 25% chance of failing with an InvalidCastException, which is equivalent to a Type Mismatch in BBC BASIC.
Using static analysis techniques it should be possible to determine at compile time whether a BBC BASIC function needs to box its return value in an object. Most functions will have exit points where the return type is well-defined, or can be inferred from the type of the returned expression. Such functions can be compiled with a fixed return type. Those functions which have multiple but differing return types, or unknowable return types, such as returned by EVAL, will need to box their return values in an object. It should then be possible at the call-site of the function to determine whether an implicit cast is needed to convert the returned object to a useful value.
June 19th, 2007 at 5:39 pm
Rob,
I don’t know C#, but that looks interesting.
If it helps, here is what I believe to be a complete set of BBC BASIC statements which can take a variable type (numeric or string), and therefore won’t necessarily issue a ‘Type mismatch’ error if presented with the output from FNunsuretype:
BPUT#
CALL (BBC BASIC for Windows only)
CASE
PRINT
PRINT#
SYS
WHEN
Regards, Richard.
June 20th, 2007 at 1:50 am
Richard,
Thankyou for the useful information. I think if all the functions you list above accept .NET objects then the scheme I presented can work. For example, PRINT will call object.ToString() and CASE/WHEN will use object.Equals(object).
Rob
September 13th, 2007 at 12:41 pm
Where you say 25 I think you mean to say 75.