如何执行我正在编写的语言?
How to implement the execution of a language that I am writing?
我正在使用 C# 编写自己的编程语言只是为了好玩。它被称为声压级。它只有 12 keywords/commands/instructions,仅此而已。我确切地知道每个命令要做什么。这是 class 图:
当然这还没完。但想法是,我们有一个运行时 ISplRuntime
。命令所做的所有事情都是在运行时完成的。例如,OutputCommand
将ISplRuntime.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.
很难预测我们看不到且您未编写的程序的行为。试一试,你会很快发现你是否写过无界递归。
祝你好运!
我正在使用 C# 编写自己的编程语言只是为了好玩。它被称为声压级。它只有 12 keywords/commands/instructions,仅此而已。我确切地知道每个命令要做什么。这是 class 图:
当然这还没完。但想法是,我们有一个运行时 ISplRuntime
。命令所做的所有事情都是在运行时完成的。例如,OutputCommand
将ISplRuntime.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.
很难预测我们看不到且您未编写的程序的行为。试一试,你会很快发现你是否写过无界递归。
祝你好运!