如何处理我正在编写的脚本语言中的标签?
所以我一直在纠结这个问题,思考了很长时间。首先是一个代码示例,然后我将对其进行解释。
:main
dostuff
otherlabel
:otherlabel
dostuff
好吧,在这个例子中,main 是代码开始的地方,它“调用”标签“otherlabel”。这实际上只是跳转命令的快捷方式,它将执行更改为内存中的不同位置。但我的问题是,如何处理这些标签,以便在调用它们之前不必声明它们?
目前,我正在进行单步编译,直接从源代码读取并输出字节码。我只是处理标签并在找到它们时将它们添加到字典中。然后我用跳转命令替换“otherlabel”到代码中的正确位置。但在这种情况下,代码无法编译。
我想了几种方法来做到这一点:
首先是在其他任何事情之前处理标签,但这要求我分两步完成所有事情,并且我必须处理相同的代码两次,这会减慢进程,并且看起来像是一个混乱。
其次是对标签调用进行排队,直到我浏览完整个文件并编译其他所有内容然后处理它们之后,这看起来更干净。
我用 C 写这个,所以我不想实现复杂的数据结构,我正在寻找最直接的方法来处理这个问题。
So I've been stewing over this for a long time, thinking about it. Here's a code example first, and then I'll explain it.
:main
dostuff
otherlabel
:otherlabel
dostuff
Alright so in this example, main is where the code starts, and it 'calls' the label 'otherlabel'. This is really just a shortcut for a jump command that changes execution to a different location in memory. My problem though is, how do I handle these labels so that they don't have to be declared before they are called?
At the moment, I'm doing a single step compilation reading straight from the source and outputting the bytecode. I am simply handling labels and adding them to a dictionary when I find them. And then I replace 'otherlabel' with a jump command to the correct location in code. But in this case that code wouldn't compile.
I've thought of a few ways to do this:
First is handling labels before anything else but this requires me to do everything in two steps and I have to deal with the same code twice, this slows down the process and just seems like a mess.
Second is queueing up the label calls until AFTER I've gone through the entire file and compiled everything else and then dealing with them, this seems much cleaner.
I'm writing this in C so I'd rather not implement complex data structures, I'm looking for the most straight forward way to handle this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用多遍。对于脚本语言来说,一次通过是不够的,尤其是当您遇到更复杂的结构时。
在编译之前的第一遍中,构建标签字典。
在稍后的编译过程中,只需使用该字典即可。
Use multiple passes. One pass isn't going to suffice for a scripting language, especially when you are getting to the more complex structures.
In a first pass, before compiling, construct your dictionary of labels.
In a later pass, when the compiling happens, just use that dictionary.
您可以使用“backpatching”,尽管听起来您已经尝试过了;它可以被解释为一个复杂的结构。
当您遇到对未定义标签的调用时,您会发出带有空白地址字段的跳转(可能进入缓冲区,否则如果您必须重新读取文件来修补它,这将与“多次传递”相同);并且您还将指向字典中“补丁”列表中的空白字段的指针存储起来。当您遇到标签定义时,请填写列表中的所有空白,然后正常继续。
You could use "backpatching", although it sounds like that's what you've tried already; and it could be consstrued as a complex structure.
When you encounter a call to an undefined label, you emit the jump with a blank address field (probably into a buffer, otherwise this becomes the same as "multipass" if you have to re-read the file to patch it); and you also store a pointer to the blank field in a "patch-up" list in the dictionary. When you encounter the label definition, you fill-in all the blanks in the list, and proceed normally.