- 分步进行
- 内部实现细节
- AssemblyCode的C++DSL
- IR的组成
- 编译器子功能
可以把整个编译器的流程变成如下
获取输入->解析->编译成中间代码(此步骤检查引用等是否合规)->编译成目标语言
这个过程中,数据的变化走向:
SOURCE->AST->IR->TARGET
由于前几章已经把整个工具链的架构确定了,即主程序调用dll的函数,那么文件调用流程就是下面:
dogc.exe.main() -> compiler.dll.dogc_run(argc, argv) -> compiler.dll.Compiler::compile()
其中,Compiler调用主函数compile之前,需调用init初始化相关数据
即调用parser和pcd的解析函数,得到分别的类文档和源码ast
随后,compile函数结束之前,调用生成汇编代码的函数,把ir变成目标语言.
AssemblyCode的C++DSL为了日后方便,先把汇编的c++版DSL(领域专用语言)实现了.
举个例子,可以直接调用asm::xor(rax, rax)而不是手动写printf("xor rax, raxn");
分解对象:寄存器和内存引用.就是rax和DWORD [RAX+2]类似的
每个对象单独对外开放"字符串"接口,比如Register对象表示"rax"的时候,暴露一个str()公开方法,返回字符串"rax"
内存引用对象是一样的
把所有的中间代码变成两个层次:对象和语句.就是Object和Statement
前者可以参与运算,后者作为结果.
比如:a + b就是Object,而print(a+b);就是Statement,但print(a+b)是Object
每种对象类继承自Object基类;每种语句继承自IR基类.其中因为c++的特性不能根据基类的指针推断子类的类型,因此必须提供tp()接口,说明自己的类型,提供给后续处理的switch,判断应有的处理
即通过类文档生成相应的汇编目标文件.
处理流程:类声明->汇编代码(包括数据段:DCT,CMIT,OMT和代码段:OMAI通用脚本)
这些后续会详细介绍.因此,需要在解析命令行参数的时候就分辨出来哪种功能,然后调用相应的子函数(dogc_main())
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)