⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 explain.cpp

📁 c语言写的VB编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}

	// 存储编辑窗口画面
	gettext(1, 1, 80, 25, TextMirror);

	if (RunLineNo < 0)
	{
		// 从编辑状态开始单步调试

		// 设置输出坐标位置和执行行号
		OutX = OutY = 1;
		PreRunLineNo = -1;

		// 清屏
		SetColor(WHITE, BLACK);
		clrscr();

		// 存储输出窗口内容
		gettext(1, 1, 80, 25, OutMirror);

		// 置光标位置
		gotoxy(OutX, OutY);

		// 得到开始调试的第一条语句的行号
		RunLineNo = NextLine(0);

		// 前以调试语句为空
		PreRunLineNo = -1;
	}
	else
	{
		// 在调试状态下继续调试

		// 恢复输出窗口内容到屏幕
		puttext(1, 1, 80, 25, OutMirror);

		// 置光标位置
		gotoxy(OutX, OutY);

		SetColor(WHITE, BLACK);

		// 记下准备执行的行号
		PreRunLineNo = RunLineNo;

		// 执行当前语句并得到下一条应当执行的语句行号
		RunLineNo = NextLine(RunLine(RunLineNo));

		// 存储输出窗口的画面
		gettext(1, 1, 80, 25, OutMirror);

		if (Finished)
		{
			// 单步执行完毕

			// 恢复编辑窗口的画面
			puttext(1, 1, 80, 25, TextMirror);

			// 置前一次执行的语句行为当前行
			TextX = PreRunLineNo;

			// 输出编辑窗口垂直滚动条
			winEdit.ScrollVertical(TextX);

			// 停止调试
			StopDebugging();

			// 恢复前一个调试行的正常颜色
			PrintLine(PreRunLineNo);

			SetCursor();

			gotoxy(NowY, NowX);
			return;
		}
	}

	// 恢复编辑窗口画面
	puttext(1, 1, 80, 25, TextMirror);

	// 置前一次执行的语句行为当前行
	TextX = RunLineNo;

	// 输出编辑窗口垂直滚动条
	winEdit.ScrollVertical(TextX);

	if (TextX < x0 || TextX >= x0 + winEdit.High())
	{
		// 当前行超出编辑窗口当前屏的范围,需要滚动

		// 设置编辑窗口当前屏的首行为当前行的前一行
		x0 = TextX - 1;

		if (x0 < 0)
		{
			x0 = 0;
		}

		// 重新打印编辑窗口当前屏的文本
		PrintText(winEdit.Top() + 1);

		SetCursor();
	}

	// 设置光标X坐标
	NowX = winEdit.Top() + TextX - x0 + 1;

	if (PreRunLineNo >= 0)
	{
		// 不是单步执行的第一条语句,需要恢复前一条执行语句的颜色

		// 重新已正常颜色打印前一条执行语句
		PrintLine(PreRunLineNo);

		SetCursor();
	}

	// 以调试状态颜色打印当前语句
	DebugLine(RunLineNo);
}

