-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
91 lines (76 loc) · 2.97 KB
/
Program.cs
File metadata and controls
91 lines (76 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using Antlr4.Runtime;
using System;
using System.Collections.Generic;
using System.Text;
namespace TinyLanguage
{
class Program
{
static void Main(string[] args)
{
var sourceCode = @"
// 示例:Collatz 序列 (3n+1 问题)
VAR n : INT; // 当前序列中的数字,初始为用户输入
VAR isEvenTemp : INT; // 用于判断 n 是否为偶数的临时变量 (0代表偶数, 1代表奇数)
VAR tempCalc : INT; // 用于中间计算
OUT(101); // ""请输入一个正整数 (n > 0):""
n = IN();
IF (n <= 0) { // 检查输入是否为正整数
OUT(901); // ""错误:输入必须是正整数!""
} ELSE {
OUT(200); // ""Collatz 序列:""
OUT(n); // 输出序列的第一个数 (即用户输入的数)
WHILE (n != 1) { // 当 n 不等于 1 时,继续循环
// 判断 n 是奇数还是偶数
// 通过 n - (n / 2) * 2 来判断余数是否为0 (模拟 n % 2)
// TL 中的 '/' 是整数除法
tempCalc = n / 2;
isEvenTemp = n - (tempCalc * 2); // 如果 n 是偶数, isEvenTemp == 0; 如果是奇数, isEvenTemp == 1 (对于正数n)
IF (isEvenTemp == 0) { // n 是偶数
n = n / 2;
} ELSE { // n 是奇数
// n = n * 3; // 不能直接这样,因为 n * 3 可能很大,先分开计算
// n = n + 1;
// 更安全的做法,使用临时变量避免过早修改 n
tempCalc = n * 3;
n = tempCalc + 1;
}
OUT(n); // 输出序列中的当前数
}
// 当 n 等于 1 时,循环结束,序列已包含最后的 1。
}
";
Console.WriteLine("---源码---");
Console.WriteLine(sourceCode);
var program = GenerateProgram(sourceCode);
var vm = new VirtualMachine();
vm.LoadProgram(program);
Console.WriteLine("---二进制---");
List<string> disassembledCode = vm.DisassembleProgram(0, program.Length);
foreach (string line in disassembledCode)
{
Console.WriteLine(line);
}
Console.WriteLine("---程序开始执行---");
vm.Run();
Console.WriteLine("---程序执行结束---");
}
static byte[] GenerateProgram(string sourceCode)
{
var inputStream = new AntlrInputStream(sourceCode);
var lexer = new TinyLanguageLexer(inputStream);
var commonTokenStream = new CommonTokenStream(lexer);
var parser = new TinyLanguageParser(commonTokenStream);
var tree = parser.program();
if (parser.NumberOfSyntaxErrors > 0)
{
throw new Exception("代码中存在语法错误");
}
var visitor = new CodeGeneratorVisitor();
visitor.Visit(tree);
var bytecode = visitor.GetBytecode();
bytecode.Add((byte)OpCode.HLT);
return bytecode.ToArray();
}
}
}