请注意,下面的 C# 示例代码专门用作 BASIC-to-C# 编译器的输出格式。任何像这样编写“真正的”C# 代码的人都将被吊销其编程许可证。
BASIC 的 GOTO 语句可以使用“尾调用悲观化”实现:将每个 GOTO X 转换为 GOSUB X:RETURN。
然后,您可以将整个 BASIC 程序渲染为一个巨大的 Gosub(int lineNumber) 函数,使用带有 case 块的每个行号的 switch 语句,以及简单地 GOSUB 到最低行号的 Main 函数。
例如,BASIC 程序:
10 PRINT "Enter an integer: ";
20 INPUT N%
30 IF N% MOD 2 = 0 THEN GOTO 60
40 PRINT N%;" is odd."
50 GOTO 70
60 PRINT N%;" is even."
70 PRINT "Goodbye."
可以像这样逐行转换成C#程序:
using System;
static class Program
{
// BASIC variables are always global and zero-initialized.
static int n_int = 0;
static void Gosub(int lineNumber)
{
switch (lineNumber)
{
case 10: // 10 PRINT "Enter an integer: ";N%
Console.Write("Enter an integer: ");
// By default, the end of each line falls thru to next line number
goto case 20;
case 20: // 20 INPUT N%
n_int = int.Parse(Console.ReadLine());
goto case 30;
case 30: // 30 IF N% MOD 2 = 0 THEN GOTO 60
if (n_int % 2 == 0)
{
Gosub(60);
return;
}
goto case 40;
case 40: // 40 PRINT N%;" is odd."
Console.WriteLine("{0} is odd.", n_int);
goto case 50;
case 50: // 50 GOTO 70
Gosub(70);
return;
case 60: // 60 PRINT N%;" is even."
Console.WriteLine("{0} is even.", n_int);
goto case 70;
case 70: // 70 PRINT "Goodbye."
Console.WriteLine("Goodbye.");
// Falling off the end of the program exits it.
return;
}
}
static void Main()
{
Gosub(10);
}
}
当您有这样的文字行号时,您可以将Gosub(X); return; 优化为goto case X;。但是,函数调用方式允许行号为任意表达式,而 C# 的goto case 则不允许。
转换后的代码显然不是很容易维护,但它确实可以编译和运行。
编辑:显然,C# 编译器不保证尾调用优化,这可能会导致长循环或无限循环的堆栈溢出。但是,您可以通过重新分配lineNumber 参数并跳回到switch 语句的开头来手动执行此优化,如下所示:
using System;
static class Program
{
// BASIC variables are always global and zero-initialized.
static int n_int = 0;
static void Gosub(int lineNumber)
{
START:
switch (lineNumber)
{
case 10: // 10 PRINT "Enter an integer: ";N%
Console.Write("Enter an integer: ");
// By default, the end of each line falls thru to next line number
goto case 20;
case 20: // 20 INPUT N%
n_int = int.Parse(Console.ReadLine());
goto case 30;
case 30: // 30 IF N% MOD 2 = 0 THEN GOTO 60
if (n_int % 2 == 0)
{
lineNumber = 60;
goto START;
}
goto case 40;
case 40: // 40 PRINT N%;" is odd."
Console.WriteLine("{0} is odd.", n_int);
goto case 50;
case 50: // 50 GOTO 70
lineNumber = 70;
goto START;
case 60: // 60 PRINT N%;" is even."
Console.WriteLine("{0} is even.", n_int);
goto case 70;
case 70: // 70 PRINT "Goodbye."
Console.WriteLine("Goodbye.");
// Falling off the end of the program exits it.
return;
}
}
static void Main()
{
Gosub(10);
Console.ReadKey();
}
}
与前面的示例一样,常量 GOTO 目标可以优化为单个 goto case 语句。