void StepOver()
{
	// 单步执行语句,不进入SUB

	if (NextLine(0) == -1)
	{
		// 程序执行完毕,退出

		return;
	}

	// 存储编辑窗口画面
	gettext(1, 1, 80, 25, TextMirror);

	int PreLine = -1;

	if (RunLineNo < 0)
	{
		// 从编辑状态开始单步调试

		// 设置输出坐标位置和执行行号
		OutX = OutY = 1;
		PreRunLineNo = -1;

		// 清屏
		SetColor(WHITE, BLACK);
		clrscr();

		// 存储输出窗口内容
		gettext(1, 1, 80, 25, OutMirror);

		// 置光标位置
		gotoxy(OutX, OutY);

		// 得到开始调试的第一条语句的行号
		RunLineNo = NextLine(0);

		// 前以调试语句为空
		PreRunLineNo = -1;
	}
	else
	{
		// 在调试状态下继续调试

		// 恢复输出窗口内容到屏幕
		puttext(1, 1, 80, 25, OutMirror);

		// 置光标位置
		gotoxy(OutX, OutY);

		SetColor(WHITE, BLACK);

		char Word[MaxY];
		GetPart(Text[RunLineNo]->Line, 1, ' ', Word);
		if (strcmp(Word, "GOSUB") == 0)
		{
			PreLine = RunLineNo;
			do
			{
				// 执行当前语句,并返回下一个要执行的语句行号

				// 记下准备执行的行号
				PreRunLineNo = RunLineNo;

				RunLineNo = NextLine(RunLine(RunLineNo));
			} while (NowSub >= 0 && !Finished && !Error);
		}
		else
		{
			// 记下准备执行的行号
			PreRunLineNo = RunLineNo;

			RunLineNo = NextLine(RunLine(RunLineNo));
		}

		// 存储输出窗口的画面
		gettext(1, 1, 80, 25, OutMirror);

		if (Finished)
		{
			// 单步执行完毕

			// 恢复编辑窗口的画面
			puttext(1, 1, 80, 25, TextMirror);

			// 置前一次执行的语句行为当前行
			TextX = PreRunLineNo;

			// 输出编辑窗口垂直滚动条
			winEdit.ScrollVertical(TextX);

			// 停止调试
			StopDebugging();

			// 恢复前一个调试行的正常颜色
			PrintLine(PreRunLineNo);
			
			SetCursor();

			gotoxy(NowY, NowX);
			return;
		}
	}

	// 恢复编辑窗口画面
	puttext(1, 1, 80, 25, TextMirror);

	// 置前一次执行的语句行为当前行
	TextX = RunLineNo;

	// 输出编辑窗口垂直滚动条
	winEdit.ScrollVertical(TextX);

	if (TextX < x0 || TextX >= x0 + winEdit.High())
	{
		// 当前行超出编辑窗口当前屏的范围,需要滚动

		// 设置编辑窗口当前屏的首行为当前行的前一行
		x0 = TextX - 1;

		if (x0 < 0)
		{
			x0 = 0;
		}

		// 重新打印编辑窗口当前屏的文本
		PrintText(winEdit.Top() + 1);

		SetCursor();
	}

	// 设置光标X坐标
	NowX = winEdit.Top() + TextX - x0 + 1;
	if (PreLine >= 0)
	{
		PreRunLineNo = PreLine;
	}

	if (PreRunLineNo >= 0)
	{
		// 不是单步执行的第一条语句,需要恢复前一条执行语句的颜色

		// 重新以正常颜色打印前一条执行语句
		PrintLine(PreRunLineNo);

		SetCursor();
	}

	// 以调试状态颜色打印当前语句
	DebugLine(RunLineNo);
}

void StopDebugging()
{
	// 停止调试

	if (TempStopNo > -1)
	{
		// 有临时断点需要清除

        // 清除该临时断点
		Text[TempStopNo]->Break = false;
		TempStopNo = -1;
	}

	// 设置光标X坐标
	NowX = winEdit.Top() + TextX - x0 + 1;

	// 清除准备运行的行号
	RunLineNo = -1;

	// 清除全部变量空间
	ClearAll();
}

void Watch()
{
	// 监视表达式的值

	// 显示监视窗口
	winWatch.Show();

	// 清理输入窗口内容
	SetColor(WHITE, BLUE);
	gotoxy(23, 11);
	cprintf("                                   ");

	// 存储输入的表达式
	char Exp[40];

	// 得到用户输入的表达式
	winWatch.GetInput(Exp, 8, 24, 34);

	while (Exp[0] != '\0')
	{
		// 用户输入非空

		SetColor(WHITE, BLUE);
		gotoxy(24, 11);

		// 不显示错误信息
		NoShown = true;

		// 计算表达式的值
		int Seat = 0;
		double Result = Expression(Exp, Seat);

		if (Error)
		{
			// 发现错误

			Error = NoError;

			// 输出错误信息
			cprintf("Error!");
		}
		else
		{
			// 输出表达式的值

			cprintf("%g", Result);
		}

		// 移动光标到表达式末尾
		gotoxy(24 + strlen(Exp), 8);

		// 等待用户按任意键
		int Key;
		Receive(Key);

		// 清理输入窗口
		SetColor(WHITE, BLUE);
		gotoxy(23, 11);
		cprintf("                                   ");

		// 得到用户输入的表达式
		winWatch.GetInput(Exp, 8, 24, 34);
	}

	// 隐藏监视窗口
	winWatch.Hide();
}

