如何执行我正在编写的语言?

How to implement the execution of a language that I am writing?

我正在使用 C# 编写自己的编程语言只是为了好玩。它被称为声压级。它只有 12 keywords/commands/instructions,仅此而已。我确切地知道每个命令要做什么。这是 class 图:

当然这还没完。但想法是,我们有一个运行时 ISplRuntime。命令所做的所有事情都是在运行时完成的。例如,OutputCommandISplRuntime.Current(这只是一个object)中的内容输出到ISplRuntime.Output(这是一个TextWriter)。

到目前为止一切顺利。但是然后我需要实现 IGotoCommand 就像 C# 中的 goto 关键字一样。我要制作三种goto。但是我不知道如何改变程序的流程。

这是我尝试过的想法:

ISplRuntime中添加一个名为RunNextCommand()的方法。在每个命令的 Execute() 方法的末尾,调用 RunNextCommand。但是,如果用户写了很多 SPL 代码,stack trace 会越来越大,导致 Stack Overflow。

ISplRuntime 添加代表。每次命令完成执行时,Invoke() 委托。委托将查找下一个要执行的命令并在 ICommand 上调用 Execute()。但是我不确定这是否也会导致堆栈溢出。 会不会导致栈溢出?

我仍然不太确定这样做是否正确。我只是想要一个关于如何做这种事情的一般性答案,因为这是我第一次写语言。也请告诉我使用委托是否会导致堆栈溢出。

通常,你会做一个循环;在循环中,在当前行执行命令,然后对于所有非流控制命令递增当前行。对于goto,只需将当前行设置为参数即可。没有堆栈问题,因为流程不是递归的 - 一切都从指令循环启动(它属于运行时,给定你的 class 图)。

I am writing my own programming language using C# just for fun.

太棒了!

Add a method called RunNextCommand() in ISplRuntime. And in the end of every command's Execute() method, call RunNextCommand.

甚至在您意识到这样做会导致堆栈溢出之前,您就应该意识到您对 RunNextCommand 的描述并不像罐头上所说的那样。您描述的内容称为 RunRemainderOfProgram。这表明此设计有些问题。

Add a delegate to ISplRuntime. Each time a command has finished executing, Invoke() the delegate. The delegate will look for the next command to execute and call Execute() on that ICommand. But I am not sure if this will also result in a stack overflow. Will it result in a stack overflow?

我不明白为什么会这样。所以这里的想法是 RunNextCommand 作为它的最后一个动作设置一个委托,当被调用时,它执行下一个命令?

你在这里发明的东西叫做延续。指令的延续是当前执行点的"what happens next?"。

I am still not very sure if this is the right way to do it. I just want an general answer about how to do this kind of thing as this is the first time for me to write a language.

有很多方法可以构建解释器,这基本上就是您在这里所做的。我会继续试验,看看哪些有效,哪些无效。

研究这个问题在虚拟机和实际机器中是如何解决的可能会有所帮助。在那些机器中,每条指令都有一个与之关联的唯一编号; "goto" 包含 运行 的下一条指令的编号。有一个名为 "instruction pointer" 的特殊变量,它具有当前 运行ning 指令的编号。如果当前指令是goto,则IP被设置为goto指示的值;如果不是,IP 递增到下一条指令,依此类推。然后主循环是 "look up the instruction at the current IP, execute it, set the new IP, repeat".

Also please tell me whether using delegates will cause a stack overflow.

很难预测我们看不到且您未编写的程序的行为。试一试,你会很快发现你是否写过无界递归。

祝你好运!