void ShowOut()
{
	// 显示输出窗口内容

	// 存储当前文本窗口画面
	gettext(1,1,80,25,TextMirror);

	// 显示输出窗口画面到屏幕
	puttext(1,1,80,25,OutMirror);

	// 隐藏光标
	_setcursortype(_NOCURSOR);

	// 等待用户输入任意键
	int Key;
	Receive(Key);

	// 恢复文本窗口画面
	puttext(1,1,80,25,TextMirror);
}

void SearchPreMark()
{
	// 定位前一个带标记的行

	for (int i = TextX - 1; i >= 0; i--)
	{
		if (Text[i]->Mark)
		{
			// 已找到前一个带标记的行

			// 改变当前行为此标记行
			TextX = i;

			if (x0 <= i && i < x0 + winEdit.High())
			{
				// 此行在文本窗口的当前屏内

				// 计算光标X坐标
				NowX = i - x0 + winEdit.Top() + 1;
			}
			else
			{
				// 需要翻屏

				// 计算光标X坐标
				NowX = winEdit.Top() + 1;

				// 修改文本窗口首行序号
				x0 = i;

				// 重新打印文本窗口当前屏
				PrintText(winEdit.Top() + 1);

				SetCursor();
			}

			ShowPosition();

			winEdit.ScrollVertical(TextX);

			SetCursor();

			// 跳出循环
			break;
		}
	}
}

void SearchNextMark()
{
	// 定位下一个带标记的行

	for (int i = TextX + 1; i <= EndLine; i++)
	{
		if (Text[i]->Mark)
		{
			// 已找到下一个带标记的行

			// 改变当前行为此标记行
			TextX = i;

			if (x0 <= i && i <= x0 + winEdit.Bottom() - winEdit.Top() - 2)
			{
				// 此行在文本窗口的当前屏内

				// 计算光标X坐标
				NowX = i - x0 + winEdit.Top() + 1;
			}
			else
			{
				// 需要翻屏

				// 计算光标X坐标
				NowX = winEdit.Top() + 1;

				// 修改文本窗口首行序号
				x0 = i;

				// 重新打印文本窗口当前屏
				PrintText(winEdit.Top() + 1);

				SetCursor();
			}

			ShowPosition();

			winEdit.ScrollVertical(TextX);

			SetCursor();

			// 跳出循环
			break;
		}
	}
}

void HelpEdit()
{
	// 显示编辑帮助

    // 显示窗口
	winHelpOnEdit.Show();

	// 等待用户翻屏
	winHelpOnEdit.Work();

	// 隐藏窗口
	winHelpOnEdit.Hide();
}

void HelpSyntax()
{
	// 显示语法帮助

	// 显示窗口
	winHelpOnSyntax.Show();

	// 等待用户翻屏
	winHelpOnSyntax.Work();

	// 隐藏窗口
	winHelpOnSyntax.Hide();
}

void Thanks()
{
	// 显示感谢

	// 显示窗口
	winThanks.Show();

	// 等待用户按任意键
	winThanks.Wait();

	// 隐藏窗口
	winThanks.Hide();
}

void AboutCBasic()
{
	// 显示关于系统

	// 显示窗口
	winAboutCool.Show();

	// 等待用户按任意键
	winAboutCool.Wait();

	// 隐藏窗口
	winAboutCool.Hide();
}

void AboutMe()
{
	// 显示关于作者

	// 显示窗口
	winAboutMe.Show();

	// 等待用户按任意键
	winAboutMe.Wait();

	// 隐藏窗口
	winAboutMe.Hide();
}

void HeadZero
	(
	const unsigned int Number,	// 数字
	char *Return				// 返回的字符串
	)
{
	// 必要的时候,在数字的前面加'0',凑成两位数,返回字符串

	// 将数字转化为字符串
	itoa(Number, Return, 10);

	if (Number < 10)
	{
		// 是一位数,需要在前面加'0'

		char Temp[3] = "0";
		strcat(Temp, Return);
		strcpy(Return, Temp);
	}
}

void Find()
{
	// 在程序中搜索字符串

	// 显示搜索窗口
	winFind.Show();

	// 得到用户输入的字符串
	winFind.GetInput(Target, 6, 39, MaxLenOfSearch);

	strupr(Target);

	// 隐藏搜索窗口
	winFind.Hide();

	if (Target[0] != '\0')
	{
		// 输入的字符串非空

		// 记下当前位置
		StartSearchX = TextX;
		StartSearchY = TextY;

		// 搜索下一个目标字符串
		SearchAgain();
	}
}

void SearchAgain()
{
	// 搜索下一个目标字符串

	if (Target[0] != '\0')
	{
		// 目标字符串非空

		if (StartSearchX == -1)
		{
			// 此字符串已经搜索过一遍,现在从当前位置继续搜索

			StartSearchX = TextX;
			StartSearchY = TextY;
		}

		// 文本行的副本
		char Line[MaxY];

		// 用于得到开始位置的字符串
		char *ptr;
		for (int i = StartSearchX; i <= EndLine; i++)
		{
			// 得到文本行的副本
			strcpy(Line, Text[i]->Line);

			// 整行全大写,便于搜索目标
			strupr(Line);

			// 得到目标字符串的开始位置
			ptr = strstr(Line, Target);

			if (ptr != NULL)
			{
				// 本行中存在目标字符串

				do
				{
					// 设置文本Y坐标为目标串的开始位置
					TextY = strlen(Line) - strlen(ptr);

					if (TextY < StartSearchY && TextX == i)
					{
						// 该目标字符串在开始搜索位的前面,应该找下一个

						// 清除当前位,以便搜索下一个
						Line[TextY] = ' ';

						// 得到目标字符串的开始位置
						ptr = strstr(Line, Target);
					}
				} while (TextX == i && TextY < StartSearchY && ptr != NULL);

				if (ptr == NULL)
				{
					// 当前行没有包含目标字符串,继续下一行

					continue;
				}

				// 改变当前行
				TextX = i;

				if (TextX > x0 + winEdit.High() - 1)
				{
					// 目标行在文本窗口当前屏外,需要翻屏

					// 设置目标行为文本窗口首行
					x0 = TextX;
				}

				PrintText(winEdit.Top() + 1);

				// 设置光标的位置
				NowX = TextX - x0 + winEdit.Top() + 1;
				NowY = TextY + winEdit.Left() + 1;

				// 设置搜索的开始位置
				StartSearchX = TextX;
				StartSearchY = TextY + 1;

				char Word[MaxY];
				GetMid(Text[TextX]->Line, TextY, TextY + strlen(Target) - 1, Word);

				gotoxy(NowY, NowX);
				SetColor(BLUE, WHITE);
				cprintf("%s", Word);
				gotoxy(NowY, NowX);

				int Key;
				Receive(Key);

				PrintLine(TextX);

				SetCursor();

				gotoxy(NowY, NowX);

				// 寻找成功,返回
				return;
			}
		}
	}

	// 寻找失败,显示搜索完毕
	
	// 显示窗口
	winSearchMessage.Show();

	// 等待用户按任意键
	winSearchMessage.Wait();

	// 隐藏窗口
	winSearchMessage.Hide();

	// 清除搜索开始位置
	StartSearchX = -1;
}

int Ask()
{
	// 询问用户是否保存当前文件

	// 显示查询窗口
	winAsk.Show();

	// 存储用户输入
	int Key;

	do
	{
		// 等待用户输入
		Receive(Key);

		if (Key == KeyEsc)
		{
			// 放弃本次操作

			// 隐藏查询窗口
			winAsk.Hide();

			return Cancel;
		}

		// 变大写
		Key = toupper(Key);

		switch (Key)
		{
		case 'Y':
			// 存盘

			// 隐藏查询窗口
			winAsk.Hide();

			return Yes;
		case 'N':
			// 不存盘

			// 隐藏查询窗口
			winAsk.Hide();

			return No;
		}
	} while (true);
}

int SaveBeforeRun()
{
	// 运行前存盘

	if (!Saved)
	{
		// 当前文件未存盘

		if (strcmp(winEdit.Caption(), DefaultFileName) == 0)
		{
			// 是默认文件名,等待用户重命名

			if (SaveAsFile() != Yes)
			{
				return false;
			}
		}
		else
		{
			// 直接存盘

			SaveFile(winEdit.Caption());
		}
	}

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -