├── .gitignore ├── CMakeLists.txt ├── Doxyfile.in ├── ReadMe.md ├── build.sh ├── doc ├── BNF.md ├── TODO.md ├── code link.mdj ├── lct.png ├── link.png ├── 与lisp的关系.md ├── 二进制元数据规范.md ├── 内置类型名称表 ├── 宏设计.md ├── 库的引用.md ├── 整体架构设计.md ├── 新版List构建约定 ├── 模块化程序设计.md ├── 测试用动态语言设计.md ├── 编译系统工作流程.png ├── 语法自扩展编译系统概要设计文档.md ├── 语法自扩展编译系统概要设计文档.pdf ├── 语法自扩展编译系统详细设计文档.md ├── 语法自扩展编译系统详细设计文档.pdf ├── 语言特性.md └── 预处理器设计.md ├── header_libs └── elegantlist │ ├── elegantlist.hpp │ └── eltest.cpp ├── includes ├── CodeGen.h ├── CodeGenContext.h ├── CodeGenFunction.h ├── ICodeGenContext.h ├── ICodeGenFunction.h ├── LLCG │ ├── llcg.h │ ├── llcg_l.h │ └── lvalue.h ├── MetaModel │ ├── FunctionModel.h │ ├── MacroModel.h │ ├── MapModel.h │ ├── MetaModel.h │ └── StructModel.h ├── Model │ ├── ByteNode.h │ ├── CharNode.h │ ├── FloatNode.h │ ├── IDNode.h │ ├── IntNode.h │ ├── Node.h │ ├── StringNode.h │ ├── TypeNode.h │ └── nodes.h ├── Pass.h ├── PassManager.h └── RedCodeGen.h ├── runtimeproj ├── CMakeLists.txt └── src │ └── runtime.cpp ├── src ├── CodeGenContext.cpp ├── CodeGenFunction.cpp ├── LLCG │ ├── LLVMLIB │ │ ├── llcg_llvm.cpp │ │ ├── llcg_llvm.h │ │ ├── llcg_llvm_l.cpp │ │ ├── llvm_libs.cpp │ │ ├── llvm_type.cpp │ │ ├── llvm_type.h │ │ ├── llvm_value.cpp │ │ └── llvm_value.h │ └── llcg.cpp ├── Macro │ ├── Classes.cpp │ ├── Functions.cpp │ └── Prescan.cpp ├── MacroTranslate.cpp ├── MacroTranslate.h ├── MetaModel │ ├── FunctionModel.cpp │ ├── MacroModel.cpp │ ├── MapModel.cpp │ ├── MetaModel.cpp │ └── StructModel.cpp ├── Model │ ├── ByteNode.cpp │ ├── CharNode.cpp │ ├── FloatNode.cpp │ ├── IDNode.cpp │ ├── IntNode.cpp │ ├── ModelCodeGen.cpp │ ├── Node.cpp │ ├── StringNode.cpp │ └── TypeNode.cpp ├── Pass.cpp ├── PassManager.cpp ├── RedCodeGen.cpp ├── Utils │ ├── StringEscape.cpp │ ├── StringEscape.h │ └── string_formatter.h ├── idmap.cpp ├── idmap.h ├── idtable.cpp ├── idtable.h ├── main.cpp ├── redapple_lex.l └── redapple_parser.y └── test1 ├── test.red ├── test2.red ├── test3.red ├── test4 ├── Makefile ├── test4.red └── test5.red ├── test5 ├── Makefile └── test5.red ├── test6 ├── Makefile └── test6.red ├── test7 ├── Makefile └── test7.red └── test8 ├── Makefile ├── declare.red └── test8.red /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /bin 3 | /Debug 4 | /Release 5 | *.*~ 6 | .fuse* 7 | *.user 8 | *.sublime-project 9 | *.sublime-workspace 10 | 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(RedApple) 3 | 4 | if(NOT BUILD_ALL) 5 | 6 | SET (CMAKE_BUILD_TYPE Debug) # 默认构建Debug模式 7 | set(LLVM_TARGETS_TO_BUILD X86) 8 | set(LLVM_BUILD_RUNTIME OFF) 9 | set(LLVM_BUILD_TOOLS OFF) 10 | 11 | find_package(LLVM 3.6 REQUIRED CONFIG) 12 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 13 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 14 | 15 | find_package(BISON) 16 | find_package(FLEX) 17 | 18 | SET (CMAKE_CXX_COMPILER_ENV_VAR "clang++") 19 | SET (CMAKE_CXX_FLAGS "-std=c++11") 20 | SET (CMAKE_CXX_FLAGS_DEBUG "-g") 21 | SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") 22 | SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG") 23 | SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") 24 | 25 | SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 26 | 27 | include_directories(${LLVM_INCLUDE_DIRS}) 28 | add_definitions(${LLVM_DEFINITIONS}) 29 | 30 | FLEX_TARGET(MyScanner ${CMAKE_CURRENT_SOURCE_DIR}/src/redapple_lex.l 31 | ${CMAKE_CURRENT_BINARY_DIR}/redapple_lex.cpp COMPILE_FLAGS -w) 32 | BISON_TARGET(MyParser ${CMAKE_CURRENT_SOURCE_DIR}/src/redapple_parser.y 33 | ${CMAKE_CURRENT_BINARY_DIR}/redapple_parser.cpp) 34 | ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser) 35 | 36 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 37 | 38 | endif() 39 | 40 | if(MSVC) 41 | #define llvm version 42 | if (${LLVM_PACKAGE_VERSION} LESS 3.7.0) 43 | set(CMAKE_CXX_FLAGS "/DLLVM_3_6") 44 | else() 45 | set(CMAKE_CXX_FLAGS "/DLLVM_3_7") 46 | endif() 47 | endif() 48 | 49 | 50 | 51 | # 核心路径配置 52 | include_directories(includes includes/Model includes/LLCG src src/Utils src/MetaModel src/cJSON 53 | src/LLCG/ src/LLCG/LLVMLIB header_libs/elegantlist) 54 | 55 | file(GLOB_RECURSE source_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp 56 | ${CMAKE_CURRENT_SOURCE_DIR}/src/Model/*.cpp 57 | ${CMAKE_CURRENT_SOURCE_DIR}/src/Macro/*.cpp 58 | ${CMAKE_CURRENT_SOURCE_DIR}/src/Utils/*.cpp 59 | ${CMAKE_CURRENT_SOURCE_DIR}/src/MetaModel/*.cpp 60 | ${CMAKE_CURRENT_SOURCE_DIR}/src/LLCG/*.cpp 61 | ${CMAKE_CURRENT_SOURCE_DIR}/src/LLCG/*/*.cpp 62 | ${CMAKE_CURRENT_SOURCE_DIR}/src/cJSON/*.c) 63 | list(REMOVE_ITEM source_files ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) 64 | 65 | if(USE_DYNAMIC) 66 | add_library(red SHARED ${source_files}) # 使用动态库 67 | install(TARGETS red RUNTIME DESTINATION bin) 68 | else() 69 | add_library(red STATIC ${source_files}) # 使用静态库 70 | install(TARGETS red ARCHIVE DESTINATION lib) 71 | endif() 72 | 73 | add_subdirectory(runtimeproj) 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | if(NOT BUILD_ALL) 83 | 84 | add_executable(redapple ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ${BISON_MyParser_OUTPUTS} ${FLEX_MyScanner_OUTPUTS}) 85 | 86 | install(TARGETS redapple RUNTIME DESTINATION bin) 87 | 88 | # Find the libraries that correspond to the LLVM components 89 | # that we wish to use 90 | llvm_map_components_to_libnames(llvm_libs 91 | support core irreader executionengine interpreter 92 | mc mcjit bitwriter x86codegen target) 93 | 94 | # Link against LLVM libraries 95 | target_link_libraries(redapple red ${llvm_libs}) 96 | 97 | endif() 98 | -------------------------------------------------------------------------------- /Doxyfile.in: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "@CMAKE_PROJECT_NAME@" 2 | PROJECT_NUMBER = @VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@ 3 | STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@ \ 4 | @PROJECT_BINARY_DIR@ 5 | INPUT = @doxy_main_page@ \ 6 | @PROJECT_SOURCE_DIR@ \ 7 | @PROJECT_BINARY_DIR@ 8 | FILE_PATTERNS = *.h \ 9 | *.c 10 | OUTPUT_LANGUAGE = Chinese 11 | RECURSIVE = YES 12 | EXTRACT_ALL = YES 13 | EXTRACT_PRIVATE = YES 14 | EXTRACT_STATIC = YES 15 | EXCLUDE_PATTERNS = */thirdparty/* 16 | USE_MDFILE_AS_MAINPAGE = @doxy_main_page@ 17 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | RedApple Programming language 2 | 3 | C++编写的一款简单的类C风格的编译语言 4 | 使用flex和bison制作的词法分析器和语法分析器 5 | 使用LLVM-3.6构建后端 6 | 使用CMake构建项目 7 | 8 | 9 | 目前支持的语法特性有: 10 | 11 | * 全局函数,无需声明 12 | * 简单的类型系统,支持int、float、double和结构体struct 13 | * 简化的指针,所有结构体变量声明的都是指针 14 | * 支持常量字符串 15 | * for while if 等逻辑控制语句 16 | * import 其他文件 17 | * meta元数据和反射调用 18 | * 用户自定义宏 19 | 20 | 示例代码: 21 | ``` 22 | void hello(int k, int g) { 23 | int y = k + g; 24 | printf("%d\n", y); 25 | if (k + g < 5) printf("right\n"); 26 | } 27 | 28 | 29 | void go(int k) { 30 | int a = 0; 31 | while (a < k) { 32 | printf("go-%d\n", a); 33 | a = a + 1; 34 | } 35 | } 36 | 37 | void print(int k) { 38 | for (int i = 0; i < 10; i = i+1) { 39 | printf("hello-%d\n",i); 40 | } 41 | } 42 | 43 | 44 | void main() { 45 | printf("hello world\n"); 46 | hello(1,2); 47 | print(9); 48 | } 49 | ``` 50 | 51 | 52 | 反射调用: 53 | ``` 54 | void print(int k) { 55 | printf("hello-%d\n",k); 56 | } 57 | 58 | void main() { 59 | FunctionCall("print", 5); 60 | } 61 | 62 | ``` 63 | 64 | 自定义宏的使用: 65 | ``` 66 | void print(int k) { 67 | @for_n (i, k) { 68 | printf("hello-%d\n", i); 69 | } 70 | } 71 | 72 | defmacro for_n (p, size, code) { 73 | for (int p = 1; p <= size; p = p+1) 74 | code; 75 | } 76 | 77 | 78 | void main() { 79 | FunctionCall("print", 5); 80 | } 81 | ``` 82 | 83 | [![Join the chat at https://gitter.im/elite-lang/RedApple](https://badges.gitter.im/elite-lang/RedApple.svg)](https://gitter.im/elite-lang/RedApple?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | mkdir ./build 2 | cd ./build 3 | cmake .. 4 | make 5 | 6 | -------------------------------------------------------------------------------- /doc/BNF.md: -------------------------------------------------------------------------------- 1 | 本语言是为了验证代码自动生成技术而设计出来的 2 | 核心的思路是尽可能多的用语法糖粘合S表达式 3 | 样式是一门类C的传统型语言 4 | 但加入了强大的元语言功能 5 | 运行时代码被编译成了具有链式数据结构 6 | 7 | 8 | 代码的底层结构一般是这样: 9 | ()[link.png] 10 | 11 | 代码是按照链表的形式组织在一起的 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/TODO.md: -------------------------------------------------------------------------------- 1 | TODO: 2 | 3 | 1. 宏系统 done 4 | 2. 浮点数的相关支持 done 5 | 3. 类型转换的相关支持 6 | 4. 运行时的内存管理接口 7 | 5. 更多的比较运算符(无符号数) 8 | 6. bool类型及位运算 9 | 7. 线程的相关绑定, 声明C接口, 为接口添加反射调用元数据 done 10 | 8. 装箱及拆箱 11 | 9. meta.bc中元数据的解析 12 | 10. 调用约定、链接属性和函数附加属性 13 | 11. meta数据的json型读取缓存 14 | 12. 多种版本的指针,普通指针、引用计数指针 15 | 13. 数组、结构体按数字索引选取 done 16 | 14. 类型定义 17 | 15. 锁机制及原子操作 18 | -------------------------------------------------------------------------------- /doc/lct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/doc/lct.png -------------------------------------------------------------------------------- /doc/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/doc/link.png -------------------------------------------------------------------------------- /doc/与lisp的关系.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | class AClass { 4 | public static void Layout() { 5 | 6 | } 7 | 8 | public void Scidme() { 9 | 10 | } 11 | 12 | int temp = 0; 13 | BClass child; 14 | } 15 | 16 | 17 | class: 18 | 1. class name 类名 19 | 2. class modifier 类修饰符 20 | 3. 声明语句列表 21 | 22 | (class name modifier statements) 23 | 24 | function: 25 | 1. function name 函数名 26 | 2. function return type 函数返回类型 27 | 3. function type list 函数参数列表 28 | 4. 语句列表 29 | 30 | (function name return types statements) 31 | 32 | -------------------------------------------------------------------------------- /doc/二进制元数据规范.md: -------------------------------------------------------------------------------- 1 | 二进制元数据规范 2 | 3 | 每个包编译后都带有一个 `包名_meta.bc` 的文件,这个文件就是当前包的元数据,这个文件是包整体编译后自动产生的。 4 | 里面包含有一个重要的函数:`包名_meta_init_func` 5 | 这个函数是一个不需要参数,也无返回值的函数,里面包含了初始化包元数据的全部代码,其实是对Runtime中函数的大量调用。 6 | 7 | 全部项目编译完成后,还会在项目最终目标目录,多生成一个初始化函数: `meta_init_func` 8 | 这个函数会添加对所有 `包名_meta_init_func`的调用,最终会在Runtime中的真实main函数中被调用 9 | 10 | 11 | 模块的链接 12 | 13 | 链接建议还是推迟到最后步骤吧,保持一个文件一个bc,这样没有用到的部分其实可以不链 14 | -------------------------------------------------------------------------------- /doc/内置类型名称表: -------------------------------------------------------------------------------- 1 | int 整形64位 2 | uint 无符号整形 3 | float 32位单精度浮点数 4 | double 64位双精度浮点数 5 | char 字符类型16位 unicode码 6 | byte 字节 8位 7 | -------------------------------------------------------------------------------- /doc/宏设计.md: -------------------------------------------------------------------------------- 1 | 宏的设计是考虑方便替换的原则, 而且需要多次替换 2 | 而宏的添加必须添加新的宏解析语法, 以及更多的一元运算符, 例如'`', ',', '@' 等 3 | 4 | defmacro class(name, father, list) { 5 | struct @name { 6 | ,@list 7 | class_meta p_this; 8 | @if_func(father p_super;) 9 | } 10 | } 11 | 12 | deffunc if_func(a, b) 13 | 14 | @表示 后面接的是一个宏表达式, ‘,@’ 则表示将该表达式展开并填入到该位置 15 | 16 | 另外一种编译时函数, 则是在用脚本的形式, 定义了翻译时的宏替换函数, 这个宏函数通过执行lua代码, 可以实现编译时的特殊功能, 甚至能够控制增加翻译趟数, 修改每一次翻译用的宏。 17 | 18 | 由于有了lua的扩展性,我们支持在程序内定义宏,实现简单的替换和展开,支持使用lua宏和lua函数,进行编译时的翻译扩展。更支持C++的宏扩展,提供最全的底层支持。 19 | 20 | 简化设计的考虑,不再自己实现脚本引擎,而全交由lua扩展实现。 -------------------------------------------------------------------------------- /doc/库的引用.md: -------------------------------------------------------------------------------- 1 | 这么语言有点特殊,它的目标代码不是虚拟机代码,而是系统真实的二进制文件,也就是我们常见的.o文件和.lib文件, 这样的库的引用, 会显得较为麻烦, 2 | 对于二进制基本的库,我们唯一的方法就是提供其定义头文件, 因为如果不这样做的话, 我们将很难获取其元数据信息. 3 | 4 | 而对于.bc文件, 可以考虑放入元数据信息 5 | 6 | 制作头文件自动生成器, 负责解析源数据, 然后自动转换成头文件 7 | 8 | 元数据引擎 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/整体架构设计.md: -------------------------------------------------------------------------------- 1 | 整个系统分为如下几个大块 2 | 3 | 1. 词法分析器 4 | 2. 语法分析器 5 | 3. 宏展开器 6 | 4. 宏翻译器 7 | 5. 后端代码生成 8 | 9 | -------------------------------------------------------------------------------- /doc/新版List构建约定: -------------------------------------------------------------------------------- 1 | List链表这个结构,用代码构建并不是十分容易 2 | 3 | 于是有了这样的约定,防止出现问题: 4 | 5 | 1. 每个BNF范式构建的链表都是以第一个元素开头,没有头节点,也没有父节点 6 | 2. 每个BNF范式在孩子的添加时,使用make_list函数和getList函数,这两个函数都会检查当前链表的长度,如果只有一个元素,则将其挂在对应位置,否则则添加一个Node节点,作为这个链的父亲。 7 | 3. 单纯想将一个链表接到一个链表的后面,需要使用addBrother函数 8 | -------------------------------------------------------------------------------- /doc/模块化程序设计.md: -------------------------------------------------------------------------------- 1 | 模块化程序设计 2 | 3 | module TM { 4 | in add(int a, int b) { 5 | 6 | } 7 | 8 | out ans(int) { 9 | 10 | } 11 | 12 | out do(int, int) { 13 | 14 | } 15 | 16 | void print() { 17 | 18 | } 19 | 20 | void send() { 21 | 22 | } 23 | 24 | public delegate void Notify(int value); //委托,函数指针 25 | 26 | public static void main() { 27 | int p; 28 | TM t = new TM(); 29 | t.ans((int x) -> p = x).add(10, 20); 30 | } 31 | } 32 | 33 | 一个模块相当于一个特殊的类 34 | 类似Java的实现 35 | in 和 out 是关键接口 36 | in 相当于传入参数 37 | out 相当于是传入一个回调函数 38 | 回调函数是非常关键的设计 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /doc/测试用动态语言设计.md: -------------------------------------------------------------------------------- 1 | 测试用动态语言设计 2 | ================= 3 | 4 | 希望能在底层构建C风格可进行自动代码生成的语言 5 | 符号是第一等公民,一切皆为符号,一切都是符号演算的过程,符号也可以看做对象 6 | 任意一个符号都是一个节点,都有自己的孩子和兄弟 7 | 例如: 8 | 9 | ```C 10 | function dowork() { 11 | init(); 12 | ... 13 | #work: do_something(); 14 | do_another_thing(); 15 | ... 16 | } 17 | 18 | function linux_dowork() { 19 | do_linux_work = dowork.copy() 20 | do_linux_work['work'] = do_linux_something; 21 | do_linux_work['work'] = do_linux_another_something; 22 | } 23 | ``` -------------------------------------------------------------------------------- /doc/编译系统工作流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/doc/编译系统工作流程.png -------------------------------------------------------------------------------- /doc/语法自扩展编译系统概要设计文档.md: -------------------------------------------------------------------------------- 1 | 语法自扩展编译系统概要设计文档 2 | =========================== 3 | 4 | 5 | ### 一、写作目的 6 | 7 | 文本是可扩展编译系统的整体设计介绍文档,简要介绍了系统的适用场景、基本功能、产品特色、整体架构等。适合开发人员阅读。 8 | 9 | ### 二、整体定位 10 | 11 | 本编译系统是一款通用编程平台,面向的是系统编程领域。适用于跨平台的系统组件开发,原生应用开发,引擎开发等。 12 | 系统编程领域,主要由C和C++占据,最近虽然也有Rust、Go等新型语言介入,但整体上开发不够灵活,组件化较差,而Java等平台,又重度依赖虚拟机的部署,调用底层库时效率较低,这款编译系统就是在用编译器技术,实现跨平台的系统编程,又能提供更为灵活的实现。 13 | 主要希望解决的是系统开发中的灵活性差的问题。 14 | 15 | ### 三、基本功能 16 | 17 | 一款通用编程语言,可以进行基本的过程式开发。 18 | 可扩展编译器,能够在编译时指定编译的语法。 19 | 脚本化编译语言,能够在编译时期执行特定脚本代码控制编译流程,可以在编译时进行代码展开。 20 | 可以在编译时打印元数据,可以动态注册语法,也就是说,可以将语法做成库的形式引入。 21 | 22 | ### 四、产品特色 23 | 24 | 可扩展性和脚本化是最大的特色。 25 | 可扩展性主要体现在编译器可以在库中增加语法,而无需变动编译器,所有的语法描述的程序,最后都会被翻译为统一的S表达式,而库在新增语法时,只需要增加对S表达式的宏替换翻译即可实现,非常的方便。而S表达式是Lisp语言的精化,而且这种函数式编程能够非常轻松的扩展语法,Lisp是用宏实现的,我们这里定义了更直观的宏翻译语法,来实现类似的功能。 26 | 脚本的编译器非常灵活,您可以在编译期间指定您要用的文法,然后将来识别文法,驱动编译,而编译过程是脚本驱动的,虽然编译速度可能不快,但非常的灵活,您可以自由的修改编译脚本,然后执行,编译器虽然是脚本驱动,但核心代码都是C++完成的,其脚本仅仅是用来驱动的接口,效率也还可以接受。 27 | 28 | ### 五、目标平台 29 | 30 | 各主流桌面平台X86架构,Arm架构等通过LLVM平台实现。 31 | 32 | ### 六、整体架构 33 | 34 | 整体来看,系统的工作流程如下: 35 | 36 | ![](lct.png) 37 | 38 | 本系统分为如下几个部分,一个部分对应编译过程中的一趟或几趟: 39 | 词法分析器 - 语法分析器 - 元脚本执行器(语义分析) - 中间代码生成及优化器 - 目标代码生成器 40 | 41 | 1. 词法分析器 42 | 使用手工打造的词法分析程序,采用等价类映射来支持Unicode字符集。 43 | 能够构建有限自动机来处理词法。 44 | 内置预处理器,引导元脚本的解析 45 | 46 | 2. 语法分析器 47 | 语法分析器在元脚本解析前就开始了,语法分析器是整个系统的核心,首先加载默认的文法文件,一个EBNF范式的描述文件,为了加速,会自动为其构建缓存,下次便不会再次解析。 48 | 49 | 3. 元脚本执行器 50 | 提供元脚本的概念,这是一种编译时脚本,利用其API,可以轻松地控制编译流程,而且可以在编译期间进行相关内容的显示与内容生成,例如根据源代码中的类生成对应类名列表,或者根据其中的注解生成新的代码等。这些功能在一些接口类的生成上,非常有用。 51 | 52 | 4. 中间代码生成及优化器 53 | 这部分主要是利用LLVM的API将我们解析出来的语法树,转换成为通用的LLVM中间代码,这个代码不但可以和其他Clang、Haskell等平台生成的目标代码混合编译,还能统一地被LLVM的JIT编译器翻译执行。这个中间代码是可以输出的,并且能够用来做跨平台的发布。 54 | 55 | 5. 目标代码生成器 56 | 这部分十分简单,利用LLVM的API便可以轻松将中间代码转换为可执行的本机Native代码。 57 | 58 | ### 七、接口设计 59 | 60 | #### 人机交互接口 61 | 62 | 采用命令行进行编译控制 63 | 64 | #### 外部接口 65 | 66 | 系统提供可执行程序,动态连接库,静态连接库等形式供外部调用。 67 | 本系统可以作为嵌入式脚本执行,提供C风格API供其他程序调用。 68 | 本系统可以作为Lua库调用,利用so库载入,接入其lua接口动态连接库。 69 | 70 | #### 内部接口 71 | 72 | 各趟之间是C++的接口连接,采用的是多态工厂类的方式进行实现。 73 | 74 | 75 | ### 八、性能要求 76 | 77 | 不要求编译速度很快,但要求整体项目编译速度较快。 78 | 主要思路是尽量避免重复劳动,虽然编译速度不一定很快,但很少进行重复编译和大段代码的拷贝,所以希望采取类似Java的整体分析编译的思路,将编译好的代码和其元数据打包在一起,让元数据很容易被读取。 79 | 80 | 编译后的代码要求运行高效,兼顾安全,尽量考虑使用原生汇编代码。避免嵌套虚拟机和复杂的内存管理机制。主要目标是高效的调用已有的C/C++函数库。 81 | 82 | ### 九、内存管理 83 | 84 | 使用LLVM原生的内存管理 85 | 暂时不使用垃圾回收机制,兼容C和C++的相互调用。 86 | 采用可选扩展垃圾回收器,后期扩展再开发。 87 | 88 | ### 十、设计原则和要求 89 | 90 | 1. 灵活优先,兼顾安全 91 | 首先保障一个系统能够实现该特性,其次保障这个特性少出问题。我希望提供尽可能多的方式来实现同样功能的代码,让开发人员可以选择对应的功能,而不是为了追求安全和效率,就不提供某些功能。 92 | 93 | 2. 重扩展性 94 | 即使一个功能目前没有,但一定保留能够实现它的手段。 95 | 96 | 3. 整体优化 97 | 不追求每个细节都十分完美和高效,但整体要保持平衡和容易让用户接受。 98 | 99 | 4. 最小化语言特性,最大化库扩展模型 100 | 库相比于语言,更容易扩展,所以这也是重扩展性的一种手段,尽量将语言本身做的小巧精致,而扩展能力更加。 101 | 102 | 5. 模块化编程 103 | 语言原生支持模块化编程,而不需要依赖任何构建系统,对组件的支持是重中之重。 104 | 105 | 6. 稳定性和可测试性 106 | 本编译系统需要重视编译过程的稳定性,对于类似的代码,能够进行同样流程的编译工作。 107 | 并且编译的每个pass都是可测试的,能够保障整个编译器稳定工作。对于超大超长源码也要能够支持。 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /doc/语法自扩展编译系统概要设计文档.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/doc/语法自扩展编译系统概要设计文档.pdf -------------------------------------------------------------------------------- /doc/语法自扩展编译系统详细设计文档.md: -------------------------------------------------------------------------------- 1 | 语法自扩展编译系统详细设计文档 2 | ======================== 3 | 4 | 5 | ### 一、写作目的 6 | 7 | 本文是可扩展编译系统的详细描述,主要介绍本编译系统的语言特性、设计特点、具体实现方法、各个组件基本功能、扩展接口设计等等。 8 | 9 | 本文适合本系统的开发人员阅读。 10 | 11 | ### 二、语言特性 12 | 13 | #### 1.跨平台 14 | 15 | 我们由于后端是采用LLVM支持的,带有跨平台的功能,而且既可以解释执行(自带JIT),也可以编译到对应平台。 16 | 目前我们使用的LLVM版本是3.6版,支持的主要平台为: 17 | 18 | * x86 19 | * amd64 20 | * ARM 21 | * PowerPC 22 | 23 | #### 2.语法的可扩展性 24 | 25 | 我们自行开发了一款脚本驱动的LALR语法分析器,这款语法分析器可以在运行中加载新的语法配置文件,生成新的分析表,然后对文法进行分析。可以在运行中通过接口控制,是这款语法分析器最大的特点,并且由于是使用lua作为其核心脚本引擎,lua的原生库也可以使用。其主要的扩展接口如下: 26 | 27 | * include 包含一个软件包 28 | * add_bnf 添加一条bnf范式 29 | * add_bnf_file 添加一个新的语法描述文件 30 | * load_default_bnf 加载默认的语法文件 31 | * load_empty_bnf 加载空的语法解析环境 32 | * parse_file 编译一个目标文件 33 | * print_bnf 打印当前bnf范式集合 34 | * print 打印一个编译时变量 35 | * 其他lua标准函数 36 | 37 | #### 3.设计支持的编程模型 38 | 39 | ##### 过程式编程 40 | 41 | 经典C风格程序,并且也可以调用其他C库函数。这部分原生支持函数的部分,但一些重要的部分也会拆到外部来实现。 42 | 43 | ##### 函数式编程 44 | 45 | 由lisp风格的函数调用实现,但暂时并不支持很多函数式特性,而是作为外部库和扩展语言特性来实现。 46 | 47 | ##### 面向对象编程 48 | 49 | 对象模型并不是内置的,而是几乎全部由扩展来实现,我们会实现一个对象模型作为其标准库的一部分,而这部分也像上两部分一样,是可以重开发和允许用户自行扩展的。 50 | 51 | ##### 模块管道式模型 52 | 53 | 增强版面向对象模型,在对象的层次上新增了管道式接口,用来处理一个对象的全部异步数据传入传出请求,方便并行化程序的编写。 54 | 55 | ##### 其他编程模型 56 | 57 | 尽量实现成库的形式,让语法自动扩展 58 | 59 | #### 4.基础语言元素 60 | 61 | ##### 表 62 | 63 | 这是仿Lisp的表结构,是唯一的元语言类型,所有的代码,在语法解析后,都会被翻译成元表。例如如下的翻译: 64 | 65 | ```java 66 | 67 | class Main { 68 | 69 | static void hello(int k, int g) { 70 | print("hello world"); 71 | } 72 | 73 | static void main() { 74 | hello(1,2); 75 | } 76 | 77 | } 78 | ``` 79 | 80 | 翻译后: 81 | 82 | ``` 83 | Node 84 | (String class 85 | String Main 86 | Node 87 | (Node 88 | (String function 89 | String void 90 | String hello 91 | Node 92 | (Node 93 | (String set 94 | String int 95 | String k) 96 | 97 | Node 98 | (String set 99 | String int 100 | String g) 101 | ) 102 | 103 | Node 104 | (Node 105 | (Node 106 | (String call 107 | String print 108 | String hello world))) 109 | Node 110 | (String static) 111 | 112 | Node 113 | (String function 114 | String void 115 | String main 116 | Node ()d 117 | Node 118 | (Node 119 | (Node 120 | (String hello 121 | Int 1 122 | Int 2))) 123 | 124 | Node 125 | (String static) 126 | ) 127 | ) 128 | ``` 129 | 130 | 表也能单独的被程序识别,是基础元编程的重要部分。 131 | 132 | ##### 宏 133 | 134 | 宏是编译时的函数,所有的描述符都是宏,例如上面例子中的:class, function 等等,均是宏。 135 | 宏是翻译的规则,将对应格式的内容填充到宏函数中。 136 | 137 | 不是宏的部分,直接作为元数据直接向下传递 138 | 函数调用要翻译为call宏 139 | 140 | 宏的C定义方式是,写一个编译器插件的so,然后编写一条函数,形式如下: 141 | 142 | ```C 143 | Value* MacroDemo(Content* list); 144 | ``` 145 | 146 | 然后调用接口将这个函数指针注册即可。 147 | C实现的宏就是在解析这个语法树,完成基础的翻译工作,将Content*包含的语法树翻译成LLVM指定的组件形式,最后拼接在一起。 148 | 同时,为了解析一个语法树,有时需要调用其他的宏,解析其内部节点,这时会由系统递归地先完成内部节点的翻译,然后最后再翻译这条。 149 | 150 | 151 | 例如,我们在矩阵运算时,频繁使用了双重for语句,假若我们可以自定义一个宏,能够展开成如下双重for语句: 152 | 153 | ```C 154 | for (int i = 0; i < 10; ++i) { 155 | for (int j = 0; j < 10; ++j) { 156 | // do some work 157 | } 158 | } 159 | ``` 160 | 161 | 对应的宏语句如下设计: 162 | 163 | ```C 164 | for_matirx (i, j, 0, 10) { 165 | // do some work 166 | } 167 | ``` 168 | 169 | 其宏定义部分是这样的: 170 | 171 | ```C 172 | defmacro for_matirx (list, code) { 173 | for (int list[0] = list[2]; list[0] < list[3]; ++list[0]) 174 | for (int list[1] = list[2]; list[1] < list[3]; ++list[1]) 175 | code 176 | } 177 | ``` 178 | 179 | 180 | #### 5.基本语法 181 | 182 | 语法都是EBNF决定的,只要能将良好表示的类C风格代码,转换为S表达式的正确格式,就完成了语法解析的基本任务。 183 | 184 | 直接书写S表达式 185 | name () [] {} 186 | 187 | -------------------------------------------------------------------------------- /doc/语法自扩展编译系统详细设计文档.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/doc/语法自扩展编译系统详细设计文档.pdf -------------------------------------------------------------------------------- /doc/语言特性.md: -------------------------------------------------------------------------------- 1 | 2 | 语言定位 3 | 适用系统级编程,具有高效率。 4 | 解决系统开发中的灵活性差、安全性差等问题。 5 | 具有模块化编程的特性,管道式处理,方便异步编程。 6 | 7 | 语言特性描述 8 | 9 | 1. 强类型 10 | 十分必要,必须在编译时指定各个变量的类型,当然,也提供自动类型推断和弱类型,提供模板。 11 | 12 | 2. 跨平台 13 | 采用最小化虚拟机模式,虚拟机提供的功能非常有限,只有最少的功能,和连接的C库的必要特性,其他通过扩展C库实现,也就是可扩展虚拟机模型。Jit也通过C库扩展实现。 14 | 但初步开发先使用LLVM进行跨平台编译。 15 | 16 | 3. 模块化编程 17 | 提出编程模型,模块。 18 | 一个模块是一个类似类的结构,但其有in接口和out接口,in接口是一个函数,可以被主动调用。out接口是一个接受参数为声明类型函数指针的函数。 19 | 可以向out接口传入一个函数指针,然后这个函数就会被自动调用。 20 | out接口可以传入多个函数指针。 21 | 双向接口inout,可以传入多个函数指针,但函数被调用后必须返回具有其类型的返回值。 22 | 23 | 4. 内存管理 24 | 使用LLVM原生的内存管理 25 | 暂时不使用垃圾回收机制,兼容C和C++的相互调用。 26 | 27 | 5. 最小化语言特性,最大化库扩展模型 28 | 可扩展解析器模式,将解析得到的结果,转换成类似lisp的树状结构 29 | 并且支持直接书写lisp模式的代码。 30 | 31 | 6. 完全面向对象 32 | 不提供独立的函数,采用面向对象的方式构建代码 33 | 34 | 7. 支持使用各类依赖控制软件 35 | 可以使用makefile等进行项目构建 36 | 也可以使用自带的构建系统 37 | -------------------------------------------------------------------------------- /doc/预处理器设计.md: -------------------------------------------------------------------------------- 1 | 预处理器设计 2 | ============ 3 | 4 | 5 | Elite中的预处理器是lua脚本运行的核心,会在最早读入文件前进行处理,自动将源文件处理成lua脚本进行执行(或者逐行解释)。 6 | 7 | 预处理能够很好的整理源代码,起到类似宏的功能。 8 | 9 | 支持一些很重要的格式化代码的功能,可以更加方便的利用模板进行代码生成操作。这点稍稍有点像php。 10 | 但设计上,比php语法更加简单。 11 | 12 | 例如: 13 | 14 | ```lua 15 | # local v = 1 16 | # function gen() 17 | # ... 18 | # end 19 | # translate = true 20 | 21 | void hello_$v () { 22 | $gen() 23 | } 24 | 25 | ``` 26 | 27 | ## 和用户宏交互 28 | 29 | 该预处理器的另一个主要设计则是要和 30 | -------------------------------------------------------------------------------- /header_libs/elegantlist/elegantlist.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEGANT_LIST_H 2 | #define ELEGANT_LIST_H 3 | 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class ElegantList { 11 | public: 12 | ElegantList() : os(std::cout) {} 13 | ElegantList(ostream& out_stream) : os(out_stream) {} 14 | 15 | void print(const string& data) { 16 | if (data == "(") { 17 | os << endl; 18 | ++level; 19 | printTab(); 20 | } 21 | os << data << ' '; 22 | if (data == ")") { 23 | --level; 24 | } 25 | } 26 | private: 27 | void printTab() { 28 | for (int i = 1; i < level; ++i) 29 | os << " "; 30 | } 31 | ostream& os; 32 | int level; 33 | }; 34 | 35 | 36 | 37 | #endif /* end of include guard: ELEGANT_LIST_H */ 38 | -------------------------------------------------------------------------------- /header_libs/elegantlist/eltest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "elegantlist.hpp" 3 | 4 | ElegantList el; 5 | 6 | int main() { 7 | 8 | el.print("("); 9 | el.print("function"); 10 | el.print("hello"); 11 | el.print("("); 12 | el.print("set"); 13 | el.print("int"); 14 | el.print("var"); 15 | el.print(")"); 16 | el.print("("); 17 | el.print("("); 18 | el.print("set"); 19 | el.print("int"); 20 | el.print("x"); 21 | el.print(")"); 22 | el.print("("); 23 | el.print("return"); 24 | el.print("0"); 25 | el.print(")"); 26 | el.print(")"); 27 | el.print(")"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /includes/CodeGen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-11 13:57:49 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 16:56:32 6 | */ 7 | 8 | 9 | #ifndef CODE_GEN_H 10 | #define CODE_GEN_H 11 | 12 | #include 13 | 14 | class Node; 15 | 16 | 17 | /** 18 | * @brief 代码生成器的接口类 19 | * @details 代码生成器的接口 20 | * 使用RedApple后端代码生成器时,核心功能可以通过该接口调用 21 | * 首先调用Init初始化该生成器, 之后对全部定义头文件进行Prescan 22 | * 接着对每一个要编译的目标文件调用Make, 23 | * 最后调用MakeMeta 24 | */ 25 | class CodeGen 26 | { 27 | public: 28 | virtual void Init() = 0; 29 | virtual void PreScan(Node* node) = 0; 30 | virtual void PreScan(std::set& nodes) = 0; 31 | virtual void Make(Node* node, const char* outfile_name, const char* module_name = "") = 0; 32 | virtual void MakeMeta(const char* outfile_name, const char* module_name = "") = 0; 33 | }; 34 | 35 | #endif // CODE_GEN_H 36 | -------------------------------------------------------------------------------- /includes/CodeGenContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-10 18:44:44 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-26 15:10:36 6 | * 7 | * 代码生成的上下文类, 是C实现宏的最核心功能类 8 | */ 9 | 10 | #ifndef CODE_GEN_CONTENT_H 11 | #define CODE_GEN_CONTENT_H 12 | 13 | #include "ICodeGenContext.h" 14 | 15 | 16 | /** 17 | * @brief 代码生成上下文, 是代码生成中的关键信息存储类 18 | * @details 存储最关键的数据, 例如符号栈, LLVM生成器对象. 19 | * 在宏翻译过程中, 该上下文指针将会传入翻译函数中.\n 20 | * 该上下文在编译器中, 同一时刻应该仅存在一份, 21 | * 生存周期为一个包的编译开始到包内全部代码翻译完毕.\n 22 | * 切换上下文时, 相当于清空符号栈, 释放资源, 重启LLVM后端 23 | * 会导致之前分析的符号全部消失 24 | */ 25 | class CodeGenContext : public ICodeGenContext 26 | { 27 | public: 28 | CodeGenContext(); 29 | virtual ~CodeGenContext(); 30 | 31 | void Init(); 32 | 33 | /** 34 | * @brief 这个函数是用来一条条翻译Node宏的 35 | * @details 这个函数是用来一条条翻译Node宏的 36 | * 37 | * @param node 要翻译的语法节点 38 | * @return 翻译后的后端变量,往往是一个表达式或一个语句返回的值 39 | */ 40 | virtual LValue MacroMake(Node* node); 41 | 42 | 43 | // 获取当前模块中已注册的函数 44 | virtual LValue getFunction(Node* node); 45 | virtual LValue getFunction(const std::string& name); 46 | 47 | 48 | // 用户宏的查找与声明设置 49 | virtual shared_ptr getUserMacro(const std::string& name); 50 | virtual void setUserMacro(const std::string& name, Node* node); 51 | 52 | virtual shared_ptr getFunctionModel(const std::string& name); 53 | virtual shared_ptr getStructModel(const std::string& name); 54 | 55 | // 类型的定义和查找 56 | virtual void DefType(string name, LValue t); 57 | virtual LValue FindType(const string& name); 58 | virtual LValue FindType(Node*); 59 | virtual LValue FindSrcType(const string& name); 60 | virtual LValue FindSrcType(Node*); 61 | 62 | /** 63 | * @brief 定义一个变量 有可能是全局变量 64 | * 65 | * @param name 变量名 66 | * @param addr 存储地址 67 | */ 68 | virtual void DefVar(const string& name, LValue addr); 69 | 70 | /** 71 | * @brief 在符号表中查找一个变量 72 | * 73 | * @param name 变量名 74 | * @return 变量的存储地址 75 | */ 76 | virtual LValue FindVar(const string& name); 77 | 78 | virtual bool isSave() { return _save; } 79 | virtual void setIsSave(bool save) { _save = save; } 80 | 81 | virtual id* FindST(Node* node) const; 82 | virtual id* FindST(const string& str) const; 83 | IDTable* st; 84 | 85 | /** 86 | * @brief 获取低层次代码生成器,目前只有llvm 87 | * @return 生成器指针 88 | */ 89 | virtual llcg* getLLCG() { return codeGenerator; } 90 | 91 | virtual void setNowPass(Pass* pass) { 92 | now_pass = pass; 93 | } 94 | 95 | virtual Pass* getNowPass() { 96 | return now_pass; 97 | } 98 | 99 | virtual PassManager* getPassManager() { 100 | return pm; 101 | } 102 | 103 | virtual void setPassManager(PassManager* pm) { 104 | this->pm = pm; 105 | } 106 | 107 | private: 108 | 109 | llcg* codeGenerator; 110 | 111 | Pass* now_pass; 112 | PassManager* pm; 113 | 114 | void setNormalType(); 115 | 116 | /** 117 | * 用来记录当前是读取还是存入状态 118 | */ 119 | bool _save; 120 | }; 121 | 122 | 123 | #endif // CODE_GEN_CONTENT_H 124 | -------------------------------------------------------------------------------- /includes/CodeGenFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-12-19 10:43:27 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:10:10 6 | */ 7 | 8 | 9 | #ifndef CODE_GEN_FUNCTION_H 10 | #define CODE_GEN_FUNCTION_H 11 | 12 | 13 | #include "ICodeGenFunction.h" 14 | 15 | /** 16 | * @brief 定义宏翻译函数指针 17 | */ 18 | typedef LValue (*CodeGenCFunction)(CodeGenContext*, Node*); 19 | 20 | class CodeGenFunction : public ICodeGenFunction 21 | { 22 | public: 23 | CodeGenFunction(); 24 | CodeGenFunction(CodeGenCFunction _cfunc); 25 | const CodeGenFunction& operator=(const CodeGenFunction& obj); 26 | const CodeGenFunction& operator=(CodeGenCFunction _cfunc); 27 | 28 | virtual LValue call(CodeGenContext*, Node*); 29 | CodeGenCFunction getCFunc(); 30 | 31 | private: 32 | CodeGenCFunction cfunc; 33 | }; 34 | 35 | /** 36 | * @brief 宏翻译函数注册结构体 37 | * @details name 为宏名, func 为函数指针 38 | */ 39 | typedef struct _funcReg 40 | { 41 | const char* name; 42 | CodeGenCFunction func; 43 | } FuncReg; 44 | 45 | 46 | 47 | #endif // CODE_GEN_FUNCTION_H 48 | -------------------------------------------------------------------------------- /includes/ICodeGenContext.h: -------------------------------------------------------------------------------- 1 | #ifndef ICODE_GEN_CONTEXT_H 2 | #define ICODE_GEN_CONTEXT_H 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include "LLCG/llcg.h" 10 | #include "MetaModel/StructModel.h" 11 | #include "MetaModel/FunctionModel.h" 12 | #include "MetaModel/MacroModel.h" 13 | #include "CodeGenFunction.h" 14 | 15 | class Node; 16 | class Pass; 17 | class PassManager; 18 | class IDTable; 19 | struct id; 20 | 21 | class ICodeGenContext 22 | { 23 | public: 24 | 25 | /** 26 | * @brief 这个函数是用来一条条翻译Node宏的 27 | * @details 这个函数是用来一条条翻译Node宏的 28 | * 29 | * @param node 要翻译的语法节点 30 | * @return 翻译后的后端变量,往往是一个表达式或一个语句返回的值 31 | */ 32 | virtual LValue MacroMake(Node* node) = 0; 33 | 34 | 35 | // 获取当前模块中已注册的函数 36 | virtual LValue getFunction(Node* node) = 0; 37 | virtual LValue getFunction(const std::string& name) = 0; 38 | 39 | 40 | // 用户宏的查找与声明设置 41 | virtual shared_ptr getUserMacro(const std::string& name) = 0; 42 | virtual void setUserMacro(const std::string& name, Node* node) = 0; 43 | 44 | virtual shared_ptr getFunctionModel(const std::string& name) = 0; 45 | virtual shared_ptr getStructModel(const std::string& name) = 0; 46 | 47 | 48 | // 类型的定义和查找 49 | virtual void DefType(string name, LValue t) = 0; 50 | virtual LValue FindType(const string& name) = 0; 51 | virtual LValue FindType(Node*) = 0; 52 | virtual LValue FindSrcType(const string& name) = 0; 53 | virtual LValue FindSrcType(Node*) = 0; 54 | 55 | /** 56 | * @brief 定义一个变量 有可能是全局变量 57 | * 58 | * @param name 变量名 59 | * @param addr 存储地址 60 | */ 61 | virtual void DefVar(const string& name, LValue addr) = 0; 62 | 63 | /** 64 | * @brief 在符号表中查找一个变量 65 | * 66 | * @param name 变量名 67 | * @return 变量的存储地址 68 | */ 69 | virtual LValue FindVar(const string& name) = 0; 70 | 71 | 72 | virtual bool isSave() = 0; 73 | virtual void setIsSave(bool save) = 0; 74 | 75 | virtual id* FindST(Node* node) const = 0; 76 | virtual id* FindST(const string& str) const = 0; 77 | 78 | /** 79 | * @brief 获取低层次代码生成器,目前只有llvm 80 | * @return 生成器指针 81 | */ 82 | virtual llcg* getLLCG() = 0; 83 | 84 | virtual void setNowPass(Pass* pass) = 0; 85 | 86 | virtual Pass* getNowPass() = 0; 87 | 88 | virtual PassManager* getPassManager() = 0; 89 | }; 90 | 91 | 92 | #endif /* end of include guard: ICODE_GEN_CONTEXT_H */ 93 | -------------------------------------------------------------------------------- /includes/ICodeGenFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-12-24 08:56:30 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 08:58:15 6 | */ 7 | 8 | #ifndef I_CODE_GEN_FUNCTION_H 9 | #define I_CODE_GEN_FUNCTION_H 10 | 11 | #include "Model/Node.h" 12 | #include "LLCG/llcg.h" 13 | class CodeGenContext; 14 | 15 | class ICodeGenFunction 16 | { 17 | public: 18 | virtual LValue call(CodeGenContext*, Node*) = 0; 19 | }; 20 | 21 | 22 | #endif // I_CODE_GEN_FUNCTION_H 23 | -------------------------------------------------------------------------------- /includes/LLCG/llcg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 10:53:22 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 17:15:54 6 | */ 7 | 8 | #ifndef LLCG_H 9 | #define LLCG_H 10 | 11 | #include "LLCG/lvalue.h" 12 | 13 | #include "MetaModel/FunctionModel.h" 14 | #include "MetaModel/StructModel.h" 15 | 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | 22 | /** 23 | * @brief 核心接口类 底层代码生成器 Low-Level Code Generator 24 | * 整个底层的聚合接口 25 | */ 26 | class llcg 27 | { 28 | public: 29 | virtual LValue FuncType(FunctionModel* fmodel) = 0; // 返回FunctionType 30 | virtual LValue FuncType(LValue ret_type, vector& types, bool isNotSure = false) = 0; 31 | virtual LValue GetOrInsertFunction(FunctionModel* fmodel) = 0; // 返回Function 32 | virtual LValue GetOrInsertFunction(const string& name, LValue func_type) = 0; 33 | virtual LValue GetOrInsertFunction(const string& name, LValue ret_type, vector& types, bool isNotSure = false) = 0; 34 | virtual void FunctionBodyBegin(LValue func, vector& name_list) = 0; // 设置当前BasicBlock 35 | virtual void FunctionBodyEnd() = 0; // 处理函数结束 36 | virtual LValue getFunction(const string& name) = 0; // 从当前模块中获取一个函数 37 | virtual LValue Call(FunctionModel* fmodel, vector& args) = 0; // 返回CallInst 38 | virtual LValue Call(LValue func, vector& args) = 0; 39 | virtual LValue Struct(StructModel* smodel) = 0; // 返回StructType 40 | virtual LValue Struct(LValue _struct, vector& types) = 0; 41 | virtual LValue DeclareStruct(const string& name) = 0; 42 | virtual LValue DefVar(LValue var_type, const string& name) = 0; // 返回分配的地址 43 | virtual LValue DefVar(LValue var_type, const string& name, LValue init) = 0; 44 | virtual LValue DefGlobalVar(LValue var_type, const string& name) = 0; 45 | virtual LValue DefGlobalVar(LValue var_type, const string& name, LValue init) = 0; 46 | virtual LValue Load(LValue var_addr) = 0; 47 | virtual LValue Store(LValue var_addr, LValue value) = 0; 48 | virtual LValue Opt1(const string& opt, LValue value) = 0; 49 | virtual LValue Opt2(const string& opt, LValue value1, LValue value2) = 0; 50 | virtual LValue Cmp(const string& opt, LValue value1, LValue value2) = 0; 51 | virtual LValue Assignment(const string& opt, LValue value1, LValue value2) = 0; 52 | virtual LValue Dot(LValue value, int num) = 0; 53 | virtual LValue Select(LValue value, vector& args) = 0; 54 | virtual void If(LValue cond, LValue father, LValue true_block, LValue true_block_end, 55 | LValue false_block, LValue false_block_end, bool isElseWork) = 0; 56 | virtual void For(LValue cond, LValue init, LValue pd, LValue work, LValue statement, LValue statement_end, LValue end) = 0; 57 | virtual void While(LValue cond, LValue father, LValue pd, LValue statement, LValue statement_end, LValue end) = 0; 58 | virtual void DoWhile(LValue statement, LValue pd) = 0; 59 | virtual void DoUntil(LValue statement, LValue pd) = 0; 60 | virtual void Goto(LValue target) = 0; 61 | virtual LValue New(LValue var_type, vector& args, const string& funcname = "") = 0; 62 | virtual LValue NewArray(LValue var_type, vector& wd, const string& funcname = "") = 0; 63 | virtual LValue Delete(LValue pointer, const string& funcname = "") = 0; 64 | virtual LValue DeleteArray(LValue pointer, const string& funcname = "") = 0; 65 | virtual LValue Return() = 0; 66 | virtual LValue Return(LValue var) = 0; 67 | 68 | virtual LValue Int8() = 0; 69 | virtual LValue Int16() = 0; 70 | virtual LValue Int32() = 0; 71 | virtual LValue Int64() = 0; 72 | virtual LValue Float() = 0; 73 | virtual LValue Double() = 0; 74 | virtual LValue Void() = 0; 75 | 76 | virtual LValue ConstString(const string& str) = 0; 77 | virtual LValue ConstInt(int num) = 0; 78 | virtual LValue ConstDouble(double num) = 0; 79 | 80 | virtual void BeginModule(const string& name) = 0; 81 | virtual void VerifyAndWrite(const string& outfile_name) = 0; 82 | virtual void MakeMetaModule(const string& outfile_name, const string& module_name) = 0; 83 | 84 | virtual LValue GetNowBasicBlock() = 0; 85 | virtual LValue CreateBasicBlock() = 0; 86 | virtual LValue CreateBasicBlock(LValue func) = 0; 87 | 88 | virtual void MakeMetaList(vector& list) = 0; 89 | virtual void MakeMetaList(const string& name, vector& list, LValue fp) = 0; 90 | virtual void CloseTerminator(LValue basicblock, LValue target) = 0; 91 | virtual void SetNowBasicBlock(LValue nowBlock) = 0; 92 | static llcg* CreateLLVM(); 93 | 94 | }; 95 | 96 | 97 | #endif // LLCG_H 98 | -------------------------------------------------------------------------------- /includes/LLCG/llcg_l.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-12-19 10:15:48 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 17:16:05 6 | */ 7 | #ifndef LLVG_L_H 8 | #define LLVG_L_H 9 | 10 | 11 | #include "LLCG/lvalue.h" 12 | 13 | #include "MetaModel/FunctionModel.h" 14 | #include "MetaModel/StructModel.h" 15 | 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | 22 | /** 23 | * @brief 核心接口类 底层代码生成器 Low-Level Code Generator 24 | * 整个底层的聚合接口 25 | */ 26 | class llcg_l 27 | { 28 | public: 29 | virtual lvalue* l_FuncType(FunctionModel* fmodel) = 0; // 返回FunctionType 30 | virtual lvalue* l_FuncType(lvalue* ret_type, vector& types, bool isNotSure = false) = 0; 31 | virtual lvalue* l_GetOrInsertFunction(FunctionModel* fmodel) = 0; // 返回Function 32 | virtual lvalue* l_GetOrInsertFunction(const string& name, lvalue* func_type) = 0; 33 | virtual lvalue* l_GetOrInsertFunction(const string& name, lvalue* ret_type, vector& types, bool isNotSure = false) = 0; 34 | virtual void l_FunctionBodyBegin(lvalue* func, vector& name_list) = 0; // 设置当前BasicBlock 35 | virtual void l_FunctionBodyEnd() = 0; // 处理函数结束 36 | virtual lvalue* l_getFunction(const string& name) = 0; // 从当前模块中获取一个函数 37 | virtual lvalue* l_Call(FunctionModel* fmodel, vector& args) = 0; // 返回CallInst 38 | virtual lvalue* l_Call(lvalue* func, vector& args) = 0; 39 | virtual lvalue* l_Struct(StructModel* smodel) = 0; // 返回StructType 40 | virtual lvalue* l_Struct(lvalue* _struct, vector& types) = 0; 41 | virtual lvalue* l_DeclareStruct(const string& name) = 0; 42 | virtual lvalue* l_DefVar(lvalue* var_type, const string& name) = 0; // 返回分配的地址 43 | virtual lvalue* l_DefVar(lvalue* var_type, const string& name, lvalue* init) = 0; 44 | virtual lvalue* l_DefGlobalVar(lvalue* var_type, const string& name) = 0; 45 | virtual lvalue* l_DefGlobalVar(lvalue* var_type, const string& name, lvalue* init) = 0; 46 | virtual lvalue* l_Load(lvalue* var_addr) = 0; 47 | virtual lvalue* l_Store(lvalue* var_addr, lvalue* value) = 0; 48 | virtual lvalue* l_Opt1(const string& opt, lvalue* value) = 0; 49 | virtual lvalue* l_Opt2(const string& opt, lvalue* value1, lvalue* value2) = 0; 50 | virtual lvalue* l_Cmp(const string& opt, lvalue* value1, lvalue* value2) = 0; 51 | virtual lvalue* l_Assignment(const string& opt, lvalue* value1, lvalue* value2) = 0; 52 | virtual lvalue* l_Dot(lvalue* value, int num) = 0; 53 | virtual lvalue* l_Select(lvalue* value, vector& args) = 0; 54 | virtual void l_If(lvalue* cond, lvalue* father, lvalue* true_block, lvalue* true_block_end, 55 | lvalue* false_block, lvalue* false_block_end, bool isElseWork) = 0; 56 | virtual void l_For(lvalue* cond, lvalue* init, lvalue* pd, lvalue* work, lvalue* statement, lvalue* statement_end, lvalue* end) = 0; 57 | virtual void l_While(lvalue* cond, lvalue* father, lvalue* pd, lvalue* statement, lvalue* statement_end, lvalue* end) = 0; 58 | virtual void l_DoWhile(lvalue* statement, lvalue* pd) = 0; 59 | virtual void l_DoUntil(lvalue* statement, lvalue* pd) = 0; 60 | virtual lvalue* l_New(lvalue* var_type, vector& args, const string& funcname = "") = 0; 61 | virtual lvalue* l_NewArray(lvalue* var_type, vector& wd, const string& funcname = "") = 0; 62 | virtual lvalue* l_Delete(lvalue* pointer, const string& funcname = "") = 0; 63 | virtual lvalue* l_DeleteArray(lvalue* pointer, const string& funcname = "") = 0; 64 | virtual lvalue* l_Return() = 0; 65 | virtual lvalue* l_Return(lvalue* var) = 0; 66 | 67 | virtual lvalue* l_Int8() = 0; 68 | virtual lvalue* l_Int16() = 0; 69 | virtual lvalue* l_Int32() = 0; 70 | virtual lvalue* l_Int64() = 0; 71 | virtual lvalue* l_Float() = 0; 72 | virtual lvalue* l_Double() = 0; 73 | virtual lvalue* l_Void() = 0; 74 | 75 | virtual lvalue* l_ConstString(const string& str) = 0; 76 | virtual lvalue* l_ConstInt(int num) = 0; 77 | virtual lvalue* l_ConstDouble(double num) = 0; 78 | 79 | virtual void l_BeginModule(const string& name) = 0; 80 | virtual void l_VerifyAndWrite(const string& outfile_name) = 0; 81 | virtual void l_MakeMetaModule(const string& outfile_name, const string& module_name) = 0; 82 | 83 | virtual lvalue* l_GetNowBasicBlock() = 0; 84 | virtual lvalue* l_CreateBasicBlock() = 0; 85 | virtual lvalue* l_CreateBasicBlock(lvalue* func) = 0; 86 | 87 | virtual void l_MakeMetaList(vector& list) = 0; 88 | virtual void l_MakeMetaList(const string& name, vector& list, lvalue* fp) = 0; 89 | virtual void l_CloseTerminator(lvalue* basicblock, lvalue* target) = 0; 90 | 91 | }; 92 | 93 | 94 | 95 | 96 | 97 | #endif // LLVG_L_H 98 | -------------------------------------------------------------------------------- /includes/LLCG/lvalue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 10:54:27 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-18 23:05:26 6 | */ 7 | 8 | 9 | #ifndef LVALUE_H 10 | #define LVALUE_H 11 | 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | class lvalue; 18 | typedef shared_ptr LValue; 19 | 20 | /** 21 | * @brief 代替LLVM中Value的类,可供返回部分自定义数据,例如整数有无符号等信息 22 | */ 23 | class lvalue 24 | { 25 | public: 26 | virtual bool isStructType() { 27 | return false; 28 | } 29 | 30 | // 当前为值时,获取当前的类型 31 | virtual LValue getType() { 32 | return NULL; 33 | } 34 | 35 | // 当前为值或类型,都能获得对应的名称 36 | virtual string getTypeName() { 37 | return ""; 38 | } 39 | 40 | // 当前为类型时, 返回一个新的指针类型 41 | virtual LValue getPointerTo() { 42 | return NULL; 43 | } 44 | 45 | }; 46 | 47 | 48 | 49 | #endif // LVALUE_H 50 | -------------------------------------------------------------------------------- /includes/MetaModel/FunctionModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-13 12:07:03 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 17:16:42 6 | */ 7 | 8 | 9 | #ifndef FUNCTION_MODEL_H 10 | #define FUNCTION_MODEL_H 11 | 12 | #include "MetaModel.h" 13 | #include 14 | #include 15 | 16 | /** 17 | * @brief 函数模型元类型 18 | */ 19 | class FunctionModel : public MetaModel 20 | { 21 | public: 22 | FunctionModel( 23 | std::string& name, 24 | std::string& ret_type, 25 | std::vector& type_list, 26 | std::vector& name_list 27 | ); 28 | 29 | int find(std::string& name); 30 | 31 | std::string return_type; 32 | std::vector type_list; 33 | std::vector name_list; 34 | 35 | LValue getFunction(CodeGenContext* context); 36 | LValue getFunctionType() { return func_type; } 37 | 38 | virtual void insertToST(CodeGenContext* context); 39 | virtual void genCode(CodeGenContext* context); 40 | virtual void genMetaCode(CodeGenContext* context); 41 | virtual MetaType getMetaType(); 42 | private: 43 | LValue func_type; 44 | }; 45 | 46 | 47 | 48 | #endif // FUNCTION_MODEL_H 49 | -------------------------------------------------------------------------------- /includes/MetaModel/MacroModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-25 15:01:05 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-21 16:52:50 6 | */ 7 | 8 | 9 | #ifndef MACRO_MODEL_H 10 | #define MACRO_MODEL_H 11 | 12 | #include "Model/Node.h" 13 | #include "MetaModel.h" 14 | 15 | /** 16 | * @brief 宏模型元类型 17 | */ 18 | class MacroModel : public MetaModel 19 | { 20 | public: 21 | MacroModel(const std::string& name, Node* node); 22 | ~MacroModel(); 23 | 24 | virtual void insertToST(CodeGenContext* context); 25 | virtual void genCode(CodeGenContext* context); 26 | virtual void genMetaCode(CodeGenContext* context); 27 | virtual MetaType getMetaType(); 28 | 29 | Node* getData() { return node; } 30 | private: 31 | Node* node; 32 | }; 33 | 34 | 35 | #endif // MACRO_MODEL_H 36 | -------------------------------------------------------------------------------- /includes/MetaModel/MapModel.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_MODEL_H 2 | #define MAP_MODEL_H 3 | 4 | #include "MetaModel/MetaModel.h" 5 | #include 6 | #include 7 | #include "idmap.h" 8 | 9 | class MapModel : public MetaModel { 10 | public: 11 | MapModel (const string& name); 12 | virtual ~MapModel (); 13 | 14 | id* find(const string& name); 15 | 16 | protected: 17 | /* data */ 18 | std::map< std::string, id* > data; 19 | 20 | }; 21 | 22 | 23 | 24 | 25 | #endif /* end of include guard: MAP_MODEL_H */ 26 | -------------------------------------------------------------------------------- /includes/MetaModel/MetaModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-13 17:08:01 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-18 23:05:21 6 | */ 7 | 8 | 9 | #ifndef META_MODEL_H 10 | #define META_MODEL_H 11 | 12 | #include 13 | #include "LLCG/lvalue.h" 14 | 15 | 16 | 17 | enum MetaType 18 | { 19 | struct_meta_t, function_meta_t, macro_meta_t, map_meta_t 20 | }; 21 | 22 | class CodeGenContext; 23 | 24 | /** 25 | * @brief 元数据模型基类 26 | */ 27 | class MetaModel : public lvalue 28 | { 29 | public: 30 | MetaModel(std::string); 31 | virtual ~MetaModel(); 32 | 33 | virtual void insertToST(CodeGenContext* context) = 0; 34 | virtual void genCode(CodeGenContext* context) = 0; 35 | virtual void genMetaCode(CodeGenContext* context) = 0; 36 | virtual MetaType getMetaType() = 0; 37 | 38 | static MetaModel* readJson(); 39 | static MetaModel* readMetaCode(); 40 | protected: 41 | std::string name; 42 | }; 43 | 44 | 45 | 46 | #endif // META_MODEL_H 47 | -------------------------------------------------------------------------------- /includes/MetaModel/StructModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-29 10:47:04 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 17:17:28 6 | */ 7 | 8 | #ifndef STRUCT_MODEL_H 9 | #define STRUCT_MODEL_H 10 | 11 | #include "MetaModel.h" 12 | #include 13 | #include 14 | 15 | /** 16 | * @brief 结构体类型元类型 17 | */ 18 | class StructModel : public MetaModel 19 | { 20 | public: 21 | StructModel(std::string& name, 22 | std::vector& type_list, 23 | std::vector& name_list); 24 | 25 | int find(std::string& name); 26 | 27 | std::vector type_list; 28 | std::vector name_list; 29 | LValue getStruct(CodeGenContext* context); 30 | 31 | virtual void insertToST(CodeGenContext* context); 32 | virtual void genCode(CodeGenContext* context); 33 | virtual void genMetaCode(CodeGenContext* context); 34 | virtual MetaType getMetaType(); 35 | private: 36 | LValue struct_type; 37 | }; 38 | 39 | 40 | 41 | #endif // STRUCT_MODEL_H 42 | -------------------------------------------------------------------------------- /includes/Model/ByteNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #ifndef _BYTENODE_H 7 | #define _BYTENODE_H 8 | 9 | #include "Node.h" 10 | 11 | 12 | class ByteNode: public Node { 13 | public: 14 | char value; 15 | 16 | // virtual Value* codeGen(CodeGenContext* context); 17 | }; 18 | 19 | #endif //_BYTENODE_H -------------------------------------------------------------------------------- /includes/Model/CharNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #ifndef _CHARNODE_H 7 | #define _CHARNODE_H 8 | 9 | #include "Node.h" 10 | 11 | 12 | class CharNode: public Node { 13 | public: 14 | char value; 15 | 16 | CharNode(char* v) { 17 | value = *v; 18 | } 19 | 20 | // virtual Value* codeGen(CodeGenContext* context); 21 | }; 22 | 23 | #endif //_CHARNODE_H -------------------------------------------------------------------------------- /includes/Model/FloatNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #ifndef _FLOATNODE_H 7 | #define _FLOATNODE_H 8 | 9 | #include "Node.h" 10 | #include 11 | using namespace std; 12 | 13 | class FloatNode: public Node { 14 | public: 15 | static FloatNode* Create(const char* num); 16 | virtual LValue codeGen(CodeGenContext* context); 17 | virtual NodeType getType(); 18 | float getFloat(); 19 | virtual Node* copy() { 20 | return new FloatNode(*this); 21 | } 22 | protected: 23 | void printSelf(); 24 | float value; 25 | FloatNode(const char* num); 26 | }; 27 | 28 | #endif //_FLOATNODE_H 29 | -------------------------------------------------------------------------------- /includes/Model/IDNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #ifndef _IDNODE_H 7 | #define _IDNODE_H 8 | 9 | #include "Node.h" 10 | #include 11 | 12 | using namespace std; 13 | 14 | class IDNode: public Node { 15 | public: 16 | static IDNode* Create(const char* _value); 17 | static IDNode* Create(char _value); 18 | std::string& getStr() { return value; } 19 | virtual LValue codeGen(CodeGenContext* context); 20 | virtual NodeType getType(); 21 | virtual Node* copy() { 22 | return new IDNode(*this); 23 | } 24 | protected: 25 | IDNode(const char* _value); 26 | IDNode(char _value); 27 | virtual void printSelf(); 28 | private: 29 | string value; 30 | }; 31 | 32 | #endif //_IDNODE_H -------------------------------------------------------------------------------- /includes/Model/IntNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #ifndef _INTNODE_H 7 | #define _INTNODE_H 8 | 9 | #include "Node.h" 10 | 11 | class IntNode: public Node { 12 | public: 13 | static IntNode* Create(const char* num); 14 | virtual LValue codeGen(CodeGenContext* context); 15 | virtual void printSelf(); 16 | virtual NodeType getType(); 17 | virtual Node* copy() { 18 | return new IntNode(*this); 19 | } 20 | protected: 21 | IntNode(const char* num); 22 | int value; 23 | }; 24 | 25 | #endif //_INTNODE_H -------------------------------------------------------------------------------- /includes/Model/Node.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-22 19:21:10 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 17:03:53 6 | */ 7 | 8 | #ifndef NODE_H 9 | #define NODE_H 10 | 11 | #include 12 | #include "LLCG/lvalue.h" 13 | 14 | class ElegantList; 15 | 16 | enum NodeType 17 | { 18 | node_t = 0, int_node_t, float_node_t, char_node_t, id_node_t, string_node_t, type_node_t 19 | }; 20 | 21 | class CodeGenContext; 22 | 23 | /** 24 | * @brief List的基本组成元素,表示一个代码中的基本节点 25 | * @details 编译器后端代码生成时,会构建Node节点串连起来的语法树,结构为左孩子 26 | * 右兄弟的二叉树,这样即可表示代码的基本结构 27 | * 28 | * Node节点的类型一般有如下几种(char 暂未使用): \n 29 | * id - 标识符 - 对应NodeType为:id_node_t \n 30 | * int - 整型 - 对应NodeType为:int_node_t \n 31 | * float - 浮点型 - 对应NodeType为:float_node_t \n 32 | * string - 字符串 - 对应NodeType为:string_node_t \n 33 | * type - 类型 - 对应NodeType为:type_node_t \n 34 | * @see NodeType 35 | * 36 | * 一般语法解析器在连接这款后端代码生成器时,只需要控制生成Node构造的语法树即可, 37 | * 语法树的形状符合RedApple中的定义,即可正确编译为后端代码。 38 | */ 39 | class Node 40 | { 41 | public: 42 | // 构建列表部分 43 | 44 | /** 45 | * @brief 添加一个孩子节点 46 | * @details 为当前Node添加一个孩子节点, 将child指针指向它, 可以是链表的首节点 47 | * 48 | * @param n 一个孩子节点,或孩子链表的首节点 49 | */ 50 | void addChildren(Node* n); 51 | 52 | /** 53 | * @brief 添加一个兄弟节点 54 | * @details 为当前Node添加一个兄弟节点, 将自己链表的末尾next指针设置为传入指针 55 | * 由于为了减少语法树的大小, 这里采用的是单链表, 所以插入速度可能有点慢, 56 | * 后期优化时, 可以权衡内存占用和速度, 再进行选择 57 | * 58 | * @param n 添加的节点指针 59 | */ 60 | void addBrother (Node* n); 61 | 62 | /** 63 | * @brief 判断当前节点是一个元素, 还是一个链表 64 | * @details 判断当前节点是一个元素, 还是一个链表, 主要用于getList方法和makeList方法 65 | * 由于构造语法树时,很多情况不知道要添加的是一个节点还是一个链表. 66 | * 这个方法可以用来判断.\n 67 | * 但一般情况, getList方法应该足够使用了. 68 | * @return 是单一元素返回true, 是链表返回false 69 | */ 70 | bool isSingle(); 71 | 72 | // 便捷的构造list的方法 73 | 74 | /** 75 | * @brief C++语言版的接口, 用来方便地构造一个列表 76 | * @details 用来方便地构造一个列表, make_list里不定参数如果传入空, 那么该位置会被跳过 77 | * 使用时务必注意, num和后面不定参数的个数一定要相当 78 | * 79 | * @param num 不定参数的格式 80 | * @param ... 每个是一个 Node* 指针 81 | * 82 | * @return 构造好的列表的首节点指针 83 | */ 84 | static Node* make_list(int num, ...); 85 | 86 | /** 87 | * @brief 其他语言的接口, 用来方便地构造一个列表 88 | * @details 用来方便地构造一个列表, 功能和 make_list 一样 89 | * @see make_list() 90 | * 91 | * @param num 参数的个数 92 | * @param plist 一个指针数组 93 | * 94 | * @return 构造好的列表的首节点指针 95 | */ 96 | static Node* makeList(int num, Node* plist[]); 97 | 98 | /** 99 | * @brief 如果传入节点是单一元素,则为其包裹一层Node节点 100 | * @details 如果传入节点是单一元素,则为其包裹一层Node节点 101 | * 如果传入的是链表,能够方便地将其作为一个新Node的子元素 102 | * 然后将新的Node节点返回, 这样就形成了一个完整的链表 103 | * 如果是单一元素,那么该函数什么都不做,将传入节点返回 104 | * 105 | * @param node 要处理的节点 106 | * @return 是链表则包围一层, 否则直接返回传入的节点 107 | */ 108 | static Node* getList(Node* node); 109 | 110 | // 全局构造析构 111 | 112 | /** 113 | * @brief 构造一个节点, 并为其添加一个子元素链表 114 | * 115 | * @param n 子元素链表, 相当于对空节点添加了孩子 116 | * @return 新构造的节点 117 | */ 118 | static Node* Create(Node* n); 119 | 120 | /** 121 | * @brief 构造一个空节点 122 | * @return 新构造的节点 123 | */ 124 | static Node* Create(); 125 | 126 | /** 127 | * @brief 释放一个节点资源 128 | * @param p 这里是一个指针的引用, 会自动将指针置为NULL 129 | */ 130 | static void Free(Node*& p); 131 | 132 | /** 133 | * @brief 递归释放节点资源 134 | * @param p 要释放的节点, 这里会递归调用子节点 135 | */ 136 | static void FreeAll(Node*& p); 137 | 138 | // 拷贝函数 139 | virtual Node* copy(); 140 | virtual Node* copyAll(); 141 | virtual Node* copyChild(); 142 | 143 | // 节点的替换 144 | void replaceNext(Node* node); 145 | void replaceChild(Node* node); 146 | void replaceChildFirst(Node* node); 147 | 148 | /** 149 | * @brief 可用于调试的打印指令 150 | * @param k 缩进层次, 首次传0或1皆可 151 | */ 152 | void print(int k); 153 | 154 | Node* getNext() { return next; } 155 | Node* getChild() { return child; } 156 | 157 | /** 158 | * @brief 重要的代码生成函数 159 | * @details 重要的代码生成函数, 对于不同的节点, 会有不同的代码生成策略, 160 | * 这个函数是多态调用的, 在每个Node的子类中都有相关实现 161 | * Node的代码生成会按照表处理, 将第一个元素视为宏名 162 | * ID会自动去符号表中查找定义, 返回符号表中存储的变量 163 | * Type会自动去符号表中查找, 返回一个类型的定义 164 | * Int会自动构造常量数字 165 | * String会自动构造常量字符串 166 | * 167 | * @param context 代码生成上下文类 168 | * @return 返回代码生成的结果指针LValue 169 | */ 170 | virtual LValue codeGen(CodeGenContext* context); 171 | 172 | // 如果是含有字符串的节点,则返回所含字符串,否则将报错 173 | /** 174 | * @brief 获取当前节点内存放的字符串 175 | * @details 只有含有字符串的节点该函数有效, 目前ID和String有效 176 | * 如果是普通的节点, 则会报异常 177 | * @return 返回字符串的引用 178 | */ 179 | virtual std::string& getStr(); 180 | 181 | /** 182 | * @brief 获取类型名 183 | * @return 节点的名字 184 | */ 185 | std::string getTypeName(); 186 | 187 | /** 188 | * @brief 获取节点类型 189 | * @return 节点类型的枚举 190 | */ 191 | virtual NodeType getType(); 192 | 193 | bool isNode(); 194 | bool isIntNode(); 195 | bool isFloatNode(); 196 | bool isIDNode(); 197 | bool isStringNode(); 198 | bool isCharNode(); 199 | bool isTypeNode(); 200 | 201 | 202 | protected: 203 | Node(); 204 | Node(Node* n); 205 | virtual ~Node(); 206 | 207 | virtual void printSelf(); 208 | void init(); 209 | 210 | Node* next; 211 | Node* child; 212 | 213 | static ElegantList el; 214 | }; 215 | 216 | 217 | #endif // NODE_H 218 | -------------------------------------------------------------------------------- /includes/Model/StringNode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-22 22:00:32 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 15:46:49 6 | */ 7 | 8 | #ifndef STRING_NODE_H 9 | #define STRING_NODE_H 10 | 11 | #include "Node.h" 12 | #include 13 | 14 | using namespace std; 15 | 16 | class StringNode : public Node 17 | { 18 | public: 19 | static StringNode* Create(const char* _value); 20 | static StringNode* Create(char _value); 21 | std::string& getStr() { return value; } 22 | virtual LValue codeGen(CodeGenContext* context); 23 | virtual NodeType getType(); 24 | virtual Node* copy() { 25 | return new StringNode(*this); 26 | } 27 | protected: 28 | virtual void printSelf(); 29 | StringNode(const char* _value); 30 | StringNode(char _value); 31 | private: 32 | string value; 33 | }; 34 | 35 | 36 | 37 | #endif // STRING_NODE_H 38 | -------------------------------------------------------------------------------- /includes/Model/TypeNode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-19 11:22:12 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 15:47:07 6 | */ 7 | 8 | #ifndef TYPE_NODE_H 9 | #define TYPE_NODE_H 10 | 11 | #include "Node.h" 12 | #include 13 | using namespace std; 14 | 15 | namespace llvm { 16 | class Type; 17 | } // llvm 18 | 19 | class TypeNode: public Node { 20 | public: 21 | static TypeNode* Create(const char* name, bool is_const = false, bool is_source = false); 22 | LValue typeGen(CodeGenContext* context); 23 | void addDimension(); 24 | bool isArray() { 25 | return dimension == 0; 26 | } 27 | 28 | virtual NodeType getType(); 29 | virtual string& getStr(); 30 | string& getTypeName(); 31 | 32 | virtual Node* copy() { 33 | return new TypeNode(*this); 34 | } 35 | protected: 36 | virtual void printSelf(); 37 | string str; 38 | string name; 39 | bool is_const = false; 40 | bool is_source = false; // 这个只在函数是结构体时有用,来设置真正的原型类型 41 | int dimension = 0; 42 | TypeNode(const char* name, bool is_const = false, bool is_source = false); 43 | }; 44 | 45 | 46 | 47 | #endif // TYPE_NODE_H 48 | -------------------------------------------------------------------------------- /includes/Model/nodes.h: -------------------------------------------------------------------------------- 1 | #include "Node.h" 2 | #include "CharNode.h" 3 | #include "FloatNode.h" 4 | #include "IDNode.h" 5 | #include "IntNode.h" 6 | #include "StringNode.h" 7 | #include "TypeNode.h" 8 | -------------------------------------------------------------------------------- /includes/Pass.h: -------------------------------------------------------------------------------- 1 | #ifndef PASS_H 2 | #define PASS_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | #include "CodeGenFunction.h" 11 | 12 | 13 | class Pass { 14 | public: 15 | Pass (const FuncReg* macro_funcs); 16 | Pass (const FuncReg* macro_funcs, const FuncReg* macro_funcs2); 17 | virtual ~Pass (); 18 | 19 | /** 20 | * @brief 正式扫描前的初始化 21 | */ 22 | virtual void Init(); 23 | 24 | 25 | /** 26 | * @brief 查找一个名称是否为一个C宏 27 | * @details 查找一个名称是否为一个C宏 28 | * 29 | * @param str 宏的名字 30 | * @return 如果有,则返回函数指针,否则返回NULL 31 | */ 32 | virtual ICodeGenFunction* getMacro(const string& str); 33 | 34 | // C++注册宏 35 | // void AddMacros(const FuncReg* macro_funcs); // 为只添加不替换保留 36 | 37 | /** 38 | * @brief 添加或替换一条宏 39 | * @details 添加或替换一条宏,如果当前名称存在则替换,没有则添加 40 | * 41 | * @param macro_funcs 一组宏定义数组,类似Lua中函数的定义方式 42 | */ 43 | virtual void AddOrReplaceMacros(const FuncReg* macro_funcs); 44 | 45 | virtual void AddOrReplaceMacros(const string& name, ICodeGenFunction* func); 46 | 47 | 48 | /** 49 | * @brief 移除全部宏指令 50 | * @details 移除全部宏指令 51 | */ 52 | virtual void RemoveAllMacros(); 53 | 54 | /** 55 | * 临时保存当前宏到堆栈中,还可以恢复 56 | * @method SaveMacros 57 | */ 58 | virtual void SaveMacros(); 59 | 60 | /** 61 | * 恢复之前保存的堆栈 62 | * @method RecoverMacros 63 | */ 64 | virtual void RecoverMacros(); 65 | 66 | 67 | protected: 68 | 69 | /** 70 | * @brief 宏定义表,用来查找是否有该宏定义的 71 | * @details 宏定义表,里面存放有对应名称的C语言宏处理函数 72 | */ 73 | map macro_map; 74 | 75 | /** 76 | * @brief 这个栈是用来临时保存上面的查询表的 77 | * @details 某些情况,可能会对宏处理的函数进行临时的变更,就需要保存和恢复全部的状态,这个栈是用来记录宏表的 78 | */ 79 | stack > macro_save_stack; 80 | 81 | 82 | }; 83 | 84 | 85 | #endif /* end of include guard: PASS_H */ 86 | -------------------------------------------------------------------------------- /includes/PassManager.h: -------------------------------------------------------------------------------- 1 | #ifndef PASS_MANAGER_H 2 | #define PASS_MANAGER_H 3 | 4 | #include "Pass.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | class ICodeGenContext; 12 | 13 | class PassManager { 14 | public: 15 | PassManager (); 16 | virtual ~PassManager (); 17 | 18 | void NewPassList(const string& name, const vector& vec); 19 | 20 | void NewPassList(const string& name, const list& lst); 21 | 22 | list* getPassList(const string& name); 23 | 24 | void RunPassList(const string& name, Node* node, ICodeGenContext* ctx); 25 | 26 | void RunPassListWithSet(const string& name, set& nodes, ICodeGenContext* ctx); 27 | 28 | void LoadDefaultLists(); 29 | 30 | protected: 31 | /* data */ 32 | 33 | /** 34 | * 所有PassList的存储位置 35 | */ 36 | map > pass_lists; 37 | }; 38 | 39 | 40 | #endif /* end of include guard: PASS_MANAGER_H */ 41 | -------------------------------------------------------------------------------- /includes/RedCodeGen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-23 22:55:30 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-26 14:28:25 6 | * 7 | * 代码生成部分的引导类 8 | */ 9 | 10 | #ifndef RED_CODE_GEN_H 11 | #define RED_CODE_GEN_H 12 | 13 | #include "Model/Node.h" 14 | #include "CodeGen.h" 15 | #include "PassManager.h" 16 | 17 | 18 | class CodeGenContext; 19 | class RedCodeGen : public CodeGen 20 | { 21 | public: 22 | virtual void Init(); 23 | virtual void PreScan(Node* node); 24 | virtual void PreScan(std::set& nodes); 25 | virtual void Make(Node* node, const char* outfile_name, const char* module_name); 26 | virtual void MakeMeta(const char* outfile_name, const char* module_name); 27 | 28 | static RedCodeGen* Create(); 29 | 30 | CodeGenContext* getContext() { return context; } 31 | private: 32 | RedCodeGen(); 33 | ~RedCodeGen(); 34 | CodeGenContext* context = NULL; 35 | PassManager pm; 36 | }; 37 | 38 | 39 | 40 | #endif // RED_CODE_GEN_H 41 | -------------------------------------------------------------------------------- /runtimeproj/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET (CMAKE_CXX_FLAGS "-std=c++11") 2 | include_directories(src ../../extlib/include) 3 | file(GLOB_RECURSE runtime_source_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) 4 | 5 | add_library(runtime STATIC ${runtime_source_files} ) 6 | install(TARGETS runtime ARCHIVE DESTINATION runtime) 7 | -------------------------------------------------------------------------------- /runtimeproj/src/runtime.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-15 10:19:10 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 18:55:41 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "dyncall.h" 15 | 16 | using namespace std; 17 | 18 | typedef void* (*FuncPtrTy)(...); 19 | 20 | struct FunctionMeta { 21 | string name; 22 | string ret_type; 23 | vector type_list; 24 | vector name_list; 25 | void* function_ptr; 26 | }; 27 | 28 | struct StructMeta { 29 | string name; 30 | vector type_list; 31 | vector name_list; 32 | }; 33 | 34 | enum NormalType 35 | { 36 | void_normal_t, 37 | int_normal_t, 38 | float_normal_t, 39 | double_normal_t, 40 | char_normal_t, 41 | byte_normal_t, 42 | ptr_normal_t, 43 | unknown_normal_t 44 | }; 45 | 46 | class EliteMeta { 47 | public: 48 | static void RegFunction(string& name, string& ret_type, 49 | vector& type_list, vector& name_list, void* fptr); 50 | static void RegStruct(string& name, 51 | vector& type_list, vector& name_list); 52 | 53 | static FunctionMeta* getFunction(string& name); 54 | static StructMeta* getStruct(string& name); 55 | static NormalType getNormalType(string& name); 56 | static EliteMeta& getInstance(); 57 | 58 | DCCallVM* vm = NULL; 59 | private: 60 | map func_map; 61 | map struct_map; 62 | 63 | EliteMeta() { vm = dcNewCallVM(4096); } 64 | ~EliteMeta() { dcFree(vm); } 65 | }; 66 | 67 | 68 | // 核心反射接口 69 | extern "C" { 70 | void elite_meta_function(const char* name, const char** list, void* fptr) { 71 | // printf("RegFunction: %s\n", name); 72 | int argno = 0; /* 纪录参数个数 */ 73 | vector type_list; 74 | vector name_list; 75 | string sret_type = list[0]; 76 | const char **para = list+1; /* 存放取出的字符串参数 */ 77 | while (*para != NULL) { 78 | ++argno; 79 | if (argno & 1) type_list.push_back(*para); 80 | else name_list.push_back(*para); 81 | // printf("%s ", *para); 82 | ++para; 83 | } 84 | string sname = name; 85 | EliteMeta::RegFunction(sname, sret_type, type_list, name_list, fptr); 86 | } 87 | 88 | void elite_meta_list(const char** list) { 89 | string meta_type = list[0]; 90 | if (meta_type == "struct") { 91 | string meta_name = list[1]; 92 | // printf("RegStruct: %s\n", meta_name.c_str()); 93 | int argno = 0; /* 纪录参数个数 */ 94 | const char** para = list+2; /* 存放取出的字符串参数 */ 95 | vector type_list; 96 | vector name_list; 97 | while (*para != NULL) { 98 | ++argno; 99 | if (argno & 1) type_list.push_back(*para); 100 | else name_list.push_back(*para); 101 | // printf("%s ", *para); 102 | ++para; 103 | } 104 | EliteMeta::RegStruct(meta_name, type_list, name_list); 105 | } 106 | } 107 | 108 | void* FunctionCall(const char* name, ...) { 109 | string sname = name; 110 | FunctionMeta* fm = EliteMeta::getFunction(sname); 111 | if (fm == NULL) { 112 | printf("运行时异常, 反射调用的函数未找到: %s\n", name); 113 | return NULL; 114 | } 115 | va_list argp; /* 定义保存函数参数的结构 */ 116 | va_start( argp, name ); 117 | 118 | // 设定调用栈 119 | DCCallVM* vm = EliteMeta::getInstance().vm; 120 | dcMode(vm, DC_CALL_C_DEFAULT); 121 | dcReset(vm); 122 | 123 | for (auto& s : fm->type_list) { 124 | NormalType t = EliteMeta::getNormalType(s); 125 | switch (t) { 126 | case int_normal_t: dcArgInt(vm, va_arg(argp, int)); break; 127 | case float_normal_t: dcArgFloat(vm, (float)va_arg(argp, double)); break; // 默认参数提升 128 | case double_normal_t: dcArgDouble(vm, va_arg(argp, double)); break; 129 | case char_normal_t: dcArgShort(vm, (short)va_arg(argp, int)); break; 130 | case byte_normal_t: dcArgChar(vm, (char)va_arg(argp, int)); break; 131 | case ptr_normal_t: dcArgPointer(vm, va_arg(argp, void*)); break; 132 | default: 133 | printf("函数类型异常: %s 类型不能作为参数\n", s.c_str()); 134 | va_end( argp ); /* 将argp置为NULL */ 135 | return NULL; 136 | } 137 | } 138 | va_end( argp ); /* 将argp置为NULL */ 139 | void* ans; 140 | DCpointer fptr = (DCpointer)(fm->function_ptr); 141 | NormalType t = EliteMeta::getNormalType(fm->ret_type); 142 | switch (t) { 143 | case void_normal_t: ans = NULL; dcCallVoid(vm, fptr); break; 144 | case int_normal_t: ans = (void*)dcCallInt(vm, fptr); break; 145 | // case float_normal_t : ans = (void*) dcCallFloat(vm, fptr); break; 146 | // case double_normal_t :ans = (void*) dcCallDouble(vm, fptr); break; 147 | case char_normal_t: ans = (void*)dcCallShort(vm, fptr); break; 148 | case byte_normal_t: ans = (void*)dcCallChar(vm, fptr); break; 149 | case ptr_normal_t: ans = (void*)dcCallPointer(vm, fptr); break; 150 | default: 151 | printf("函数类型异常: %s 类型不能作为返回类型\n", fm->ret_type.c_str()); 152 | return NULL; 153 | } 154 | return ans; 155 | } 156 | 157 | void* malloc_array(int size, ...) { 158 | va_list argp; /* 定义保存函数参数的结构 */ 159 | va_start( argp, size ); 160 | std::vector wd; 161 | int v; int num = 1; 162 | do { 163 | v = va_arg(argp, int); 164 | if (v != 0) { 165 | wd.push_back(v); 166 | num *= v; 167 | } 168 | } while (v != 0); 169 | va_end( argp ); /* 将argp置为NULL */ 170 | 171 | int full_size = wd.size()*sizeof(int) + size* num; 172 | int* ans = (int*) malloc(full_size); 173 | int* i = ans; 174 | for (auto p = wd.begin(); p != wd.end(); ++p, ++i) { 175 | *i = *p; 176 | } 177 | return (void*) i; 178 | } 179 | 180 | void free_array(void* ptr, int v) { 181 | if (ptr == NULL) return; 182 | void* real_ptr = (int*)ptr - v; 183 | free(ptr); 184 | } 185 | 186 | } 187 | 188 | 189 | 190 | 191 | 192 | void EliteMeta::RegFunction(string& name, string& ret_type, 193 | vector& type_list, vector& name_list, void* fptr) { 194 | FunctionMeta* fm = new FunctionMeta(); 195 | fm->name = name; 196 | fm->ret_type = ret_type; 197 | fm->type_list = type_list; 198 | fm->name_list = name_list; 199 | fm->function_ptr = fptr; 200 | getInstance().func_map[name] = fm; 201 | } 202 | 203 | void EliteMeta::RegStruct(string& name, 204 | vector& type_list, vector& name_list) { 205 | StructMeta* sm = new StructMeta(); 206 | sm->name = name; 207 | sm->type_list = type_list; 208 | sm->name_list = name_list; 209 | getInstance().struct_map[name] = sm; 210 | } 211 | 212 | FunctionMeta* EliteMeta::getFunction(string& name) { 213 | auto& map = getInstance().func_map; 214 | auto p = map.find(name); 215 | if (p == map.end()) return NULL; 216 | else return p->second; 217 | } 218 | 219 | StructMeta* EliteMeta::getStruct(string& name) { 220 | auto& map = getInstance().struct_map; 221 | auto p = map.find(name); 222 | if (p == map.end()) return NULL; 223 | else return p->second; 224 | } 225 | 226 | 227 | EliteMeta& EliteMeta::getInstance() { 228 | static EliteMeta meta; 229 | return meta; 230 | } 231 | 232 | 233 | NormalType EliteMeta::getNormalType(string& name) { 234 | if (getStruct(name) != NULL) return ptr_normal_t; 235 | if (name == "void") return void_normal_t; 236 | if (name == "int") return int_normal_t; 237 | if (name == "float") return float_normal_t; 238 | if (name == "double") return double_normal_t; 239 | if (name == "char") return char_normal_t; 240 | if (name == "byte") return byte_normal_t; 241 | return unknown_normal_t; 242 | } 243 | -------------------------------------------------------------------------------- /src/CodeGenContext.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-10 18:45:20 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:37:24 6 | */ 7 | 8 | #include "CodeGenContext.h" 9 | #include "StringNode.h" 10 | #include "IDNode.h" 11 | #include 12 | #include "idtable.h" 13 | #include "MacroTranslate.h" 14 | #include "Pass.h" 15 | 16 | using namespace std; 17 | 18 | LValue CodeGenContext::MacroMake(Node* node) { 19 | if (node == NULL) return NULL; 20 | 21 | if (node->isIDNode()) { 22 | shared_ptr p = getUserMacro(node->getStr()); 23 | if (p != NULL) { 24 | Node* user_macro_node = p->getData(); 25 | MacroTranslate translater; 26 | Node* replace = translater.Marco(user_macro_node, node->getNext()); 27 | LValue ans = MacroMake(replace); 28 | Node::FreeAll(replace); 29 | return ans; 30 | } 31 | ICodeGenFunction* func = now_pass->getMacro(node->getStr()); 32 | if (func != NULL) { 33 | return func->call(this, node->getNext()); 34 | } 35 | return NULL; 36 | } 37 | if (node->getChild() != NULL && node->getChild()->isIDNode()) 38 | return MacroMake(node->getChild()); 39 | LValue ans; 40 | for (Node* p = node->getChild(); p != NULL; p = p->getNext()) 41 | ans = MacroMake(p); 42 | return ans; 43 | } 44 | 45 | 46 | id* CodeGenContext::FindST(Node* node) const{ 47 | return FindST(node->getStr()); 48 | } 49 | 50 | id* CodeGenContext::FindST(const string& str) const { 51 | return st->find(str); 52 | } 53 | 54 | LValue CodeGenContext::getFunction(Node* node) { 55 | return getFunction(node->getStr()); 56 | } 57 | 58 | LValue CodeGenContext::getFunction(const std::string& name) { 59 | shared_ptr fm = getFunctionModel(name); 60 | if (fm != NULL) return fm->getFunction(this); 61 | LValue defined_func = getLLCG()->getFunction(name); 62 | if (defined_func != NULL) return defined_func; 63 | cerr << "函数未定义: " << name << endl; 64 | return NULL; 65 | } 66 | 67 | shared_ptr CodeGenContext::getFunctionModel(const string& name) { 68 | id* i = FindST(name); 69 | if (i == NULL) { 70 | return NULL; 71 | } 72 | if (i->type != function_t) { 73 | return NULL; 74 | } 75 | return dynamic_pointer_cast(i->data); 76 | } 77 | 78 | shared_ptr CodeGenContext::getUserMacro(const std::string& name) { 79 | id* i = FindST(name); 80 | if (i == NULL) return NULL; 81 | if (i->type != macro_t) return NULL; 82 | return dynamic_pointer_cast(i->data); 83 | } 84 | 85 | void CodeGenContext::setUserMacro(const std::string& name, Node* node) { 86 | LValue p(new MacroModel(name, node)); 87 | st->insert(name, macro_t, p); 88 | } 89 | 90 | shared_ptr CodeGenContext::getStructModel(const string& name) { 91 | id* i = FindST(name); 92 | if (i == NULL) { 93 | printf("错误: 符号 %s 未找到\n", name.c_str()); 94 | return NULL; 95 | } 96 | if (i->type != struct_t) { 97 | printf("错误: 符号 %s 类型不是结构体\n", name.c_str()); 98 | return NULL; 99 | } 100 | return dynamic_pointer_cast(i->data); 101 | } 102 | 103 | 104 | void CodeGenContext::DefType(string name, LValue t) { 105 | st->insert(name, type_t, t); 106 | } 107 | 108 | LValue CodeGenContext::FindSrcType(const string& name) { 109 | id* i = st->find(name); 110 | LValue ret_type; 111 | if (i != NULL && i->type == type_t) { 112 | LValue t = i->data; 113 | ret_type = t; 114 | } else if (i != NULL && i->type == struct_t) { 115 | auto s = dynamic_pointer_cast(i->data); 116 | ret_type = s->getStruct(this); 117 | } else { 118 | cerr << "找不到该类型的定义: "; 119 | cerr << name << "\n"; 120 | return NULL; 121 | } 122 | return ret_type; 123 | } 124 | 125 | LValue CodeGenContext::FindSrcType(Node* node) { 126 | return FindSrcType(node->getStr()); 127 | } 128 | 129 | LValue CodeGenContext::FindType(const string& name) { 130 | string find_name = name; int d = 0; 131 | bool is_source = false; 132 | if (find_name[0] == '*') { 133 | is_source = true; 134 | find_name.erase(find_name.begin()); 135 | } 136 | 137 | while (find_name.back() == ']') { 138 | find_name.pop_back(); 139 | find_name.pop_back(); 140 | ++d; 141 | } 142 | LValue t = FindSrcType(find_name); 143 | if (t->isStructType() && !is_source) 144 | t = t->getPointerTo(); 145 | if (d >= 1) { // - -! 这么白痴的错误居然瞪了两个小时没发现 146 | t = t->getPointerTo(); 147 | } 148 | return t; 149 | } 150 | 151 | LValue CodeGenContext::FindType(Node* node) { 152 | return FindType(node->getStr()); 153 | } 154 | 155 | void CodeGenContext::DefVar(const string& name, LValue addr) { 156 | st->insert(name, var_t, addr); 157 | } 158 | 159 | LValue CodeGenContext::FindVar(const string& name) { 160 | id* i = st->find(name); 161 | if (i != NULL && i->type == var_t) { 162 | return i->data; 163 | } 164 | cerr << "变量未找到: " << name << endl; 165 | return NULL; 166 | } 167 | 168 | 169 | void CodeGenContext::setNormalType() { 170 | DefType("void", codeGenerator->Void()); 171 | DefType("int", codeGenerator->Int64()); 172 | DefType("float", codeGenerator->Float()); 173 | DefType("double", codeGenerator->Double()); 174 | 175 | DefType("int8", codeGenerator->Int8()); 176 | DefType("int16", codeGenerator->Int16()); 177 | DefType("int32", codeGenerator->Int32()); 178 | DefType("int64", codeGenerator->Int64()); 179 | 180 | DefType("uint64", codeGenerator->Int64()); 181 | DefType("uint8", codeGenerator->Int8()); 182 | DefType("uint16", codeGenerator->Int16()); 183 | DefType("uint32", codeGenerator->Int32()); 184 | DefType("uint64", codeGenerator->Int64()); 185 | 186 | DefType("byte", codeGenerator->Int8()); 187 | DefType("char", codeGenerator->Int8()); 188 | DefType("wchar", codeGenerator->Int32()); 189 | } 190 | 191 | 192 | CodeGenContext::CodeGenContext() { 193 | _save = false; 194 | st = new IDTable(); 195 | codeGenerator = llcg::CreateLLVM(); 196 | setNormalType(); 197 | } 198 | 199 | void CodeGenContext::Init() { 200 | _save = false; 201 | } 202 | 203 | CodeGenContext::~CodeGenContext() { 204 | delete st; 205 | delete codeGenerator; 206 | } 207 | -------------------------------------------------------------------------------- /src/CodeGenFunction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-12-19 10:44:37 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:10:42 6 | */ 7 | 8 | #include "CodeGenFunction.h" 9 | #include 10 | #include "CodeGenContext.h" 11 | 12 | CodeGenFunction::CodeGenFunction() { 13 | } 14 | 15 | CodeGenFunction::CodeGenFunction(CodeGenCFunction _cfunc) { 16 | *this = _cfunc; 17 | } 18 | 19 | const CodeGenFunction& CodeGenFunction::operator= (const CodeGenFunction& obj) { 20 | this->cfunc = obj.cfunc; 21 | return *this; 22 | } 23 | 24 | const CodeGenFunction& CodeGenFunction::operator= (CodeGenCFunction _cfunc) { 25 | this->cfunc = _cfunc; 26 | return *this; 27 | } 28 | 29 | LValue CodeGenFunction::call(CodeGenContext* ctx, Node* n) { 30 | CodeGenCFunction f = getCFunc(); 31 | return f(ctx, n); 32 | } 33 | 34 | CodeGenCFunction CodeGenFunction::getCFunc() { 35 | return this->cfunc; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llcg_llvm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 21:41:19 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 17:17:28 6 | */ 7 | 8 | #include "llcg_llvm.h" 9 | #include "llvm_value.h" 10 | #include "llvm_type.h" 11 | 12 | #include 13 | #include 14 | using namespace std; 15 | llcg_llvm::llcg_llvm() { 16 | meta_M = llvm::make_unique("", context); 17 | register_metalib(); 18 | } 19 | 20 | llcg_llvm::~llcg_llvm() { 21 | llvm_shutdown(); 22 | } 23 | 24 | LValue llcg_llvm::FuncType(FunctionModel* fmodel) { 25 | return nullptr; 26 | } // 返回FunctionType 27 | 28 | LValue llcg_llvm::FuncType(LValue ret_type, vector& types, bool isNotSure) { 29 | LLVMType ret = LLTYPE(ret_type); 30 | vector malloc_type; 31 | for (auto p : types) { 32 | LLVMType t = LLTYPE(p); 33 | malloc_type.push_back(*t); 34 | } 35 | FunctionType* func_type = FunctionType::get(*ret, malloc_type, 36 | /*vararg*/isNotSure); 37 | return LValue(new llvm_type(func_type)); 38 | } 39 | 40 | LValue llcg_llvm::GetOrInsertFunction(FunctionModel* fmodel) { 41 | return nullptr; 42 | } // 返回Function 43 | 44 | LValue llcg_llvm::GetOrInsertFunction(const string& name, LValue func_type) { 45 | LLVMType _func_type = LLTYPE(func_type); 46 | Type* t = *_func_type; 47 | Constant* f = M->getOrInsertFunction(name, (FunctionType*)t); 48 | return LValue(new llvm_value(f)); 49 | } 50 | 51 | LValue llcg_llvm::GetOrInsertFunction(const string& name, LValue ret_type, vector& types, bool isNotSure) { 52 | return nullptr; 53 | } 54 | 55 | void llcg_llvm::FunctionBodyBegin(LValue func, vector& name_list) { 56 | Value* _func = *LLVALUE(func); 57 | Function* F = dyn_cast(_func); 58 | int i = 0; 59 | for (auto arg = F->arg_begin(); i != name_list.size(); ++arg, ++i) { 60 | arg->setName(name_list[i]); 61 | Value* argumentValue = arg; 62 | ValueSymbolTable* st = nowBlock->getValueSymbolTable(); 63 | Value* v = st->lookup(name_list[i]); 64 | new StoreInst(argumentValue, v, false, nowBlock); 65 | } 66 | } // 设置当前BasicBlock 67 | 68 | void llcg_llvm::FunctionBodyEnd() { 69 | if (nowBlock->getTerminator() == NULL) 70 | ReturnInst::Create(context, nowBlock); 71 | } // 处理函数结束 72 | 73 | LValue llcg_llvm::getFunction(const string& name) { 74 | Function* f = M->getFunction(name); 75 | return LValue(new llvm_value(f)); 76 | } 77 | 78 | LValue llcg_llvm::Call(FunctionModel* fmodel, vector& args) { 79 | // LLVMValue _func = LLVALUE(fmodel->getFunction()); 80 | vector fargs; 81 | for (auto p : args) { 82 | LLVMValue t = LLVALUE(p); 83 | fargs.push_back(*t); 84 | } 85 | 86 | // CallInst *call = CallInst::Create(_func, fargs, "", nowBlock); 87 | // return LValue(new llvm_value(call)); 88 | return nullptr; 89 | } // 返回CallInst 90 | 91 | LValue llcg_llvm::Call(LValue func, vector& args) { 92 | LLVMValue _func = LLVALUE(func); 93 | vector fargs; 94 | for (auto p : args) { 95 | LLVMValue t = LLVALUE(p); 96 | fargs.push_back(*t); 97 | } 98 | 99 | CallInst *call = CallInst::Create(*_func, fargs, "", nowBlock); 100 | return LValue(new llvm_value(call)); 101 | } 102 | 103 | LValue llcg_llvm::Struct(StructModel* smodel) { 104 | return nullptr; 105 | } // 返回StructType 106 | 107 | LValue llcg_llvm::Struct(LValue _struct, vector& types) { 108 | std::vector type_vec; 109 | for (auto p : types) { 110 | Type* t = *LLTYPE(p); 111 | type_vec.push_back(t); 112 | } 113 | Type* struct_type = *LLTYPE(_struct); 114 | StructType* st = dyn_cast(struct_type); 115 | st->setBody(type_vec); 116 | return LValue(new llvm_type(st)); 117 | } 118 | 119 | LValue llcg_llvm::DeclareStruct(const string& name) { 120 | StructType* st = StructType::create(context, name); 121 | return LValue(new llvm_type(st)); 122 | } 123 | 124 | 125 | LValue llcg_llvm::DefVar(LValue var_type, const string& name) { 126 | Type* t = *LLTYPE(var_type); 127 | AllocaInst *alloc = new AllocaInst(t, name, nowBlock); 128 | return LValue(new llvm_value(alloc)); 129 | } 130 | 131 | LValue llcg_llvm::DefVar(LValue var_type, const string& name, LValue init) { 132 | Type* t = *LLTYPE(var_type); 133 | Value* v = *LLVALUE(init); 134 | AllocaInst *alloc = new AllocaInst(t, name, nowBlock); 135 | new StoreInst(v, alloc, false, nowBlock); 136 | return LValue(new llvm_value(alloc)); 137 | } 138 | 139 | LValue llcg_llvm::DefGlobalVar(LValue var_type, const string& name) { 140 | Type* t = *LLTYPE(var_type); 141 | Value* v = new GlobalVariable(*M, t, false, GlobalValue::LinkageTypes::ExternalLinkage, NULL, name); 142 | return LValue(new llvm_value(v)); 143 | } 144 | 145 | LValue llcg_llvm::DefGlobalVar(LValue var_type, const string& name, LValue init) { 146 | Type* t = *LLTYPE(var_type); 147 | Value* v = *LLVALUE(init); 148 | Value* g = new GlobalVariable(*M, t, false, GlobalValue::LinkageTypes::ExternalLinkage, 149 | dyn_cast(v), name); 150 | return LValue(new llvm_value(g)); 151 | } 152 | 153 | LValue llcg_llvm::Load(LValue var_addr) { 154 | Value* ptr = *LLVALUE(var_addr); 155 | Value* v = new LoadInst(ptr, "", false, nowBlock); 156 | return LValue(new llvm_value(v)); 157 | } 158 | 159 | LValue llcg_llvm::Store(LValue var_addr, LValue value) { 160 | Value* addr = *LLVALUE(var_addr); 161 | Value* v = *LLVALUE(value); 162 | new StoreInst(v, addr, false, nowBlock); 163 | return value; 164 | } 165 | 166 | LValue llcg_llvm::Opt1(const string& opt, LValue value) { 167 | Value* ans = *LLVALUE(value); 168 | 169 | AtomicRMWInst::BinOp bop; 170 | Value* one = ConstantInt::get(Type::getInt64Ty(context), 1); 171 | Value* ret; 172 | if (opt == "-") { ret = BinaryOperator::CreateNeg(ans, "", nowBlock); 173 | return LValue(new llvm_value(ret)); } 174 | if (opt == "~") { ret = BinaryOperator::CreateNot(ans, "", nowBlock); 175 | return LValue(new llvm_value(ret)); } 176 | if (opt == "++") { bop = AtomicRMWInst::BinOp::Add; goto selfWork; } 177 | if (opt == "--") { bop = AtomicRMWInst::BinOp::Sub; goto selfWork; } 178 | if (opt == "b++") { bop = AtomicRMWInst::BinOp::Add; goto saveWork; } 179 | if (opt == "b--") { bop = AtomicRMWInst::BinOp::Sub; goto saveWork; } 180 | 181 | selfWork: 182 | new AtomicRMWInst(bop, ans, one, AtomicOrdering::SequentiallyConsistent, 183 | SynchronizationScope::CrossThread, nowBlock); 184 | ret = new LoadInst(ans, "", false, nowBlock); 185 | return LValue(new llvm_value(ret)); 186 | 187 | saveWork: 188 | ret = new AtomicRMWInst(bop, ans, one, AtomicOrdering::SequentiallyConsistent, 189 | SynchronizationScope::CrossThread, nowBlock); 190 | return LValue(new llvm_value(ret)); 191 | } 192 | 193 | static Value* getCast(Value* v, Type* t, BasicBlock* bb) { 194 | Instruction::CastOps cops = CastInst::getCastOpcode(v, true, t, true); 195 | return CastInst::Create(cops, v, t, "", bb); 196 | } 197 | 198 | static void normalize_type(Value*& v1, Value*& v2, BasicBlock* bb) { 199 | Type* t1 = v1->getType(); 200 | Type* t2 = v2->getType(); 201 | if (t1->isDoubleTy() || t2->isDoubleTy()) { 202 | if (!t1->isDoubleTy()) v1 = getCast(v1, t2, bb); 203 | if (!t2->isDoubleTy()) v2 = getCast(v2, t1, bb); 204 | return; 205 | } 206 | if (t1->isFloatTy() || t2->isFloatTy()) { 207 | if (!t1->isFloatTy()) v1 = getCast(v1, t2, bb); 208 | if (!t2->isFloatTy()) v2 = getCast(v2, t1, bb); 209 | return; 210 | } 211 | } 212 | 213 | 214 | LValue llcg_llvm::Opt2(const string& opt, LValue value1, LValue value2) { 215 | Value* ans1 = *LLVALUE(value1); 216 | Value* ans2 = *LLVALUE(value2); 217 | Type* t1 = ans1->getType(); 218 | Type* t2 = ans2->getType(); 219 | Instruction::BinaryOps instr; 220 | if (t1->isIntegerTy() && t2->isIntegerTy() && t1->getIntegerBitWidth()==t2->getIntegerBitWidth() ) { 221 | if (opt == "+") { instr = Instruction::Add; goto binOper; } 222 | if (opt == "-") { instr = Instruction::Sub; goto binOper; } 223 | if (opt == "*") { instr = Instruction::Mul; goto binOper; } 224 | if (opt == "/") { instr = Instruction::SDiv; goto binOper; } 225 | if (opt == "%") { instr = Instruction::SRem; goto binOper; } 226 | if (opt == "<<") { instr = Instruction::Shl; goto binOper; } 227 | if (opt == ">>") { instr = Instruction::LShr; goto binOper; } // 注意,这里没处理有符号数和无符号数的问题 AShr(arithmetic) 228 | if (opt == "&") { instr = Instruction::And; goto binOper; } 229 | if (opt == "|") { instr = Instruction::Or; goto binOper; } 230 | if (opt == "^") { instr = Instruction::Xor; goto binOper; } 231 | } else { 232 | normalize_type(ans1, ans2, nowBlock); 233 | if (opt == "+") { instr = Instruction::FAdd; goto binOper; } 234 | if (opt == "-") { instr = Instruction::FSub; goto binOper; } 235 | if (opt == "*") { instr = Instruction::FMul; goto binOper; } 236 | if (opt == "/") { instr = Instruction::FDiv; goto binOper; } 237 | if (opt == "%") { instr = Instruction::FRem; goto binOper; } 238 | } 239 | 240 | binOper: 241 | Value* ret = BinaryOperator::Create(instr, ans1, ans2, "", nowBlock); 242 | return LValue(new llvm_value(ret)); 243 | } 244 | 245 | LValue llcg_llvm::Cmp(const string& opt, LValue value1, LValue value2) { 246 | Value* ans1 = *LLVALUE(value1); 247 | Value* ans2 = *LLVALUE(value2); 248 | Type* t1 = ans1->getType(); 249 | Type* t2 = ans2->getType(); 250 | CmpInst::Predicate instp; 251 | if (t1->isIntegerTy() && t2->isIntegerTy() && t1->getIntegerBitWidth()==t2->getIntegerBitWidth() ) { 252 | if (opt == "==") { instp = CmpInst::Predicate::ICMP_EQ; goto cmpOper; } 253 | if (opt == "!=") { instp = CmpInst::Predicate::ICMP_NE; goto cmpOper; } 254 | if (opt == "<=") { instp = CmpInst::Predicate::ICMP_SLE; goto cmpOper; } 255 | if (opt == ">=") { instp = CmpInst::Predicate::ICMP_SGE; goto cmpOper; } 256 | if (opt == "<") { instp = CmpInst::Predicate::ICMP_SLT; goto cmpOper; } 257 | if (opt == ">") { instp = CmpInst::Predicate::ICMP_SGT; goto cmpOper; } 258 | } else { 259 | normalize_type(ans1, ans2, nowBlock); 260 | if (opt == "==") { instp = CmpInst::Predicate::FCMP_OEQ; goto cmpOper; } 261 | if (opt == "!=") { instp = CmpInst::Predicate::FCMP_ONE; goto cmpOper; } 262 | if (opt == "<=") { instp = CmpInst::Predicate::FCMP_OLE; goto cmpOper; } 263 | if (opt == ">=") { instp = CmpInst::Predicate::FCMP_OGE; goto cmpOper; } 264 | if (opt == "<") { instp = CmpInst::Predicate::FCMP_OLT; goto cmpOper; } 265 | if (opt == ">") { instp = CmpInst::Predicate::FCMP_OGT; goto cmpOper; } 266 | } 267 | 268 | cmpOper: 269 | Value* ret = CmpInst::Create(Instruction::ICmp, instp, ans1, ans2, "", nowBlock); 270 | return LValue(new llvm_value(ret)); 271 | } 272 | 273 | LValue llcg_llvm::Assignment(const string& opt, LValue value1, LValue value2) { 274 | Value* ans1 = *LLVALUE(value1); 275 | Value* ans2 = *LLVALUE(value2); 276 | if (opt == "=") { 277 | Value* ret = new StoreInst(ans2, ans1, false, nowBlock); 278 | return LValue(new llvm_value(ret)); 279 | } 280 | AtomicRMWInst::BinOp bop; 281 | if (opt == "+=") { bop = AtomicRMWInst::BinOp::Add; goto rmwOper; } 282 | if (opt == "-=") { bop = AtomicRMWInst::BinOp::Sub; goto rmwOper; } 283 | if (opt == "&=") { bop = AtomicRMWInst::BinOp::And; goto rmwOper; } 284 | if (opt == "|=") { bop = AtomicRMWInst::BinOp::Or; goto rmwOper; } 285 | if (opt == "^=") { bop = AtomicRMWInst::BinOp::Xor; goto rmwOper; } 286 | rmwOper: 287 | Value* ret = new AtomicRMWInst(bop, ans1, ans2, AtomicOrdering::SequentiallyConsistent, 288 | SynchronizationScope::CrossThread, nowBlock); 289 | return LValue(new llvm_value(ret)); 290 | } 291 | 292 | LValue llcg_llvm::Dot(LValue value, int num) { 293 | Value* ans = *LLVALUE(value); 294 | ConstantInt* zero = ConstantInt::get(Type::getInt32Ty(context), 0); 295 | ConstantInt* n = ConstantInt::get(Type::getInt32Ty(context), num); 296 | std::vector indices; 297 | indices.push_back(zero); 298 | indices.push_back(n); 299 | GetElementPtrInst* ptr = GetElementPtrInst::CreateInBounds(ans, indices, "", nowBlock); 300 | return LValue(new llvm_value(ptr)); 301 | } 302 | 303 | LValue llcg_llvm::Select(LValue value, vector& args) { 304 | Value* v = *LLVALUE(value); 305 | Value* len_array; 306 | errs() << "type:" << *(v->getType()); 307 | if (!(v->getType()->isPointerTy())) return nullptr; 308 | if (v->getType()->getPointerElementType()->isIntegerTy(64)) 309 | len_array = v; 310 | else 311 | len_array = CastInst::CreatePointerCast(v, Type::getInt64PtrTy(context)); 312 | Value* index; 313 | if (args.size() != 0) { 314 | index = *LLVALUE(args[0]); 315 | for (int i = -2, j = 0; j < args.size()-1; --i, ++j) { 316 | Value* len = new LoadInst(ptrMove(len_array, i), "", false, nowBlock); 317 | index = BinaryOperator::Create(Instruction::Mul, index, len, "", nowBlock); 318 | Value* other = *LLVALUE(args[j+1]); 319 | index = BinaryOperator::Create(Instruction::Add, index, other, "", nowBlock); 320 | } 321 | } else { errs() << "error index\n"; } 322 | 323 | std::vector indices; 324 | indices.push_back(index); 325 | GetElementPtrInst* ptr = GetElementPtrInst::CreateInBounds(v, indices, "", nowBlock); 326 | return LValue(new llvm_value(ptr)); 327 | } 328 | 329 | GetElementPtrInst* llcg_llvm::ptrMove(Value* v, int n) { 330 | std::vector indices; 331 | ConstantInt* num = ConstantInt::get(Type::getInt64Ty(context), n); 332 | indices.push_back(num); 333 | GetElementPtrInst* p1 = GetElementPtrInst::CreateInBounds(v, indices, "", nowBlock); 334 | return p1; 335 | } 336 | 337 | 338 | void llcg_llvm::If(LValue cond, LValue father, LValue true_block, LValue true_block_end, 339 | LValue false_block, LValue false_block_end, bool isElseWork) { 340 | 341 | // 由于动态转换模板的特殊性,需要先转换成Value*类型 342 | Value* condition = *LLVALUE(cond); 343 | Value* _father = *LLVALUE(father); 344 | Value* _true_block = *LLVALUE(true_block); 345 | Value* _false_block = *LLVALUE(false_block); 346 | Value* _true_block_end = *LLVALUE(true_block_end); 347 | Value* _false_block_end = *LLVALUE(false_block_end); 348 | 349 | BasicBlock* father_block = dyn_cast(_father); 350 | BasicBlock* _true_block_ = dyn_cast(_true_block); 351 | BasicBlock* _false_block_ = dyn_cast(_false_block); 352 | BasicBlock* _true_block_end_ = dyn_cast(_true_block_end); 353 | BasicBlock* _false_block_end_ = dyn_cast(_false_block_end); 354 | 355 | if (isElseWork) { 356 | BasicBlock* end_block = createBlock(); 357 | if (_true_block_end_->getTerminator() == NULL) 358 | BranchInst::Create(end_block, _true_block_end_); 359 | if (_false_block_end_->getTerminator() == NULL) 360 | BranchInst::Create(end_block, _false_block_end_); 361 | } else { 362 | if (_true_block_end_->getTerminator() == NULL) 363 | BranchInst::Create(_false_block_, _true_block_end_); 364 | } 365 | BranchInst* branch = BranchInst::Create(_true_block_, _false_block_, condition, father_block); 366 | } 367 | 368 | void llcg_llvm::For(LValue cond, LValue init, LValue pd, LValue work, LValue statement, LValue statement_end, LValue end) { 369 | Value* condition = *LLVALUE(cond); 370 | Value* _init = *LLVALUE(init); 371 | Value* _pd = *LLVALUE(pd); 372 | Value* _work = *LLVALUE(work); 373 | Value* _statement = *LLVALUE(statement); 374 | Value* _statement_end = *LLVALUE(statement_end); 375 | Value* _end = *LLVALUE(end); 376 | BasicBlock* init_block = dyn_cast(_init); 377 | BasicBlock* end_block = dyn_cast(_pd); 378 | BasicBlock* do_block = dyn_cast(_work); 379 | BasicBlock* work_block = dyn_cast(_statement); 380 | BasicBlock* work_block_end = dyn_cast(_statement_end); 381 | BasicBlock* false_block = dyn_cast(_end); 382 | 383 | BranchInst* branch = BranchInst::Create(work_block, false_block, condition, end_block); 384 | if (init_block->getTerminator() == NULL) 385 | BranchInst::Create(end_block, init_block); 386 | if (work_block_end->getTerminator() == NULL) 387 | BranchInst::Create(do_block, work_block_end); 388 | if (do_block->getTerminator() == NULL) 389 | BranchInst::Create(end_block, do_block); 390 | } 391 | 392 | void llcg_llvm::While(LValue cond, LValue father, LValue pd, LValue statement, LValue statement_end, LValue end) { 393 | Value* condition = *LLVALUE(cond); 394 | Value* _father = *LLVALUE(father); 395 | Value* _pd = *LLVALUE(pd); 396 | Value* _statement = *LLVALUE(statement); 397 | Value* _statement_end = *LLVALUE(statement_end); 398 | Value* _end = *LLVALUE(end); 399 | BasicBlock* father_block = dyn_cast(_father); 400 | BasicBlock* pd_block = dyn_cast(_pd); 401 | BasicBlock* true_block = dyn_cast(_statement); 402 | BasicBlock* true_block_end = dyn_cast(_statement_end); 403 | BasicBlock* false_block = dyn_cast(_end); 404 | 405 | // 生成while循环 406 | BranchInst* branch = BranchInst::Create(true_block, false_block, condition, pd_block); 407 | if (father_block->getTerminator() == NULL) 408 | BranchInst::Create(pd_block, father_block); 409 | if (true_block_end->getTerminator() == NULL) 410 | BranchInst::Create(pd_block, true_block_end); 411 | } 412 | 413 | void llcg_llvm::DoWhile(LValue statement, LValue pd) { 414 | 415 | } 416 | 417 | void llcg_llvm::DoUntil(LValue statement, LValue pd) { 418 | 419 | } 420 | 421 | void llcg_llvm::Goto(LValue target) { 422 | if (nowBlock->getTerminator()) return; 423 | Value* v = *LLVALUE(target); 424 | BasicBlock* target_block = dyn_cast(v); 425 | BranchInst::Create(target_block, nowBlock); 426 | } 427 | 428 | LValue llcg_llvm::New(LValue var_type, vector& args, const string& funcname) { 429 | Type* t = *LLTYPE(var_type); 430 | Type* ITy = Type::getInt64Ty(context); 431 | Constant* AllocSize = ConstantExpr::getSizeOf(t); 432 | Instruction* Malloc; 433 | if (funcname == "") { 434 | Malloc = CallInst::CreateMalloc(nowBlock, ITy, t, AllocSize); 435 | Malloc->insertAfter(&(nowBlock->back())); 436 | } else { 437 | Function* f = (Function*)(M->getOrInsertFunction(funcname, getMallocType())); 438 | f->setCallingConv(CallingConv::C); 439 | vector fargs; 440 | fargs.push_back(AllocSize); 441 | CallInst* call = CallInst::Create(f, fargs, "", nowBlock); 442 | Malloc = CastInst::CreatePointerCast(call, t->getPointerTo(), "", nowBlock); 443 | } 444 | return LValue(new llvm_value(Malloc)); 445 | } 446 | 447 | LValue llcg_llvm::NewArray(LValue var_type, vector& wd, const string& funcname) { 448 | // 这里实现自定义的数组malloc函数 449 | Type* t = *LLTYPE(var_type); 450 | ConstantInt* zero = ConstantInt::get(Type::getInt64Ty(context), 0); 451 | vector args; 452 | Constant* AllocSize = ConstantExpr::getSizeOf(t); // 获取当前类型的大小 453 | t = t->getPointerTo(); // 将t转换为指针类型 454 | Value* Malloc; CallInst *call; 455 | 456 | args.push_back(AllocSize); 457 | for (auto p : wd) { 458 | Value* v = *LLVALUE(p); 459 | args.push_back(v); 460 | } 461 | args.push_back(zero); 462 | if (funcname == "") { 463 | string func_name = "malloc_array"; 464 | call = CallInst::Create(M->getFunction(func_name), 465 | args, "", nowBlock); 466 | } else { 467 | Function* f = (Function*)(M->getOrInsertFunction(funcname, getMallocArrayType())); 468 | f->setCallingConv(CallingConv::C); 469 | call = CallInst::Create(f, args, "", nowBlock); 470 | } 471 | 472 | Malloc = CastInst::CreatePointerCast(call, t, "", nowBlock); 473 | return LValue(new llvm_value(Malloc)); 474 | } 475 | 476 | LValue llcg_llvm::Delete(LValue pointer, const string& funcname) { 477 | Value* ptr = *LLVALUE(pointer); 478 | Instruction* Free = CallInst::CreateFree(ptr, nowBlock); 479 | return LValue(new llvm_value(Free)); 480 | } 481 | 482 | LValue llcg_llvm::DeleteArray(LValue pointer, const string& funcname) { 483 | return NULL; 484 | } 485 | 486 | 487 | 488 | LValue llcg_llvm::Return() { 489 | Value* ret = ReturnInst::Create(context, nullptr, nowBlock); 490 | return LValue(new llvm_value(ret)); 491 | } 492 | 493 | LValue llcg_llvm::Return(LValue var) { 494 | Value* v = *LLVALUE(var); 495 | Value* ret = ReturnInst::Create(context, v, nowBlock); 496 | return LValue(new llvm_value(ret)); 497 | } 498 | 499 | 500 | 501 | 502 | LValue llcg_llvm::Int8() { 503 | return LValue(new llvm_type(Type::getInt8Ty(context))); 504 | } 505 | 506 | LValue llcg_llvm::Int16() { 507 | return LValue(new llvm_type(Type::getInt16Ty(context))); 508 | } 509 | 510 | LValue llcg_llvm::Int32() { 511 | return LValue(new llvm_type(Type::getInt32Ty(context))); 512 | } 513 | 514 | LValue llcg_llvm::Int64() { 515 | return LValue(new llvm_type(Type::getInt64Ty(context))); 516 | } 517 | 518 | LValue llcg_llvm::Float() { 519 | return LValue(new llvm_type(Type::getFloatTy(context))); 520 | } 521 | 522 | LValue llcg_llvm::Double() { 523 | return LValue(new llvm_type(Type::getDoubleTy(context))); 524 | } 525 | 526 | LValue llcg_llvm::Void() { 527 | return LValue(new llvm_type(Type::getVoidTy(context))); 528 | } 529 | 530 | 531 | Constant* llcg_llvm::geti8StrVal(Module& M, char const* str, Twine const& name) { 532 | LLVMContext& ctx = M.getContext(); // 千万别用Global Context 533 | Constant* strConstant = ConstantDataArray::getString(ctx, str); 534 | GlobalVariable* GVStr = 535 | new GlobalVariable(M, strConstant->getType(), true, 536 | GlobalValue::InternalLinkage, strConstant, name); 537 | Constant* zero = Constant::getNullValue(IntegerType::getInt32Ty(ctx)); 538 | Constant* indices[] = {zero, zero}; 539 | #if defined(LLVM_3_7) 540 | Constant* strVal = ConstantExpr::getGetElementPtr(GVStr->getType(), GVStr, indices, true); 541 | #else 542 | Constant* strVal = ConstantExpr::getGetElementPtr(GVStr, indices, true); 543 | #endif 544 | return strVal; 545 | } 546 | 547 | Constant* llcg_llvm::getPtrArray(Module& M, vector& args_list) { 548 | LLVMContext& ctx = M.getContext(); // 千万别用Global Context 549 | ArrayType* arr_type = ArrayType::get(Type::getInt8PtrTy(M.getContext()), args_list.size()); 550 | Constant* strConstant = ConstantArray::get(arr_type, args_list); 551 | GlobalVariable* GVStr = 552 | new GlobalVariable(M, arr_type, true, 553 | GlobalValue::InternalLinkage, strConstant, ""); 554 | Constant* zero = Constant::getNullValue(IntegerType::getInt32Ty(ctx)); 555 | Constant* indices[] = {zero, zero}; 556 | #if defined(LLVM_3_7) 557 | Constant* strVal = ConstantExpr::getGetElementPtr(GVStr->getType(), GVStr, indices, true); 558 | #else 559 | Constant* strVal = ConstantExpr::getGetElementPtr(GVStr, indices, true); 560 | #endif 561 | return strVal; 562 | } 563 | 564 | LValue llcg_llvm::ConstString(const string& str) { 565 | return LValue(new llvm_value(geti8StrVal(*M, str.c_str(), ""))); 566 | } 567 | 568 | LValue llcg_llvm::ConstInt(int num) { 569 | Type* t = Type::getInt64Ty(context); 570 | return LValue(new llvm_value(ConstantInt::get(t, num))); 571 | } 572 | 573 | LValue llcg_llvm::ConstDouble(double num) { 574 | Type* t = Type::getDoubleTy(context); 575 | return LValue(new llvm_value(ConstantFP::get(t, num))); 576 | } 577 | 578 | extern const LibFunc stdlibs[]; 579 | 580 | void llcg_llvm::BeginModule(const string& name) { 581 | M = llvm::make_unique(name, context); 582 | register_stdlib(M.get(), stdlibs); 583 | nowBlock = NULL; 584 | nowFunc = NULL; 585 | } 586 | 587 | void llcg_llvm::register_stdlib(Module* M, const LibFunc* libs_func) { 588 | while (*libs_func != NULL) { 589 | (*libs_func)(M); 590 | ++libs_func; 591 | } 592 | } 593 | 594 | extern const LibFunc metalibs[]; 595 | 596 | void llcg_llvm::register_metalib() { 597 | register_stdlib(meta_M.get(), metalibs); 598 | } 599 | 600 | void llcg_llvm::SetNowBasicBlock(LValue nowBlock) { 601 | Value* v = *LLVALUE(nowBlock); 602 | this->nowBlock = dyn_cast(v); 603 | } 604 | 605 | 606 | LValue llcg_llvm::GetNowBasicBlock() { 607 | return LValue(new llvm_value(nowBlock)); 608 | } 609 | 610 | LValue llcg_llvm::CreateBasicBlock() { 611 | return LValue(new llvm_value(createBlock())); 612 | } 613 | 614 | LValue llcg_llvm::CreateBasicBlock(LValue func) { 615 | Value* v = *LLVALUE(func); 616 | Function* f = dyn_cast(v); 617 | return LValue(new llvm_value(createBlock(f))); 618 | } 619 | 620 | void llcg_llvm::VerifyAndWrite(const string& outfile_name) { 621 | verifyModuleAndWrite(M.get(), outfile_name); 622 | } 623 | 624 | void llcg_llvm::verifyModuleAndWrite(llvm::Module* M, const string& outfile_name) { 625 | // 输出编译后的LLVM可读字节码 626 | outs() << "LLVM module:\n\n" << *M; 627 | outs() << "\n\n"; 628 | outs().flush(); 629 | 630 | // 校验问题, 这个函数需要一个输出流来打印错误信息 631 | outs() << "\n"; 632 | if (verifyModule(*M, &outs())) { 633 | outs() << "构建LLVM字节码出错!\n"; 634 | exit(1); 635 | } 636 | 637 | std::error_code ErrInfo; 638 | raw_fd_ostream fs(outfile_name+".bitcode", ErrInfo, sys::fs::F_None); 639 | fs << *M << "\n"; 640 | fs.flush(); 641 | 642 | // 输出二进制BitCode到.bc文件 643 | 644 | raw_fd_ostream out(outfile_name, ErrInfo, sys::fs::F_None); 645 | WriteBitcodeToFile(M, out); 646 | out.flush(); 647 | } 648 | 649 | void llcg_llvm::MakeMetaModule(const string& outfile_name, const string& module_name) { 650 | Module* M = meta_M.get(); 651 | M->setModuleIdentifier(module_name); 652 | 653 | Function *F = M->getFunction("elite_meta_init"); 654 | BasicBlock& bb = F->getEntryBlock(); // 仅有一个BasicBlock,所以这样写可以 655 | if (bb.getTerminator() == NULL) // 处理函数结尾返回 656 | ReturnInst::Create(context, &bb); 657 | Type* function_ptr = F->getFunctionType()->getPointerTo(); // 获取函数指针类型 658 | 659 | vector type_list; 660 | type_list.push_back(Type::getInt32Ty(M->getContext())); 661 | type_list.push_back(function_ptr); 662 | type_list.push_back(Type::getInt8PtrTy(M->getContext())); 663 | 664 | vector init_list; 665 | init_list.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 65535)); 666 | init_list.push_back(ConstantExpr::getBitCast(F, function_ptr)); 667 | init_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 668 | 669 | StructType* st = StructType::create(type_list, ""); 670 | ArrayType* at = ArrayType::get(st, 1); 671 | vector array_init_list; 672 | array_init_list.push_back(ConstantStruct::get(st, init_list)); 673 | Constant* init_var = ConstantArray::get(at, array_init_list); 674 | 675 | GlobalVariable* gv = new GlobalVariable( 676 | *M, at, false, GlobalValue::AppendingLinkage, init_var, "llvm.global_ctors" 677 | ); 678 | 679 | verifyModuleAndWrite(M, outfile_name); 680 | } 681 | 682 | 683 | 684 | BasicBlock* llcg_llvm::createBlock() { 685 | return nowBlock = BasicBlock::Create(context, "", nowFunc); 686 | } 687 | 688 | BasicBlock* llcg_llvm::createBlock(Function* f) { 689 | nowFunc = f; 690 | return nowBlock = BasicBlock::Create(context, "entry", f); 691 | } 692 | 693 | void llcg_llvm::MakeMetaList(vector& list) { 694 | Module* M = meta_M.get(); 695 | Function* F = M->getFunction("elite_meta_init"); 696 | vector args_list; 697 | for (int i = 0; i < list.size(); ++i) { 698 | args_list.push_back(geti8StrVal(*M, list[i].c_str(), "")); 699 | } 700 | args_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 701 | BasicBlock& bb = F->getEntryBlock(); 702 | Function* FuncF = M->getFunction("elite_meta_list"); 703 | Constant* list_vec = getPtrArray(*M, args_list); 704 | vector args; 705 | args.push_back(list_vec); 706 | CallInst::Create(FuncF, args, "", &bb); 707 | } 708 | 709 | void llcg_llvm::MakeMetaList(const string& name, vector& list, LValue fp) { 710 | Module* M = meta_M.get(); 711 | Function* F = M->getFunction("elite_meta_init"); 712 | vector args_list; 713 | for (int i = 0; i < list.size(); ++i) { 714 | args_list.push_back(geti8StrVal(*M, list[i].c_str(), "")); 715 | // Constant* c = init_list[i]; 716 | // if (c != NULL) 717 | // init_meta_list.push_back(ConstantAsMetadata::get(c)); 718 | // else 719 | // init_meta_list.push_back(MDString::get(M->getContext(), "NULL")); 720 | } 721 | args_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 722 | 723 | Constant* list_vec = getPtrArray(*M, args_list); 724 | vector args; 725 | args.push_back(geti8StrVal(*M, name.c_str(), "")); // 第一个参数, 函数名 726 | args.push_back(list_vec); // 第二个参数, 函数类型定义字符串列表 727 | 728 | Type* ft = *LLTYPE(fp); 729 | Function* nowFunc = dyn_cast(M->getOrInsertFunction(name, (FunctionType*)ft)); 730 | Type* nowType = Type::getInt8PtrTy(M->getContext()); 731 | args.push_back(ConstantExpr::getBitCast(nowFunc, nowType)); 732 | BasicBlock& bb = F->getEntryBlock(); 733 | Function* FuncF = M->getFunction("elite_meta_function"); 734 | CallInst::Create(FuncF, args, "", &bb); 735 | } 736 | 737 | 738 | FunctionType* llcg_llvm::getMallocType() { 739 | if (malloc_type != NULL) return malloc_type; 740 | 741 | Type* ret = Type::getVoidTy(context)->getPointerTo(); 742 | vector types; 743 | types.push_back(Type::getInt64Ty(context)); 744 | malloc_type = FunctionType::get(ret, types, /*vararg*/false); 745 | return malloc_type; 746 | } 747 | 748 | FunctionType* llcg_llvm::getMallocArrayType() { 749 | if (malloc_array_type != NULL) return malloc_array_type; 750 | 751 | Type* ret = Type::getVoidTy(context)->getPointerTo(); 752 | vector types; 753 | types.push_back(Type::getInt64Ty(context)); 754 | malloc_array_type = FunctionType::get(ret, types, /*vararg*/true); 755 | return malloc_array_type; 756 | } 757 | 758 | 759 | void llcg_llvm::CloseTerminator(LValue basicblock, LValue target) { 760 | Value* _basicblock = *LLVALUE(basicblock); 761 | Value* _target = *LLVALUE(target); 762 | BasicBlock* bb = dyn_cast(_basicblock); 763 | BasicBlock* tg = dyn_cast(_target); 764 | if (bb->getTerminator() == NULL) 765 | BranchInst::Create(tg, bb); 766 | } 767 | 768 | FunctionType* llcg_llvm::malloc_type = NULL; 769 | FunctionType* llcg_llvm::malloc_array_type = NULL; 770 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llcg_llvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 21:37:15 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 17:16:39 6 | */ 7 | 8 | 9 | #ifndef LLCG_LLVM_H 10 | #define LLCG_LLVM_H 11 | 12 | #include "LLCG/llcg.h" 13 | #include "LLCG/llcg_l.h" 14 | 15 | #include "llvm/IR/Verifier.h" 16 | #include "llvm/ExecutionEngine/GenericValue.h" 17 | #include "llvm/ExecutionEngine/Interpreter.h" 18 | #include "llvm/IR/Constants.h" 19 | #include "llvm/IR/DerivedTypes.h" 20 | #include "llvm/IR/Instructions.h" 21 | #include "llvm/IR/LLVMContext.h" 22 | #include "llvm/IR/Module.h" 23 | #include "llvm/IR/IRBuilder.h" 24 | #include "llvm/Support/ManagedStatic.h" 25 | #include "llvm/Support/TargetSelect.h" 26 | #include "llvm/Support/raw_ostream.h" 27 | #include "llvm/Bitcode/ReaderWriter.h" 28 | #include "llvm/Support/FileSystem.h" 29 | #include "llvm/IR/ValueSymbolTable.h" 30 | 31 | using namespace llvm; 32 | 33 | typedef void (*LibFunc)(Module*); 34 | 35 | class llcg_llvm : public llcg, public llcg_l 36 | { 37 | public: 38 | llcg_llvm(); 39 | ~llcg_llvm(); 40 | 41 | virtual LValue FuncType(FunctionModel* fmodel); // 返回FunctionType 42 | virtual LValue FuncType(LValue ret_type, vector& types, bool isNotSure = false); 43 | virtual LValue GetOrInsertFunction(FunctionModel* fmodel); // 返回Function 44 | virtual LValue GetOrInsertFunction(const string& name, LValue func_type); 45 | virtual LValue GetOrInsertFunction(const string& name, LValue ret_type, vector& types, bool isNotSure = false); 46 | virtual void FunctionBodyBegin(LValue func, vector& name_list); // 设置当前BasicBlock 47 | virtual void FunctionBodyEnd(); // 处理函数结束 48 | virtual LValue getFunction(const string& name); // 从当前模块中获取一个函数 49 | virtual LValue Call(FunctionModel* fmodel, vector& args); // 返回CallInst 50 | virtual LValue Call(LValue func, vector& args); 51 | virtual LValue Struct(StructModel* smodel); // 返回StructType 52 | virtual LValue Struct(LValue _struct, vector& types); 53 | virtual LValue DeclareStruct(const string& name); 54 | virtual LValue DefVar(LValue var_type, const string& name); // 返回分配的地址 55 | virtual LValue DefVar(LValue var_type, const string& name, LValue init); 56 | virtual LValue DefGlobalVar(LValue var_type, const string& name); 57 | virtual LValue DefGlobalVar(LValue var_type, const string& name, LValue init); 58 | virtual LValue Load(LValue var_addr); 59 | virtual LValue Store(LValue var_addr, LValue value); 60 | virtual LValue Opt1(const string& opt, LValue value); 61 | virtual LValue Opt2(const string& opt, LValue value1, LValue value2); 62 | virtual LValue Cmp(const string& opt, LValue value1, LValue value2); 63 | virtual LValue Assignment(const string& opt, LValue value1, LValue value2); 64 | virtual LValue Dot(LValue value, int num); 65 | virtual LValue Select(LValue value, vector& args); 66 | virtual void If(LValue cond, LValue father, LValue true_block, LValue true_block_end, 67 | LValue false_block, LValue false_block_end, bool isElseWork); 68 | virtual void For(LValue cond, LValue init, LValue pd, LValue work, LValue statement, LValue statement_end, LValue end); 69 | virtual void While(LValue cond, LValue father, LValue pd, LValue statement, LValue statement_end, LValue end); 70 | virtual void DoWhile(LValue statement, LValue pd); 71 | virtual void DoUntil(LValue statement, LValue pd); 72 | virtual void Goto(LValue target); 73 | virtual LValue New(LValue var_type, vector& args, const string& funcname = ""); 74 | virtual LValue NewArray(LValue var_type, vector& wd, const string& funcname = ""); 75 | virtual LValue Delete(LValue pointer, const string& funcname = ""); 76 | virtual LValue DeleteArray(LValue pointer, const string& funcname = ""); 77 | virtual LValue Return(); 78 | virtual LValue Return(LValue var); 79 | 80 | virtual LValue Int8(); 81 | virtual LValue Int16(); 82 | virtual LValue Int32(); 83 | virtual LValue Int64(); 84 | virtual LValue Float(); 85 | virtual LValue Double(); 86 | virtual LValue Void(); 87 | 88 | virtual LValue ConstString(const string& str); 89 | virtual LValue ConstInt(int num); 90 | virtual LValue ConstDouble(double num); 91 | 92 | virtual void BeginModule(const string& name); 93 | virtual void VerifyAndWrite(const string& outfile_name); 94 | virtual void MakeMetaModule(const string& outfile_name, const string& module_name); 95 | 96 | virtual LValue GetNowBasicBlock(); 97 | virtual LValue CreateBasicBlock(); 98 | virtual LValue CreateBasicBlock(LValue func); 99 | 100 | virtual void MakeMetaList(vector& list); 101 | virtual void MakeMetaList(const string& name, vector& list, LValue fp); 102 | virtual void CloseTerminator(LValue basicblock, LValue target); 103 | virtual void SetNowBasicBlock(LValue nowBlock); 104 | 105 | /* 下面是llcg_l的继承 */ 106 | 107 | virtual lvalue* l_FuncType(FunctionModel* fmodel); // 返回FunctionType 108 | virtual lvalue* l_FuncType(lvalue* ret_type, vector& types, bool isNotSure = false); 109 | virtual lvalue* l_GetOrInsertFunction(FunctionModel* fmodel); // 返回Function 110 | virtual lvalue* l_GetOrInsertFunction(const string& name, lvalue* func_type); 111 | virtual lvalue* l_GetOrInsertFunction(const string& name, lvalue* ret_type, vector& types, bool isNotSure = false); 112 | virtual void l_FunctionBodyBegin(lvalue* func, vector& name_list); // 设置当前BasicBlock 113 | virtual void l_FunctionBodyEnd(); // 处理函数结束 114 | virtual lvalue* l_getFunction(const string& name); // 从当前模块中获取一个函数 115 | virtual lvalue* l_Call(FunctionModel* fmodel, vector& args); // 返回CallInst 116 | virtual lvalue* l_Call(lvalue* func, vector& args); 117 | virtual lvalue* l_Struct(StructModel* smodel); // 返回StructType 118 | virtual lvalue* l_Struct(lvalue* _struct, vector& types); 119 | virtual lvalue* l_DeclareStruct(const string& name); 120 | virtual lvalue* l_DefVar(lvalue* var_type, const string& name); // 返回分配的地址 121 | virtual lvalue* l_DefVar(lvalue* var_type, const string& name, lvalue* init); 122 | virtual lvalue* l_DefGlobalVar(lvalue* var_type, const string& name); 123 | virtual lvalue* l_DefGlobalVar(lvalue* var_type, const string& name, lvalue* init); 124 | virtual lvalue* l_Load(lvalue* var_addr); 125 | virtual lvalue* l_Store(lvalue* var_addr, lvalue* value); 126 | virtual lvalue* l_Opt1(const string& opt, lvalue* value); 127 | virtual lvalue* l_Opt2(const string& opt, lvalue* value1, lvalue* value2); 128 | virtual lvalue* l_Cmp(const string& opt, lvalue* value1, lvalue* value2); 129 | virtual lvalue* l_Assignment(const string& opt, lvalue* value1, lvalue* value2); 130 | virtual lvalue* l_Dot(lvalue* value, int num); 131 | virtual lvalue* l_Select(lvalue* value, vector& args); 132 | virtual void l_If(lvalue* cond, lvalue* father, lvalue* true_block, lvalue* true_block_end, 133 | lvalue* false_block, lvalue* false_block_end, bool isElseWork); 134 | virtual void l_For(lvalue* cond, lvalue* init, lvalue* pd, lvalue* work, lvalue* statement, lvalue* statement_end, lvalue* end); 135 | virtual void l_While(lvalue* cond, lvalue* father, lvalue* pd, lvalue* statement, lvalue* statement_end, lvalue* end); 136 | virtual void l_DoWhile(lvalue* statement, lvalue* pd); 137 | virtual void l_DoUntil(lvalue* statement, lvalue* pd); 138 | virtual lvalue* l_New(lvalue* var_type, vector& args, const string& funcname = ""); 139 | virtual lvalue* l_NewArray(lvalue* var_type, vector& wd, const string& funcname = ""); 140 | virtual lvalue* l_Delete(lvalue* pointer, const string& funcname = ""); 141 | virtual lvalue* l_DeleteArray(lvalue* pointer, const string& funcname = ""); 142 | virtual lvalue* l_Return(); 143 | virtual lvalue* l_Return(lvalue* var); 144 | 145 | virtual lvalue* l_Int8(); 146 | virtual lvalue* l_Int16(); 147 | virtual lvalue* l_Int32(); 148 | virtual lvalue* l_Int64(); 149 | virtual lvalue* l_Float(); 150 | virtual lvalue* l_Double(); 151 | virtual lvalue* l_Void(); 152 | 153 | virtual lvalue* l_ConstString(const string& str); 154 | virtual lvalue* l_ConstInt(int num); 155 | virtual lvalue* l_ConstDouble(double num); 156 | 157 | virtual void l_BeginModule(const string& name); 158 | virtual void l_VerifyAndWrite(const string& outfile_name); 159 | virtual void l_MakeMetaModule(const string& outfile_name, const string& module_name); 160 | 161 | virtual lvalue* l_GetNowBasicBlock(); 162 | virtual lvalue* l_CreateBasicBlock(); 163 | virtual lvalue* l_CreateBasicBlock(lvalue* func); 164 | 165 | virtual void l_MakeMetaList(vector& list); 166 | virtual void l_MakeMetaList(const string& name, vector& list, lvalue* fp); 167 | virtual void l_CloseTerminator(lvalue* basicblock, lvalue* target); 168 | 169 | protected: 170 | 171 | // 当前的LLVM Module 172 | unique_ptr M; 173 | // 模块元数据 Module 174 | unique_ptr meta_M; 175 | 176 | LLVMContext context; 177 | Function* nowFunc; 178 | BasicBlock* nowBlock; 179 | 180 | void register_stdlib(Module* M, const LibFunc*); 181 | void register_metalib(); 182 | void verifyModuleAndWrite(llvm::Module* M, const string& outfile_name); 183 | static Constant* geti8StrVal(Module& M, char const* str, Twine const& name); 184 | static Constant* getPtrArray(Module& M, vector& args_list); 185 | GetElementPtrInst* ptrMove(Value* v, int n); 186 | BasicBlock* createBlock(); 187 | BasicBlock* createBlock(Function* f); 188 | 189 | FunctionType* getMallocType(); 190 | FunctionType* getMallocArrayType(); 191 | static FunctionType* malloc_type; 192 | static FunctionType* malloc_array_type; 193 | 194 | }; 195 | 196 | 197 | 198 | 199 | #endif // LLCG_LLVM_H 200 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llcg_llvm_l.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-12-24 17:54:40 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2016-01-01 17:17:52 6 | */ 7 | 8 | #include "llcg_llvm.h" 9 | 10 | #include "llvm_value.h" 11 | #include "llvm_type.h" 12 | 13 | lvalue* llcg_llvm::l_FuncType(FunctionModel* fmodel) { 14 | return nullptr; 15 | } // 返回FunctionType 16 | 17 | lvalue* llcg_llvm::l_FuncType(lvalue* ret_type, vector& types, bool isNotSure) { 18 | llvm_type* ret = dynamic_cast(ret_type); 19 | vector arg_types; 20 | for (auto p : types) { 21 | llvm_type* t = dynamic_cast(p); 22 | arg_types.push_back(*t); 23 | } 24 | FunctionType* func_type = FunctionType::get(*ret, arg_types, 25 | /*vararg*/isNotSure); 26 | return new llvm_type(func_type); 27 | } 28 | 29 | lvalue* llcg_llvm::l_GetOrInsertFunction(FunctionModel* fmodel) { 30 | return nullptr; 31 | } // 返回Function 32 | 33 | lvalue* llcg_llvm::l_GetOrInsertFunction(const string& name, lvalue* func_type) { 34 | llvm_type* _func_type = dynamic_cast(func_type); 35 | Type* t = *_func_type; 36 | Constant* f = M->getOrInsertFunction(name, (FunctionType*)t); 37 | return new llvm_value(f); 38 | } 39 | 40 | lvalue* llcg_llvm::l_GetOrInsertFunction(const string& name, lvalue* ret_type, vector& types, bool isNotSure) { 41 | return nullptr; 42 | } 43 | 44 | void llcg_llvm::l_FunctionBodyBegin(lvalue* func, vector& name_list) { 45 | Value* _func = *dynamic_cast(func); 46 | Function* F = dyn_cast(_func); 47 | int i = 0; 48 | for (auto arg = F->arg_begin(); i != name_list.size(); ++arg, ++i) { 49 | arg->setName(name_list[i]); 50 | Value* argumentValue = arg; 51 | ValueSymbolTable* st = nowBlock->getValueSymbolTable(); 52 | Value* v = st->lookup(name_list[i]); 53 | new StoreInst(argumentValue, v, false, nowBlock); 54 | } 55 | } // 设置当前BasicBlock 56 | 57 | void llcg_llvm::l_FunctionBodyEnd() { 58 | if (nowBlock->getTerminator() == NULL) 59 | ReturnInst::Create(context, nowBlock); 60 | } // 处理函数结束 61 | 62 | lvalue* llcg_llvm::l_getFunction(const string& name) { 63 | Function* f = M->getFunction(name); 64 | return new llvm_value(f); 65 | } // 从当前模块中获取一个函数 66 | 67 | lvalue* llcg_llvm::l_Call(FunctionModel* fmodel, vector& args) { 68 | return nullptr; 69 | } // 返回CallInst 70 | 71 | lvalue* llcg_llvm::l_Call(lvalue* func, vector& args) { 72 | llvm_value* _func = dynamic_cast(func); 73 | vector fargs; 74 | for (auto p : args) { 75 | llvm_value* t = dynamic_cast(p); 76 | fargs.push_back(*t); 77 | } 78 | 79 | CallInst *call = CallInst::Create(*_func, fargs, "", nowBlock); 80 | return new llvm_value(call); 81 | } 82 | 83 | lvalue* llcg_llvm::l_Struct(StructModel* smodel) { 84 | return nullptr; 85 | } // 返回StructType 86 | 87 | lvalue* llcg_llvm::l_Struct(lvalue* _struct, vector& types) { 88 | std::vector type_vec; 89 | for (auto p : types) { 90 | Type* t = *dynamic_cast(p); 91 | type_vec.push_back(t); 92 | } 93 | Type* struct_type = *dynamic_cast(_struct); 94 | StructType* st = dyn_cast(struct_type); 95 | st->setBody(type_vec); 96 | return new llvm_type(st); 97 | } 98 | 99 | lvalue* llcg_llvm::l_DeclareStruct(const string& name) { 100 | StructType* st = StructType::create(context, name); 101 | return new llvm_type(st); 102 | } 103 | 104 | lvalue* llcg_llvm::l_DefVar(lvalue* var_type, const string& name) { 105 | Type* t = *dynamic_cast(var_type); 106 | AllocaInst *alloc = new AllocaInst(t, name, nowBlock); 107 | return new llvm_value(alloc); 108 | } // 返回分配的地址 109 | 110 | lvalue* llcg_llvm::l_DefVar(lvalue* var_type, const string& name, lvalue* init) { 111 | Type* t = *dynamic_cast(var_type); 112 | Value* v = *dynamic_cast(init); 113 | AllocaInst *alloc = new AllocaInst(t, name, nowBlock); 114 | new StoreInst(v, alloc, false, nowBlock); 115 | return new llvm_value(alloc); 116 | } 117 | 118 | lvalue* llcg_llvm::l_DefGlobalVar(lvalue* var_type, const string& name) { 119 | Type* t = *dynamic_cast(var_type); 120 | Value* v = new GlobalVariable(*M, t, false, GlobalValue::LinkageTypes::ExternalLinkage, NULL, name); 121 | return new llvm_value(v); 122 | } 123 | 124 | lvalue* llcg_llvm::l_DefGlobalVar(lvalue* var_type, const string& name, lvalue* init) { 125 | Type* t = *dynamic_cast(var_type); 126 | Value* v = *dynamic_cast(init); 127 | Value* g = new GlobalVariable(*M, t, false, GlobalValue::LinkageTypes::ExternalLinkage, 128 | dyn_cast(v), name); 129 | return new llvm_value(g); 130 | } 131 | 132 | lvalue* llcg_llvm::l_Load(lvalue* var_addr) { 133 | Value* ptr = *dynamic_cast(var_addr); 134 | Value* v = new LoadInst(ptr, "", false, nowBlock); 135 | return new llvm_value(v); 136 | } 137 | 138 | lvalue* llcg_llvm::l_Store(lvalue* var_addr, lvalue* value) { 139 | Value* addr = *dynamic_cast(var_addr); 140 | Value* v = *dynamic_cast(value); 141 | new StoreInst(v, addr, false, nowBlock); 142 | return value; 143 | } 144 | 145 | lvalue* llcg_llvm::l_Opt1(const string& opt, lvalue* value) { 146 | Value* ans = *dynamic_cast(value); 147 | 148 | AtomicRMWInst::BinOp bop; 149 | Value* one = ConstantInt::get(Type::getInt64Ty(context), 1); 150 | Value* ret; 151 | if (opt == "-") { ret = BinaryOperator::CreateNeg(ans, "", nowBlock); 152 | return new llvm_value(ret); } 153 | if (opt == "~") { ret = BinaryOperator::CreateNot(ans, "", nowBlock); 154 | return new llvm_value(ret); } 155 | if (opt == "++") { bop = AtomicRMWInst::BinOp::Add; goto selfWork; } 156 | if (opt == "--") { bop = AtomicRMWInst::BinOp::Sub; goto selfWork; } 157 | if (opt == "b++") { bop = AtomicRMWInst::BinOp::Add; goto saveWork; } 158 | if (opt == "b--") { bop = AtomicRMWInst::BinOp::Sub; goto saveWork; } 159 | 160 | selfWork: 161 | new AtomicRMWInst(bop, ans, one, AtomicOrdering::SequentiallyConsistent, 162 | SynchronizationScope::CrossThread, nowBlock); 163 | ret = new LoadInst(ans, "", false, nowBlock); 164 | return new llvm_value(ret); 165 | 166 | saveWork: 167 | ret = new AtomicRMWInst(bop, ans, one, AtomicOrdering::SequentiallyConsistent, 168 | SynchronizationScope::CrossThread, nowBlock); 169 | return new llvm_value(ret); 170 | } 171 | 172 | 173 | static Value* getCast(Value* v, Type* t, BasicBlock* bb) { 174 | Instruction::CastOps cops = CastInst::getCastOpcode(v, true, t, true); 175 | return CastInst::Create(cops, v, t, "", bb); 176 | } 177 | 178 | static void normalize_type(Value*& v1, Value*& v2, BasicBlock* bb) { 179 | Type* t1 = v1->getType(); 180 | Type* t2 = v2->getType(); 181 | if (t1->isDoubleTy() || t2->isDoubleTy()) { 182 | if (!t1->isDoubleTy()) v1 = getCast(v1, t2, bb); 183 | if (!t2->isDoubleTy()) v2 = getCast(v2, t1, bb); 184 | return; 185 | } 186 | if (t1->isFloatTy() || t2->isFloatTy()) { 187 | if (!t1->isFloatTy()) v1 = getCast(v1, t2, bb); 188 | if (!t2->isFloatTy()) v2 = getCast(v2, t1, bb); 189 | return; 190 | } 191 | } 192 | 193 | 194 | lvalue* llcg_llvm::l_Opt2(const string& opt, lvalue* value1, lvalue* value2) { 195 | Value* ans1 = *dynamic_cast(value1); 196 | Value* ans2 = *dynamic_cast(value2); 197 | Type* t1 = ans1->getType(); 198 | Type* t2 = ans2->getType(); 199 | Instruction::BinaryOps instr; 200 | if (t1->isIntegerTy() && t2->isIntegerTy() && t1->getIntegerBitWidth()==t2->getIntegerBitWidth() ) { 201 | if (opt == "+") { instr = Instruction::Add; goto binOper; } 202 | if (opt == "-") { instr = Instruction::Sub; goto binOper; } 203 | if (opt == "*") { instr = Instruction::Mul; goto binOper; } 204 | if (opt == "/") { instr = Instruction::SDiv; goto binOper; } 205 | if (opt == "%") { instr = Instruction::SRem; goto binOper; } 206 | if (opt == "<<") { instr = Instruction::Shl; goto binOper; } 207 | if (opt == ">>") { instr = Instruction::LShr; goto binOper; } // 注意,这里没处理有符号数和无符号数的问题 AShr(arithmetic) 208 | if (opt == "&") { instr = Instruction::And; goto binOper; } 209 | if (opt == "|") { instr = Instruction::Or; goto binOper; } 210 | if (opt == "^") { instr = Instruction::Xor; goto binOper; } 211 | } else { 212 | normalize_type(ans1, ans2, nowBlock); 213 | if (opt == "+") { instr = Instruction::FAdd; goto binOper; } 214 | if (opt == "-") { instr = Instruction::FSub; goto binOper; } 215 | if (opt == "*") { instr = Instruction::FMul; goto binOper; } 216 | if (opt == "/") { instr = Instruction::FDiv; goto binOper; } 217 | if (opt == "%") { instr = Instruction::FRem; goto binOper; } 218 | } 219 | 220 | binOper: 221 | Value* ret = BinaryOperator::Create(instr, ans1, ans2, "", nowBlock); 222 | return new llvm_value(ret); 223 | } 224 | 225 | lvalue* llcg_llvm::l_Cmp(const string& opt, lvalue* value1, lvalue* value2) { 226 | Value* ans1 = *dynamic_cast(value1); 227 | Value* ans2 = *dynamic_cast(value2); 228 | Type* t1 = ans1->getType(); 229 | Type* t2 = ans2->getType(); 230 | CmpInst::Predicate instp; 231 | if (t1->isIntegerTy() && t2->isIntegerTy() && t1->getIntegerBitWidth()==t2->getIntegerBitWidth() ) { 232 | if (opt == "==") { instp = CmpInst::Predicate::ICMP_EQ; goto cmpOper; } 233 | if (opt == "!=") { instp = CmpInst::Predicate::ICMP_NE; goto cmpOper; } 234 | if (opt == "<=") { instp = CmpInst::Predicate::ICMP_SLE; goto cmpOper; } 235 | if (opt == ">=") { instp = CmpInst::Predicate::ICMP_SGE; goto cmpOper; } 236 | if (opt == "<") { instp = CmpInst::Predicate::ICMP_SLT; goto cmpOper; } 237 | if (opt == ">") { instp = CmpInst::Predicate::ICMP_SGT; goto cmpOper; } 238 | } else { 239 | normalize_type(ans1, ans2, nowBlock); 240 | if (opt == "==") { instp = CmpInst::Predicate::FCMP_OEQ; goto cmpOper; } 241 | if (opt == "!=") { instp = CmpInst::Predicate::FCMP_ONE; goto cmpOper; } 242 | if (opt == "<=") { instp = CmpInst::Predicate::FCMP_OLE; goto cmpOper; } 243 | if (opt == ">=") { instp = CmpInst::Predicate::FCMP_OGE; goto cmpOper; } 244 | if (opt == "<") { instp = CmpInst::Predicate::FCMP_OLT; goto cmpOper; } 245 | if (opt == ">") { instp = CmpInst::Predicate::FCMP_OGT; goto cmpOper; } 246 | } 247 | 248 | cmpOper: 249 | Value* ret = CmpInst::Create(Instruction::ICmp, instp, ans1, ans2, "", nowBlock); 250 | return new llvm_value(ret); 251 | } 252 | 253 | lvalue* llcg_llvm::l_Assignment(const string& opt, lvalue* value1, lvalue* value2) { 254 | Value* ans1 = *dynamic_cast(value1); 255 | Value* ans2 = *dynamic_cast(value2); 256 | if (opt == "=") { 257 | Value* ret = new StoreInst(ans2, ans1, false, nowBlock); 258 | return new llvm_value(ret); 259 | } 260 | AtomicRMWInst::BinOp bop; 261 | if (opt == "+=") { bop = AtomicRMWInst::BinOp::Add; goto rmwOper; } 262 | if (opt == "-=") { bop = AtomicRMWInst::BinOp::Sub; goto rmwOper; } 263 | if (opt == "&=") { bop = AtomicRMWInst::BinOp::And; goto rmwOper; } 264 | if (opt == "|=") { bop = AtomicRMWInst::BinOp::Or; goto rmwOper; } 265 | if (opt == "^=") { bop = AtomicRMWInst::BinOp::Xor; goto rmwOper; } 266 | rmwOper: 267 | Value* ret = new AtomicRMWInst(bop, ans1, ans2, AtomicOrdering::SequentiallyConsistent, 268 | SynchronizationScope::CrossThread, nowBlock); 269 | return new llvm_value(ret); 270 | } 271 | 272 | lvalue* llcg_llvm::l_Dot(lvalue* value, int num) { 273 | Value* ans = *dynamic_cast(value); 274 | ConstantInt* zero = ConstantInt::get(Type::getInt32Ty(context), 0); 275 | ConstantInt* n = ConstantInt::get(Type::getInt32Ty(context), num); 276 | std::vector indices; 277 | indices.push_back(zero); 278 | indices.push_back(n); 279 | GetElementPtrInst* ptr = GetElementPtrInst::CreateInBounds(ans, indices, "", nowBlock); 280 | return new llvm_value(ptr); 281 | } 282 | 283 | lvalue* llcg_llvm::l_Select(lvalue* value, vector& args) { 284 | Value* v = *dynamic_cast(value); 285 | Value* len_array; 286 | errs() << "type:" << *(v->getType()); 287 | if (!(v->getType()->isPointerTy())) return nullptr; 288 | if (v->getType()->getPointerElementType()->isIntegerTy(64)) 289 | len_array = v; 290 | else 291 | len_array = CastInst::CreatePointerCast(v, Type::getInt64PtrTy(context)); 292 | Value* index; 293 | if (args.size() != 0) { 294 | index = *dynamic_cast(args[0]); 295 | for (int i = -2, j = 0; j < args.size()-1; --i, ++j) { 296 | Value* len = new LoadInst(ptrMove(len_array, i), "", false, nowBlock); 297 | index = BinaryOperator::Create(Instruction::Mul, index, len, "", nowBlock); 298 | Value* other = *dynamic_cast(args[j+1]); 299 | index = BinaryOperator::Create(Instruction::Add, index, other, "", nowBlock); 300 | } 301 | } else { errs() << "error index\n"; } 302 | 303 | std::vector indices; 304 | indices.push_back(index); 305 | GetElementPtrInst* ptr = GetElementPtrInst::CreateInBounds(v, indices, "", nowBlock); 306 | return new llvm_value(ptr); 307 | } 308 | 309 | void llcg_llvm::l_If(lvalue* cond, lvalue* father, lvalue* true_block, lvalue* true_block_end, 310 | lvalue* false_block, lvalue* false_block_end, bool isElseWork) { 311 | Value* condition = *dynamic_cast(cond); 312 | Value* _father = *dynamic_cast(father); 313 | Value* _true_block = *dynamic_cast(true_block); 314 | Value* _false_block = *dynamic_cast(false_block); 315 | BasicBlock* father_block = dyn_cast(_father); 316 | BasicBlock* _true_block_ = dyn_cast(_true_block); 317 | BasicBlock* _false_block_ = dyn_cast(_false_block); 318 | 319 | if (isElseWork) { 320 | BasicBlock* end_block = createBlock(); 321 | if (_true_block_->getTerminator() == NULL) 322 | BranchInst::Create(end_block, _true_block_); 323 | if (_false_block_->getTerminator() == NULL) 324 | BranchInst::Create(end_block, _false_block_); 325 | } else { 326 | if (_true_block_->getTerminator() == NULL) 327 | BranchInst::Create(_false_block_, _true_block_); 328 | } 329 | BranchInst* branch = BranchInst::Create(_true_block_, _false_block_, condition, father_block); 330 | } 331 | 332 | void llcg_llvm::l_For(lvalue* cond, lvalue* init, lvalue* pd, lvalue* work, lvalue* statement, lvalue* statement_end, lvalue* end) { 333 | Value* condition = *dynamic_cast(cond); 334 | Value* _init = *dynamic_cast(init); 335 | Value* _pd = *dynamic_cast(pd); 336 | Value* _work = *dynamic_cast(work); 337 | Value* _statement = *dynamic_cast(statement); 338 | Value* _end = *dynamic_cast(end); 339 | BasicBlock* init_block = dyn_cast(_init); 340 | BasicBlock* end_block = dyn_cast(_pd); 341 | BasicBlock* do_block = dyn_cast(_work); 342 | BasicBlock* work_block = dyn_cast(_statement); 343 | BasicBlock* false_block = dyn_cast(_end); 344 | 345 | BranchInst* branch = BranchInst::Create(work_block, false_block, condition, end_block); 346 | if (init_block->getTerminator() == NULL) 347 | BranchInst::Create(end_block, init_block); 348 | if (work_block->getTerminator() == NULL) 349 | BranchInst::Create(do_block, work_block); 350 | if (do_block->getTerminator() == NULL) 351 | BranchInst::Create(end_block, do_block); 352 | } 353 | 354 | void llcg_llvm::l_While(lvalue* cond, lvalue* father, lvalue* pd, lvalue* statement, lvalue* statement_end, lvalue* end) { 355 | Value* condition = *dynamic_cast(cond); 356 | Value* _father = *dynamic_cast(father); 357 | Value* _pd = *dynamic_cast(pd); 358 | Value* _statement = *dynamic_cast(statement); 359 | Value* _end = *dynamic_cast(end); 360 | 361 | BasicBlock* father_block = dyn_cast(_father); 362 | BasicBlock* pd_block = dyn_cast(_pd); 363 | BasicBlock* true_block = dyn_cast(_statement); 364 | BasicBlock* false_block = dyn_cast(_end); 365 | 366 | // 生成while循环 367 | BranchInst* branch = BranchInst::Create(true_block, false_block, condition, pd_block); 368 | if (father_block->getTerminator() == NULL) 369 | BranchInst::Create(pd_block, father_block); 370 | if (true_block->getTerminator() == NULL) 371 | BranchInst::Create(pd_block, true_block); 372 | } 373 | 374 | void llcg_llvm::l_DoWhile(lvalue* statement, lvalue* pd) { 375 | 376 | } 377 | 378 | void llcg_llvm::l_DoUntil(lvalue* statement, lvalue* pd) { 379 | 380 | } 381 | 382 | lvalue* llcg_llvm::l_New(lvalue* var_type, vector& args, const string& funcname) { 383 | Type* t = *dynamic_cast(var_type); 384 | Type* ITy = Type::getInt64Ty(context); 385 | Constant* AllocSize = ConstantExpr::getSizeOf(t); 386 | Instruction* Malloc = CallInst::CreateMalloc(nowBlock, ITy, t, AllocSize); 387 | Malloc->insertAfter(&(nowBlock->back())); 388 | return new llvm_value(Malloc); 389 | } 390 | 391 | lvalue* llcg_llvm::l_NewArray(lvalue* var_type, vector& wd, const string& funcname) { 392 | // 这里实现自定义的数组malloc函数 393 | Type* t = *dynamic_cast(var_type); 394 | ConstantInt* zero = ConstantInt::get(Type::getInt64Ty(context), 0); 395 | vector args; 396 | for (auto p : wd) { 397 | Value* v = *dynamic_cast(p); 398 | args.push_back(v); 399 | } 400 | args.push_back(zero); 401 | string func_name = "malloc_array"; 402 | CallInst *call = CallInst::Create(M->getFunction(func_name), 403 | args, "", nowBlock); 404 | // t = ArrayType::get(t, 0); 405 | t = t->getPointerTo(); 406 | Value* ret = CastInst::CreatePointerCast(call, t, "", nowBlock); 407 | return new llvm_value(ret); 408 | } 409 | 410 | lvalue* llcg_llvm::l_Delete(lvalue* pointer, const string& funcname) { 411 | Value* ptr = *dynamic_cast(pointer); 412 | Instruction* Free = CallInst::CreateFree(ptr, nowBlock); 413 | return new llvm_value(Free); 414 | } 415 | 416 | lvalue* llcg_llvm::l_DeleteArray(lvalue* pointer, const string& funcname) { 417 | return NULL; 418 | } 419 | 420 | 421 | 422 | lvalue* llcg_llvm::l_Return() { 423 | Value* ret = ReturnInst::Create(context, nullptr, nowBlock); 424 | return new llvm_value(ret); 425 | } 426 | 427 | lvalue* llcg_llvm::l_Return(lvalue* var) { 428 | Value* v = *dynamic_cast(var); 429 | Value* ret = ReturnInst::Create(context, v, nowBlock); 430 | return new llvm_value(ret); 431 | } 432 | 433 | 434 | lvalue* llcg_llvm::l_Int8() { 435 | return new llvm_type(Type::getInt8Ty(context)); 436 | } 437 | 438 | lvalue* llcg_llvm::l_Int16() { 439 | return new llvm_type(Type::getInt16Ty(context)); 440 | 441 | } 442 | 443 | lvalue* llcg_llvm::l_Int32() { 444 | return new llvm_type(Type::getInt32Ty(context)); 445 | 446 | } 447 | 448 | lvalue* llcg_llvm::l_Int64() { 449 | return new llvm_type(Type::getInt64Ty(context)); 450 | 451 | } 452 | 453 | lvalue* llcg_llvm::l_Float() { 454 | return new llvm_type(Type::getFloatTy(context)); 455 | 456 | } 457 | 458 | lvalue* llcg_llvm::l_Double() { 459 | return new llvm_type(Type::getDoubleTy(context)); 460 | 461 | } 462 | 463 | lvalue* llcg_llvm::l_Void() { 464 | return new llvm_type(Type::getVoidTy(context)); 465 | 466 | } 467 | 468 | lvalue* llcg_llvm::l_ConstString(const string& str) { 469 | return new llvm_value(geti8StrVal(*M, str.c_str(), "")); 470 | 471 | } 472 | 473 | lvalue* llcg_llvm::l_ConstInt(int num) { 474 | Type* t = Type::getInt64Ty(context); 475 | return new llvm_value(ConstantInt::get(t, num)); 476 | } 477 | 478 | lvalue* llcg_llvm::l_ConstDouble(double num) { 479 | Type* t = Type::getDoubleTy(context); 480 | return new llvm_value(ConstantFP::get(t, num)); 481 | } 482 | 483 | extern const LibFunc stdlibs[]; 484 | 485 | void llcg_llvm::l_BeginModule(const string& name) { 486 | M = llvm::make_unique(name, context); 487 | register_stdlib(M.get(), stdlibs); 488 | } 489 | 490 | void llcg_llvm::l_VerifyAndWrite(const string& outfile_name) { 491 | verifyModuleAndWrite(M.get(), outfile_name); 492 | 493 | } 494 | 495 | void llcg_llvm::l_MakeMetaModule(const string& outfile_name, const string& module_name) { 496 | Module* M = meta_M.get(); 497 | M->setModuleIdentifier(module_name); 498 | 499 | Function *F = M->getFunction("elite_meta_init"); 500 | BasicBlock& bb = F->getEntryBlock(); // 仅有一个BasicBlock,所以这样写可以 501 | if (bb.getTerminator() == NULL) // 处理函数结尾返回 502 | ReturnInst::Create(context, &bb); 503 | Type* function_ptr = F->getFunctionType()->getPointerTo(); // 获取函数指针类型 504 | 505 | vector type_list; 506 | type_list.push_back(Type::getInt32Ty(M->getContext())); 507 | type_list.push_back(function_ptr); 508 | type_list.push_back(Type::getInt8PtrTy(M->getContext())); 509 | 510 | vector init_list; 511 | init_list.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 65535)); 512 | init_list.push_back(ConstantExpr::getBitCast(F, function_ptr)); 513 | init_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 514 | 515 | StructType* st = StructType::create(type_list, ""); 516 | ArrayType* at = ArrayType::get(st, 1); 517 | vector array_init_list; 518 | array_init_list.push_back(ConstantStruct::get(st, init_list)); 519 | Constant* init_var = ConstantArray::get(at, array_init_list); 520 | 521 | GlobalVariable* gv = new GlobalVariable( 522 | *M, at, false, GlobalValue::AppendingLinkage, init_var, "llvm.globallcg_llvm::l_ctors" 523 | ); 524 | 525 | verifyModuleAndWrite(M, outfile_name); 526 | } 527 | 528 | 529 | lvalue* llcg_llvm::l_GetNowBasicBlock() { 530 | return new llvm_value(nowBlock); 531 | 532 | } 533 | 534 | lvalue* llcg_llvm::l_CreateBasicBlock() { 535 | return new llvm_value(createBlock()); 536 | 537 | } 538 | 539 | lvalue* llcg_llvm::l_CreateBasicBlock(lvalue* func) { 540 | Value* v = *dynamic_cast(func); 541 | Function* f = dyn_cast(v); 542 | return new llvm_value(createBlock(f)); 543 | } 544 | 545 | 546 | void llcg_llvm::l_MakeMetaList(vector& list) { 547 | Module* M = meta_M.get(); 548 | Function* F = M->getFunction("elite_meta_init"); 549 | vector args_list; 550 | for (int i = 0; i < list.size(); ++i) { 551 | args_list.push_back(geti8StrVal(*M, list[i].c_str(), "")); 552 | } 553 | args_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 554 | BasicBlock& bb = F->getEntryBlock(); 555 | Function* FuncF = M->getFunction("elite_meta_list"); 556 | Constant* list_vec = getPtrArray(*M, args_list); 557 | vector args; 558 | args.push_back(list_vec); 559 | CallInst::Create(FuncF, args, "", &bb); 560 | } 561 | 562 | void llcg_llvm::l_MakeMetaList(const string& name, vector& list, lvalue* fp) { 563 | Module* M = meta_M.get(); 564 | Function* F = M->getFunction("elite_meta_init"); 565 | vector args_list; 566 | for (int i = 0; i < list.size(); ++i) { 567 | args_list.push_back(geti8StrVal(*M, list[i].c_str(), "")); 568 | } 569 | args_list.push_back(Constant::getNullValue(Type::getInt8PtrTy(M->getContext()))); 570 | 571 | Constant* list_vec = getPtrArray(*M, args_list); 572 | vector args; 573 | args.push_back(geti8StrVal(*M, name.c_str(), "")); // 第一个参数, 函数名 574 | args.push_back(list_vec); // 第二个参数, 函数类型定义字符串列表 575 | 576 | Type* ft = *dynamic_cast(fp); 577 | Function* nowFunc = dyn_cast(M->getOrInsertFunction(name, (FunctionType*)ft)); 578 | Type* nowType = Type::getInt8PtrTy(M->getContext()); 579 | args.push_back(ConstantExpr::getBitCast(nowFunc, nowType)); 580 | BasicBlock& bb = F->getEntryBlock(); 581 | Function* FuncF = M->getFunction("elite_meta_function"); 582 | CallInst::Create(FuncF, args, "", &bb); 583 | } 584 | 585 | void llcg_llvm::l_CloseTerminator(lvalue* basicblock, lvalue* target) { 586 | Value* _basicblock = *dynamic_cast(basicblock); 587 | Value* _target = *dynamic_cast(target); 588 | BasicBlock* bb = dyn_cast(_basicblock); 589 | BasicBlock* tg = dyn_cast(_target); 590 | if (bb->getTerminator() == NULL) 591 | BranchInst::Create(tg, bb); 592 | } 593 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llvm_libs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-24 10:21:35 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-16 22:22:28 6 | */ 7 | 8 | #include "llcg_llvm.h" 9 | 10 | 11 | static void register_printf(llvm::Module *module) { 12 | std::vector printf_arg_types; 13 | printf_arg_types.push_back(llvm::Type::getInt8PtrTy(module->getContext())); 14 | 15 | llvm::FunctionType* printf_type = 16 | llvm::FunctionType::get( 17 | llvm::Type::getInt32Ty(module->getContext()), printf_arg_types, true); 18 | 19 | llvm::Function *func = llvm::Function::Create( 20 | printf_type, llvm::Function::ExternalLinkage, 21 | llvm::Twine("printf"), 22 | module 23 | ); 24 | func->setCallingConv(llvm::CallingConv::C); 25 | } 26 | 27 | static void register_functioncall(llvm::Module *module) { 28 | std::vector arg_types; 29 | arg_types.push_back(llvm::Type::getInt8PtrTy(module->getContext())); 30 | 31 | llvm::FunctionType* func_type = 32 | llvm::FunctionType::get( 33 | llvm::Type::getInt8PtrTy(module->getContext()), arg_types, true); 34 | 35 | llvm::Function *func = llvm::Function::Create( 36 | func_type, llvm::Function::ExternalLinkage, 37 | llvm::Twine("FunctionCall"), 38 | module 39 | ); 40 | func->setCallingConv(llvm::CallingConv::C); 41 | } 42 | 43 | 44 | static void register_elite_meta_function(Module *module) { 45 | std::vector arg_types; 46 | arg_types.push_back(Type::getInt8PtrTy(module->getContext())); 47 | arg_types.push_back(Type::getInt8PtrTy(module->getContext())->getPointerTo()); 48 | arg_types.push_back(Type::getInt8PtrTy(module->getContext())); 49 | 50 | FunctionType* meta_type = 51 | FunctionType::get( 52 | Type::getVoidTy(module->getContext()), arg_types, false); 53 | 54 | Function *func = Function::Create( 55 | meta_type, Function::ExternalLinkage, 56 | Twine("elite_meta_function"), 57 | module 58 | ); 59 | func->setCallingConv(CallingConv::C); 60 | } 61 | 62 | static void register_elite_meta_list(Module *module) { 63 | std::vector arg_types; 64 | arg_types.push_back(Type::getInt8PtrTy(module->getContext())->getPointerTo()); 65 | 66 | FunctionType* meta_type = 67 | FunctionType::get( 68 | Type::getVoidTy(module->getContext()), arg_types, true); 69 | 70 | Function *func = Function::Create( 71 | meta_type, Function::ExternalLinkage, 72 | Twine("elite_meta_list"), 73 | module 74 | ); 75 | func->setCallingConv(CallingConv::C); 76 | } 77 | 78 | 79 | static void register_elite_meta_init(Module *module) { 80 | std::vector arg_types; 81 | 82 | FunctionType* meta_type = 83 | FunctionType::get( 84 | Type::getVoidTy(module->getContext()), arg_types, false); 85 | 86 | Function *func = Function::Create( 87 | meta_type, Function::InternalLinkage, 88 | Twine("elite_meta_init"), 89 | module 90 | ); 91 | func->setCallingConv(CallingConv::C); 92 | 93 | BasicBlock::Create(module->getContext(), "entry", func); 94 | } 95 | 96 | static void register_malloc_array(Module *module) { 97 | std::vector arg_types; 98 | arg_types.push_back(Type::getInt64Ty(module->getContext())); 99 | 100 | FunctionType* meta_type = 101 | FunctionType::get( 102 | Type::getInt8PtrTy(module->getContext()), arg_types, true); 103 | 104 | Function *func = Function::Create( 105 | meta_type, Function::ExternalLinkage, 106 | Twine("malloc_array"), 107 | module 108 | ); 109 | func->setCallingConv(CallingConv::C); 110 | } 111 | 112 | extern const LibFunc stdlibs[] = { 113 | register_printf, 114 | register_functioncall, 115 | register_malloc_array, 116 | NULL 117 | }; 118 | 119 | extern const LibFunc metalibs[] = { 120 | register_elite_meta_function, 121 | register_elite_meta_list, 122 | register_elite_meta_init, 123 | NULL 124 | }; 125 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llvm_type.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-24 15:40:26 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-21 17:08:13 6 | */ 7 | 8 | #include "llvm_type.h" 9 | #include "llvm/IR/DerivedTypes.h" 10 | #include "llvm/Support/raw_ostream.h" 11 | using namespace llvm; 12 | 13 | llvm_type::llvm_type(llvm::Type* v) { 14 | data = v; 15 | } 16 | 17 | llvm_type::~llvm_type() { 18 | 19 | } 20 | 21 | bool llvm_type::isStructType() { 22 | return data->isStructTy(); 23 | } 24 | 25 | 26 | string llvm_type::getTypeName() { 27 | if (data->isStructTy()) { 28 | StructType* st = (StructType*) data; 29 | return st->getName().str(); 30 | } 31 | return ""; 32 | } 33 | 34 | LValue llvm_type::getPointerTo() { 35 | Type* t = data->getPointerTo(); 36 | return LValue(new llvm_type(t)); 37 | } -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llvm_type.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-24 08:43:52 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-21 16:44:22 6 | */ 7 | 8 | 9 | #ifndef LLVM_TYPE_H 10 | #define LLVM_TYPE_H 11 | 12 | #include "lvalue.h" 13 | 14 | class llvm_type; 15 | 16 | typedef shared_ptr LLVMType; 17 | #define LLTYPE(T) dynamic_pointer_cast(T) 18 | 19 | namespace llvm { 20 | class Type; 21 | } // llvm 22 | 23 | class llvm_type : public lvalue 24 | { 25 | public: 26 | llvm_type(llvm::Type* v); 27 | virtual ~llvm_type(); 28 | 29 | operator llvm::Type* () const { return data; } 30 | virtual bool isStructType(); 31 | virtual string getTypeName(); 32 | virtual LValue getPointerTo(); 33 | private: 34 | llvm::Type* data; 35 | }; 36 | 37 | 38 | 39 | #endif // LLVM_TYPE_H 40 | -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llvm_value.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-24 15:39:17 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 16:55:59 6 | */ 7 | 8 | #include "llvm_value.h" 9 | #include "llvm/IR/DerivedTypes.h" 10 | #include "llvm/IR/Module.h" 11 | 12 | using namespace llvm; 13 | 14 | llvm_value::llvm_value(llvm::Value* v) { 15 | data = v; 16 | } 17 | 18 | llvm_value::~llvm_value() { 19 | 20 | } 21 | 22 | string llvm_value::getTypeName() { 23 | Type* t = data->getType(); 24 | StructType* st = (StructType*)(t->getPointerElementType()); 25 | return st->getName().str(); 26 | } -------------------------------------------------------------------------------- /src/LLCG/LLVMLIB/llvm_value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 22:03:33 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 16:42:19 6 | */ 7 | 8 | #ifndef LLVM_VALUE_H 9 | #define LLVM_VALUE_H 10 | 11 | #include "lvalue.h" 12 | 13 | class llvm_value; 14 | 15 | typedef shared_ptr LLVMValue; 16 | #define LLVALUE(T) dynamic_pointer_cast(T) 17 | 18 | namespace llvm { 19 | class Value; 20 | } // llvm 21 | 22 | class llvm_value : public lvalue 23 | { 24 | public: 25 | llvm_value(llvm::Value* v); 26 | virtual ~llvm_value(); 27 | 28 | operator llvm::Value* () const { return data; } 29 | virtual string getTypeName(); 30 | 31 | private: 32 | llvm::Value* data; 33 | }; 34 | 35 | 36 | 37 | #endif // LLVM_VALUE_H 38 | -------------------------------------------------------------------------------- /src/LLCG/llcg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-23 21:43:28 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-24 11:01:39 6 | */ 7 | 8 | #include "llcg.h" 9 | #include "llcg_llvm.h" 10 | 11 | llcg* llcg::CreateLLVM() { 12 | return new llcg_llvm(); 13 | } 14 | -------------------------------------------------------------------------------- /src/Macro/Classes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-26 14:05:30 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 15:35:28 6 | */ 7 | 8 | #include "CodeGenContext.h" 9 | #include "StringNode.h" 10 | #include "IDNode.h" 11 | #include 12 | #include "Pass.h" 13 | 14 | extern const FuncReg macro_classes_replace[]; 15 | 16 | static LValue class_macro(CodeGenContext* context, Node* node) { 17 | auto pass = context->getNowPass(); 18 | pass->SaveMacros(); 19 | pass->AddOrReplaceMacros(macro_classes_replace); 20 | 21 | 22 | pass->RecoverMacros(); 23 | return NULL; 24 | } 25 | 26 | static LValue module_macro(CodeGenContext* context, Node* node) { 27 | 28 | 29 | return NULL; 30 | } 31 | 32 | extern const FuncReg macro_funcs[]; 33 | 34 | static LValue function_macro(CodeGenContext* context, Node* node) { 35 | auto pass = context->getNowPass(); 36 | pass->SaveMacros(); 37 | pass->AddOrReplaceMacros(macro_funcs); 38 | 39 | pass->RecoverMacros(); 40 | return NULL; 41 | } 42 | 43 | static LValue set_macro(CodeGenContext* context, Node* node) { 44 | return NULL; 45 | } 46 | 47 | 48 | extern const FuncReg macro_classes_replace[] = { 49 | {"function", function_macro}, 50 | {"set", set_macro}, 51 | {NULL, NULL} 52 | }; 53 | 54 | 55 | extern const FuncReg macro_classes[] = { 56 | {"class", class_macro}, 57 | {"module", module_macro}, 58 | {NULL, NULL} 59 | }; 60 | -------------------------------------------------------------------------------- /src/Macro/Functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-26 14:00:25 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-27 16:30:41 6 | */ 7 | 8 | #include "CodeGenContext.h" 9 | #include "StringNode.h" 10 | #include "MetaModel/StructModel.h" 11 | #include "MetaModel/FunctionModel.h" 12 | #include "nodes.h" 13 | #include "idtable.h" 14 | #include 15 | 16 | using namespace std; 17 | 18 | static LValue function_macro(CodeGenContext* context, Node* node) { 19 | // 第二个参数, 函数名 20 | node = node->getNext(); 21 | std::string function_name = node->getStr(); 22 | cout << function_name << endl; 23 | shared_ptr fm = context->getFunctionModel(function_name); 24 | fm->genMetaCode(context); 25 | LValue F = fm->getFunction(context); 26 | 27 | // 第三个参数, 参数表 28 | Node* args_node = node = node->getNext(); 29 | 30 | // 第四个参数, 代码块 31 | node = node->getNext(); 32 | if (node->getChild() == NULL) { 33 | return F; // 仅仅是函数声明 34 | } 35 | context->st->push(); 36 | context->getLLCG()->CreateBasicBlock(F); // 创建新的Block 37 | 38 | // 特殊处理参数表, 这个地方特别坑,你必须给每个函数的参数 39 | // 手动AllocaInst开空间,再用StoreInst存一遍才行,否则一Load就报错 40 | // context->MacroMake(args_node->getChild()); 41 | if (args_node->getChild() != NULL) { 42 | context->MacroMake(args_node); 43 | context->getLLCG()->FunctionBodyBegin(F, fm->name_list); 44 | } 45 | context->MacroMake(node); 46 | context->st->pop(); 47 | // 处理块结尾 48 | context->getLLCG()->FunctionBodyEnd(); 49 | return F; 50 | } 51 | 52 | static LValue set_macro(CodeGenContext* context, Node* node) { 53 | // 参数一 类型 54 | LValue t; 55 | if (node->isTypeNode()) { 56 | TypeNode* tn = (TypeNode*) node; 57 | t = tn->typeGen(context); 58 | } else { 59 | printf("错误的节点类型\n"); 60 | exit(1); 61 | } 62 | 63 | // 参数二 变量名 64 | Node* var_node = node->getNext(); 65 | string var_name = var_node->getStr(); 66 | 67 | // 参数三 初始化值 68 | // 这里有个问题 初始化为常数时,Store会出问题 69 | node = var_node->getNext(); 70 | if (node == NULL) { 71 | LValue addr = context->getLLCG()->DefVar(t, var_name); 72 | context->DefVar(var_name, addr); 73 | return addr; 74 | } 75 | LValue init_expr = node->codeGen(context); 76 | if (init_expr == NULL) { 77 | cerr << "变量的初始化无效: " << var_name << endl; 78 | exit(1); 79 | } 80 | LValue addr; 81 | if (context->st->getLevel() != 0) 82 | addr = context->getLLCG()->DefVar(t, var_name, init_expr); 83 | else 84 | addr = context->getLLCG()->DefGlobalVar(t, var_name, init_expr); 85 | context->DefVar(var_name, addr); 86 | return addr; 87 | } 88 | 89 | static LValue select_macro(CodeGenContext* context, Node* node) { 90 | bool save_bool = false; 91 | if (context->isSave()) { 92 | save_bool = true; 93 | context->setIsSave(false); 94 | } 95 | 96 | LValue value = node->codeGen(context); 97 | 98 | std::vector args; 99 | for (Node* p = node->getNext(); p != NULL; p = p->getNext()) { 100 | LValue v = p->codeGen(context); 101 | if (v != NULL) { 102 | args.push_back(v); 103 | } 104 | } 105 | 106 | LValue ptr = context->getLLCG()->Select(value, args); 107 | if (save_bool) return ptr; 108 | return context->getLLCG()->Load(ptr); 109 | } 110 | 111 | static LValue call_macro(CodeGenContext* context, Node* node) { 112 | // 参数一 函数名 113 | LValue func = context->getFunction(node); 114 | if (func == NULL) { 115 | cerr << "找不到函数的定义: "; 116 | cerr << node->getStr() << endl; 117 | exit(1); 118 | } 119 | 120 | // 其余参数 要传入的参数 121 | std::vector args; 122 | for (Node* p = node->getNext(); p != NULL; p = p->getNext()) { 123 | LValue v = p->codeGen(context); 124 | if (v != NULL) 125 | args.push_back(v); 126 | } 127 | 128 | return context->getLLCG()->Call(func, args); 129 | } 130 | 131 | static LValue for_macro(CodeGenContext* context, Node* node) { 132 | context->st->push(); 133 | // 参数一 初始化 134 | LValue init_block = context->getLLCG()->GetNowBasicBlock(); 135 | context->MacroMake(node); 136 | 137 | // 参数二 终止条件 138 | node = node->getNext(); 139 | LValue end_block = context->getLLCG()->CreateBasicBlock(); 140 | LValue condition = context->MacroMake(node); 141 | 142 | // 参数三 每次循环 143 | node = node->getNext(); 144 | LValue do_block = context->getLLCG()->CreateBasicBlock(); 145 | context->MacroMake(node); 146 | 147 | // 参数四 循环体 148 | node = node->getNext(); 149 | LValue work_block = context->getLLCG()->CreateBasicBlock(); 150 | 151 | LValue false_block = context->getLLCG()->CreateBasicBlock(); 152 | 153 | // 生成break和continue标识 154 | context->st->insert("break", conditions_t, false_block); 155 | context->st->insert("continue", conditions_t, end_block); 156 | 157 | // 为了在生成代码前先记录break时要跳出的位置, 必须先建好各个BasicBlock, 最后再设定跳转关系 158 | context->getLLCG()->SetNowBasicBlock(work_block); 159 | context->MacroMake(node); 160 | LValue work_end_block = context->getLLCG()->GetNowBasicBlock(); 161 | context->getLLCG()->SetNowBasicBlock(false_block); 162 | // 生成for循环 163 | context->getLLCG()->For(condition, init_block, end_block, do_block, work_block, work_end_block, false_block); 164 | 165 | context->st->pop(); 166 | return NULL; 167 | } 168 | 169 | static LValue while_macro(CodeGenContext* context, Node* node) { 170 | 171 | // 参数一 条件 172 | LValue father_block = context->getLLCG()->GetNowBasicBlock(); 173 | LValue pd_block = context->getLLCG()->CreateBasicBlock(); 174 | LValue condition = context->MacroMake(node); 175 | 176 | // 参数二 循环体 177 | node = node->getNext(); 178 | LValue true_block = context->getLLCG()->CreateBasicBlock(); 179 | LValue false_block = context->getLLCG()->CreateBasicBlock(); 180 | 181 | context->st->push(); 182 | context->getLLCG()->SetNowBasicBlock(true_block); 183 | context->MacroMake(node); 184 | context->st->pop(); 185 | LValue work_end_block = context->getLLCG()->GetNowBasicBlock(); 186 | 187 | context->getLLCG()->SetNowBasicBlock(false_block); 188 | 189 | // 生成while循环 190 | context->getLLCG()->While(condition, father_block, pd_block, true_block, work_end_block, false_block); 191 | return NULL; 192 | } 193 | 194 | static LValue if_macro(CodeGenContext* context, Node* node) { 195 | 196 | // 参数一 条件 197 | LValue condition = context->MacroMake(node); 198 | LValue father_block = context->getLLCG()->GetNowBasicBlock(); 199 | 200 | // 参数二 为真时, 跳转到的Label 201 | node = node->getNext(); 202 | 203 | LValue true_block = context->getLLCG()->CreateBasicBlock(); 204 | context->st->push(); 205 | context->MacroMake(node); 206 | context->st->pop(); 207 | LValue true_end_block = context->getLLCG()->GetNowBasicBlock(); 208 | 209 | // 参数三 为假时, 跳转到的Label 210 | node = node->getNext(); 211 | LValue false_block = context->getLLCG()->CreateBasicBlock(); 212 | if (node != NULL) { 213 | context->st->push(); 214 | context->MacroMake(node); 215 | context->st->pop(); 216 | } 217 | LValue false_end_block = context->getLLCG()->GetNowBasicBlock(); 218 | 219 | 220 | context->getLLCG()->If(condition, father_block, true_block, 221 | true_end_block, false_block, false_end_block, node != NULL); 222 | return NULL; 223 | } 224 | 225 | 226 | static LValue opt1_macro(CodeGenContext* context, Node* node) { 227 | std::string opt = node->getStr(); 228 | node = node->getNext(); 229 | if (node == NULL) return NULL; 230 | context->setIsSave(true); // 这两句设置的目前是为下面的节点解析时,返回指针而不是load后的值 231 | LValue ans = node->codeGen(context); 232 | context->setIsSave(false); 233 | return context->getLLCG()->Opt1(opt, ans); 234 | } 235 | 236 | static LValue opt2_macro(CodeGenContext* context, Node* node) { 237 | std::string opt = node->getStr(); 238 | 239 | Node* op1 = (node = node->getNext()); 240 | if (node == NULL) return NULL; 241 | Node* op2 = (node = node->getNext()); 242 | if (node == NULL) return NULL; 243 | 244 | if (opt == "=" || opt == "+=" || opt == "-=" || opt == "&=" || opt == "|=" || opt == "^=") { 245 | context->setIsSave(true); // 这两句设置的目前是为下面的节点解析时,返回指针而不是load后的值 246 | LValue ans1 = op1->codeGen(context); 247 | context->setIsSave(false); 248 | LValue ans2 = op2->codeGen(context); 249 | return context->getLLCG()->Assignment(opt, ans1, ans2); 250 | } 251 | 252 | if (opt == ".") { 253 | bool save_bool = false; 254 | if (context->isSave()) { 255 | save_bool = true; 256 | context->setIsSave(false); 257 | } 258 | 259 | LValue ans1 = op1->codeGen(context); 260 | string ans2 = op2->getStr(); 261 | string struct_name = ans1->getTypeName(); 262 | shared_ptr sm_ptr = context->getStructModel(struct_name); 263 | int n = sm_ptr->find(ans2); 264 | 265 | LValue ptr = context->getLLCG()->Dot(ans1, n); 266 | if (save_bool) return ptr; 267 | return context->getLLCG()->Load(ptr); 268 | } 269 | 270 | LValue ans1 = op1->codeGen(context); 271 | LValue ans2 = op2->codeGen(context); 272 | if (opt == "+" || opt == "-" || opt == "*" || opt == "*" || opt == "/" || opt == "<<" || 273 | opt == ">>" || opt == "&" || opt == "|" || opt == "^" || opt == "%") { 274 | return context->getLLCG()->Opt2(opt, ans1, ans2); 275 | } 276 | 277 | if (opt == "==" || opt == "!=" || opt == "<=" || opt == ">=" || opt == "<" || opt == ">") { 278 | return context->getLLCG()->Cmp(opt, ans1, ans2); 279 | } 280 | return NULL; 281 | } 282 | 283 | static LValue struct_macro(CodeGenContext* context, Node* node) { 284 | std::string struct_name = node->getStr(); 285 | shared_ptr sm = context->getStructModel(struct_name); 286 | sm->genMetaCode(context); 287 | return NULL; 288 | } 289 | 290 | static LValue return_macro(CodeGenContext* context, Node* node) { 291 | if (node != NULL) { 292 | LValue v = node->codeGen(context); 293 | return context->getLLCG()->Return(v); 294 | } 295 | return context->getLLCG()->Return(); 296 | } 297 | 298 | static LValue new_macro(CodeGenContext* context, Node* node) { 299 | TypeNode* tn = (TypeNode*) node; 300 | LValue t = context->FindSrcType(tn->getTypeName()); 301 | 302 | // 第二个参数,构造函数表 303 | node = node->getNext(); 304 | 305 | // 第三个参数,维度信息 306 | vector args; 307 | node = node->getNext(); 308 | if (node != NULL) 309 | for (Node* p = node->getChild(); p != NULL; p = p->getNext()) { 310 | args.push_back(p->codeGen(context)); 311 | } 312 | if (args.size() == 0) { 313 | return context->getLLCG()->New(t,args); 314 | } else { 315 | return context->getLLCG()->NewArray(t, args); 316 | } 317 | } 318 | 319 | static LValue delete_macro(CodeGenContext* context, Node* node) { 320 | std::string str = node->getStr(); 321 | 322 | return NULL; 323 | } 324 | 325 | static LValue delete_array_macro(CodeGenContext* context, Node* node) { 326 | return NULL; 327 | } 328 | 329 | static LValue break_macro(CodeGenContext* context, Node* node) { 330 | printf("break macro\n"); 331 | id* d = context->st->find("break"); 332 | if (d == NULL) { 333 | printf("错误的break语句使用环境\n"); 334 | exit(1); 335 | } 336 | context->getLLCG()->Goto(d->data); 337 | return NULL; 338 | } 339 | 340 | static LValue continue_macro(CodeGenContext* context, Node* node) { 341 | printf("continue macro\n"); 342 | id* d = context->st->find("continue"); 343 | if (d == NULL) { 344 | printf("错误的continue语句使用环境\n"); 345 | exit(1); 346 | } 347 | context->getLLCG()->Goto(d->data); 348 | return NULL; 349 | } 350 | 351 | 352 | 353 | 354 | /* 355 | extern Node* parseFile(const char* path); 356 | 357 | static LValue import_macro(CodeGenContext* context, Node* node) { 358 | string file_name = node->getStr(); 359 | context->SaveMacros(); 360 | context->ScanOther(parseFile(file_name.c_str())); 361 | context->RecoverMacros(); 362 | return NULL; 363 | } 364 | */ 365 | extern const FuncReg macro_funcs[] = { 366 | {"function", function_macro}, 367 | {"struct", struct_macro}, 368 | {"set", set_macro}, 369 | {"call", call_macro}, 370 | {"select", select_macro}, 371 | {"opt1", opt1_macro}, 372 | {"opt2", opt2_macro}, 373 | {"for", for_macro}, 374 | {"while", while_macro}, 375 | {"if", if_macro}, 376 | {"return", return_macro}, 377 | {"new", new_macro}, 378 | {"delete", delete_macro}, 379 | {"delete[]", delete_array_macro}, 380 | {"break", break_macro}, 381 | {"continue", continue_macro}, 382 | //{"import", import_macro}, // 实验型导入功能,最后应从库中删除 383 | {NULL, NULL} 384 | }; 385 | -------------------------------------------------------------------------------- /src/Macro/Prescan.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-29 11:05:42 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:41:18 6 | */ 7 | 8 | #include "CodeGenContext.h" 9 | #include "StringNode.h" 10 | #include "MetaModel/StructModel.h" 11 | #include "MetaModel/FunctionModel.h" 12 | #include "IDNode.h" 13 | #include "idtable.h" 14 | #include 15 | 16 | static LValue function_macro(CodeGenContext* context, Node* node) { 17 | // 第一个参数, 返回类型 18 | std::string ret_type = node->getStr(); 19 | 20 | // 第二个参数, 函数名 21 | node = node->getNext(); 22 | std::string function_name = node->getStr(); 23 | 24 | // 第三个参数, 参数表 25 | Node* args_node = node = node->getNext(); 26 | std::vector type_vec; 27 | std::vector arg_name; 28 | if (args_node->getChild() != NULL) { 29 | for (Node* pC = args_node->getChild(); 30 | pC != NULL; pC = pC->getNext() ) 31 | { 32 | Node* pSec = pC->getChild()->getNext(); 33 | type_vec.push_back(pSec->getStr()); 34 | pSec = pSec->getNext(); 35 | arg_name.push_back(pSec->getStr()); 36 | pSec = pSec->getNext(); 37 | if (pSec != NULL) 38 | { 39 | LValue v = pSec->getNext()->codeGen(context); 40 | } else { 41 | } 42 | } 43 | } 44 | FunctionModel* fm = new FunctionModel(function_name, ret_type, type_vec, arg_name); 45 | fm->insertToST(context); 46 | return NULL; 47 | } 48 | 49 | static LValue struct_macro(CodeGenContext* context, Node* node) { 50 | // 第一个参数, 结构体名 51 | std::string struct_name = node->getStr(); 52 | Node* args_node = node->getNext(); 53 | std::vector type_vec; 54 | std::vector arg_name; 55 | if (args_node->getChild() != NULL) { 56 | for (Node* pC = args_node->getChild(); 57 | pC != NULL; pC = pC->getNext() ) 58 | { 59 | Node* pSec = pC->getChild()->getNext(); 60 | type_vec.push_back(pSec->getStr()); 61 | arg_name.push_back(pSec->getNext()->getStr()); 62 | } 63 | } 64 | StructModel* sm = new StructModel(struct_name, type_vec, arg_name); 65 | sm->insertToST(context); 66 | return NULL; 67 | } 68 | 69 | static LValue struct_type_macro(CodeGenContext* context, Node* node) { 70 | // 第一个参数, 结构体名 71 | std::string struct_name = node->getStr(); 72 | id* i = context->st->find(struct_name); 73 | if (i->type != struct_t) return NULL; 74 | auto sm = dynamic_pointer_cast(i->data); 75 | sm->genCode(context); 76 | return NULL; 77 | } 78 | 79 | 80 | static LValue function_type_macro(CodeGenContext* context, Node* node) { 81 | // 第二个参数, 函数名 82 | node = node->getNext(); 83 | std::string function_name = node->getStr(); 84 | id* i = context->st->find(function_name); 85 | if (i == NULL || i->type != function_t) return NULL; 86 | auto fm = dynamic_pointer_cast(i->data); 87 | fm->genCode(context); 88 | return NULL; 89 | } 90 | 91 | static LValue defmacro_macro(CodeGenContext* context, Node* node) { 92 | context->setUserMacro(node->getStr(), node->getNext()); 93 | return NULL; 94 | } 95 | 96 | extern const FuncReg macro_prescan[] = { 97 | {"function", function_macro}, 98 | {"struct", struct_macro}, 99 | {NULL, NULL} 100 | }; 101 | 102 | extern const FuncReg macro_pretype[] = { 103 | {"function", function_type_macro}, 104 | {"struct", struct_type_macro}, 105 | {NULL, NULL} 106 | }; 107 | 108 | extern const FuncReg macro_defmacro[] = { 109 | {"defmacro", defmacro_macro}, 110 | {NULL, NULL} 111 | }; 112 | -------------------------------------------------------------------------------- /src/MacroTranslate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-17 18:33:42 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-17 20:51:34 6 | */ 7 | 8 | #include "MacroTranslate.h" 9 | 10 | Node* MacroTranslate::Marco(Node* node_template, Node* args) { 11 | // 第一个参数 宏参数表 12 | Node* node = node_template->getChild(); 13 | for (Node* p = node; p != NULL; p = p->getNext(), args = args->getNext()) { 14 | string name = p->getStr(); 15 | args_map[name] = args; 16 | } 17 | 18 | // 第二个参数 模板部分 19 | node_template = node_template->getNext(); 20 | Node* copied_temp = node_template->copyChild(); 21 | marcoReplace(copied_temp); 22 | return copied_temp; 23 | } 24 | 25 | void MacroTranslate::marcoReplace(Node* node) { 26 | if (node == NULL) return; 27 | for (Node* p = node; p != NULL; p = p->getNext()) { 28 | Node* n = p->getNext(); 29 | if (n != NULL && n->isIDNode()) { 30 | Node* arg = findArg(n->getStr()); 31 | if (arg != NULL) { 32 | p->replaceNext(arg->copyChild()); 33 | } 34 | } 35 | n = p->getChild(); 36 | if (n != NULL) { 37 | if (n->isIDNode()) { 38 | Node* arg = findArg(n->getStr()); 39 | if (arg != NULL) { 40 | p->replaceChild(arg->copyChild()); 41 | continue; 42 | } 43 | } 44 | marcoReplace(n); 45 | } 46 | } 47 | } 48 | 49 | Node* MacroTranslate::findArg(const string& name) { 50 | auto p = args_map.find(name); 51 | if (p == args_map.end()) return NULL; 52 | return p->second; 53 | } 54 | -------------------------------------------------------------------------------- /src/MacroTranslate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-17 17:11:42 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 17:09:06 6 | */ 7 | 8 | #ifndef MACRO_TRANSLATE_H 9 | #define MACRO_TRANSLATE_H 10 | 11 | #include 12 | #include 13 | #include "Node.h" 14 | 15 | using namespace std; 16 | 17 | /** 18 | * @brief 宏翻译器, 可以支持用户自定义宏 19 | * @details 宏翻译器, 应该说是宏展开器, 能够根据用户的定义, 20 | * 将宏转换为真正的形式, 支持递归 21 | */ 22 | class MacroTranslate 23 | { 24 | public: 25 | Node* Marco(Node* node_template, Node* args); 26 | private: 27 | void marcoReplace(Node* node); 28 | Node* findArg(const string& name); 29 | map< string, Node* > args_map; 30 | }; 31 | 32 | 33 | 34 | #endif // MACRO_TRANSLATE_H 35 | -------------------------------------------------------------------------------- /src/MetaModel/FunctionModel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-13 16:45:51 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:46:12 6 | */ 7 | 8 | #include "MetaModel/FunctionModel.h" 9 | #include "CodeGenContext.h" 10 | #include "idtable.h" 11 | 12 | FunctionModel::FunctionModel( 13 | std::string& name, 14 | std::string& ret_type, 15 | std::vector& type_list, 16 | std::vector& name_list 17 | ) : MetaModel(name) 18 | { 19 | this->return_type = ret_type; 20 | this->type_list = type_list; 21 | this->name_list = name_list; 22 | } 23 | 24 | int FunctionModel::find(std::string& name) 25 | { 26 | int i = 0; 27 | if (name_list.size() == 0) return -1; 28 | for (auto& p : name_list) { 29 | if (name == p) return i; 30 | ++i; 31 | } 32 | return -1; 33 | } 34 | 35 | void FunctionModel::insertToST(CodeGenContext* context) { 36 | context->st->insert(name, function_t, LValue(this)); // 插入符号表中 37 | } 38 | 39 | LValue FunctionModel::getFunction(CodeGenContext* context) { 40 | return context->getLLCG()->GetOrInsertFunction(name, func_type); 41 | } 42 | 43 | 44 | void FunctionModel::genCode(CodeGenContext* context) { 45 | LValue ret_type = context->FindType(return_type); 46 | std::vector type_vec; 47 | for (auto& s : type_list) { 48 | LValue t = context->FindType(s); 49 | type_vec.push_back(t); 50 | } 51 | // 先合成一个函数 52 | func_type = context->getLLCG()->FuncType(ret_type, type_vec, 53 | /*not vararg*/false); 54 | } 55 | 56 | 57 | void FunctionModel::genMetaCode(CodeGenContext* context) { 58 | vector data; 59 | data.push_back(return_type); // 参数表1, 返回类型 60 | for (int i = 0; i < name_list.size(); ++i) { 61 | data.push_back(type_list[i]); // 类型 62 | data.push_back(name_list[i]); // 名称 63 | } 64 | context->getLLCG()->MakeMetaList(name, data, func_type); 65 | } 66 | 67 | MetaType FunctionModel::getMetaType() { 68 | return function_meta_t; 69 | } 70 | -------------------------------------------------------------------------------- /src/MetaModel/MacroModel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-25 15:02:32 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:46:30 6 | */ 7 | 8 | #include "MetaModel/MacroModel.h" 9 | 10 | MacroModel::MacroModel(const std::string& name, Node* node) : MetaModel(name) { 11 | this->node = node; 12 | } 13 | 14 | MacroModel::~MacroModel() { 15 | 16 | } 17 | 18 | 19 | void MacroModel::insertToST(CodeGenContext* context) { 20 | 21 | } 22 | 23 | void MacroModel::genCode(CodeGenContext* context) { 24 | 25 | } 26 | 27 | 28 | void MacroModel::genMetaCode(CodeGenContext* context) { 29 | 30 | } 31 | 32 | MetaType MacroModel::getMetaType() { 33 | return macro_meta_t; 34 | } 35 | -------------------------------------------------------------------------------- /src/MetaModel/MapModel.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MetaModel/MapModel.h" 3 | 4 | 5 | MapModel::MapModel (const string& name) 6 | : MetaModel(name) { 7 | 8 | } 9 | 10 | MapModel::~MapModel () { 11 | 12 | } 13 | 14 | 15 | id* MapModel::find(const string& name) { 16 | auto p = data.find(name); 17 | if (p != data.end()) return p->second; 18 | return NULL; 19 | } 20 | -------------------------------------------------------------------------------- /src/MetaModel/MetaModel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-14 14:33:49 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:46:33 6 | */ 7 | 8 | #include "MetaModel/MetaModel.h" 9 | #include "CodeGenContext.h" 10 | 11 | MetaModel::MetaModel(std::string name) { 12 | this->name = name; 13 | } 14 | 15 | MetaModel::~MetaModel() { 16 | 17 | } 18 | 19 | MetaModel* MetaModel::readJson() { 20 | return NULL; 21 | } 22 | 23 | MetaModel* MetaModel::readMetaCode() { 24 | return NULL; 25 | } 26 | -------------------------------------------------------------------------------- /src/MetaModel/StructModel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-31 18:24:33 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-24 09:46:46 6 | */ 7 | 8 | #include "MetaModel/StructModel.h" 9 | #include "CodeGenContext.h" 10 | #include "idtable.h" 11 | 12 | 13 | 14 | StructModel::StructModel(std::string& name, 15 | std::vector& type_list, 16 | std::vector& name_list) 17 | : MetaModel(name) 18 | { 19 | this->type_list = type_list; 20 | this->name_list = name_list; 21 | } 22 | 23 | int StructModel::find(std::string& name) 24 | { 25 | int i = 0; 26 | if (name_list.size() == 0) return -1; 27 | for (auto& p : name_list) { 28 | if (name == p) return i; 29 | ++i; 30 | } 31 | return -1; 32 | } 33 | 34 | void StructModel::insertToST(CodeGenContext* context) { 35 | context->st->insert(name, struct_t, LValue(this)); // 插入符号表中 36 | } 37 | 38 | LValue StructModel::getStruct(CodeGenContext* context) { 39 | if (struct_type == NULL) 40 | struct_type = context->getLLCG()->DeclareStruct(name); 41 | return struct_type; 42 | } 43 | 44 | void StructModel::genCode(CodeGenContext* context) { 45 | std::vector type_vec; 46 | for (auto& s : type_list) { 47 | LValue t = context->FindType(s); 48 | type_vec.push_back(t); 49 | } 50 | struct_type = context->getLLCG()->Struct(getStruct(context), type_vec); 51 | } 52 | 53 | 54 | void StructModel::genMetaCode(CodeGenContext* context) { 55 | vector data; 56 | data.push_back("struct"); 57 | data.push_back(name); 58 | for (int i = 0; i < name_list.size(); ++i) { 59 | data.push_back(type_list[i]); 60 | data.push_back(name_list[i]); 61 | } 62 | context->getLLCG()->MakeMetaList(data); 63 | } 64 | 65 | MetaType StructModel::getMetaType() { 66 | return struct_meta_t; 67 | } 68 | -------------------------------------------------------------------------------- /src/Model/ByteNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #include "ByteNode.h" 7 | 8 | /** 9 | * ByteNode implementation 10 | */ 11 | 12 | -------------------------------------------------------------------------------- /src/Model/CharNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #include "CharNode.h" 7 | 8 | /** 9 | * CharNode implementation 10 | */ 11 | -------------------------------------------------------------------------------- /src/Model/FloatNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #include "FloatNode.h" 7 | #include 8 | #include "elegantlist.hpp" 9 | #include "Utils/string_formatter.h" 10 | /** 11 | * FloatNode implementation 12 | */ 13 | 14 | FloatNode::FloatNode(const char* num) { 15 | value = atof(num); 16 | } 17 | 18 | FloatNode* FloatNode::Create(const char* num) { 19 | return new FloatNode(num); 20 | } 21 | 22 | NodeType FloatNode::getType() { 23 | return float_node_t; 24 | } 25 | 26 | float FloatNode::getFloat() { 27 | return value; 28 | } 29 | 30 | void FloatNode::printSelf() { 31 | Node::el.print(string_format("%f.2", value)); 32 | } 33 | -------------------------------------------------------------------------------- /src/Model/IDNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #include "IDNode.h" 7 | #include "elegantlist.hpp" 8 | 9 | /** 10 | * IDNode implementation 11 | */ 12 | 13 | IDNode* IDNode::Create(const char* _value) { 14 | return new IDNode(_value); 15 | } 16 | 17 | IDNode* IDNode::Create(char _value) { 18 | return new IDNode(_value); 19 | } 20 | 21 | IDNode::IDNode(const char* _value){ 22 | this->value = _value; 23 | } 24 | IDNode::IDNode(char _value){ 25 | this->value = _value; 26 | } 27 | 28 | void IDNode::printSelf() { 29 | // printf("ID %s", value.c_str()); 30 | Node::el.print(value); 31 | } 32 | 33 | NodeType IDNode::getType() { 34 | return id_node_t; 35 | } 36 | -------------------------------------------------------------------------------- /src/Model/IntNode.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Project Untitled 3 | */ 4 | 5 | 6 | #include "IntNode.h" 7 | #include 8 | #include 9 | #include "elegantlist.hpp" 10 | #include "Utils/string_formatter.h" 11 | /** 12 | * IntNode implementation 13 | */ 14 | 15 | IntNode* IntNode::Create(const char* num) { 16 | return new IntNode(num); 17 | } 18 | 19 | IntNode::IntNode(const char* num) { 20 | value = atoi(num); 21 | } 22 | 23 | void IntNode::printSelf() { 24 | Node::el.print(string_format("%d", value)); 25 | } 26 | 27 | NodeType IntNode::getType() { 28 | return int_node_t; 29 | } 30 | -------------------------------------------------------------------------------- /src/Model/ModelCodeGen.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-12 19:21:50 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 21:58:03 6 | */ 7 | 8 | #include "CodeGenContext.h" 9 | #include "nodes.h" 10 | 11 | #include 12 | using namespace std; 13 | 14 | 15 | LValue Node::codeGen(CodeGenContext* context) { 16 | return context->MacroMake(this); 17 | } 18 | 19 | LValue IntNode::codeGen(CodeGenContext* context) { 20 | return context->getLLCG()->ConstInt(value); 21 | } 22 | 23 | LValue FloatNode::codeGen(CodeGenContext* context) { 24 | return context->getLLCG()->ConstDouble(value); 25 | } 26 | 27 | 28 | LValue StringNode::codeGen(CodeGenContext* context) { 29 | return context->getLLCG()->ConstString(value); 30 | } 31 | 32 | LValue IDNode::codeGen(CodeGenContext* context) { 33 | LValue v = context->FindVar(value); 34 | if (v == NULL) { 35 | cerr << "未定义的变量: " << value << endl; 36 | return NULL; 37 | } 38 | if (context->isSave()) return v; 39 | return context->getLLCG()->Load(v); 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Model/Node.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-22 19:21:40 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-10 18:19:23 6 | */ 7 | 8 | #include "Node.h" 9 | #include 10 | #include 11 | #include "nodes.h" 12 | #include 13 | #include "elegantlist.hpp" 14 | 15 | void Node::init() { 16 | next = child = NULL; 17 | } 18 | 19 | Node::Node() { 20 | init(); 21 | } 22 | 23 | Node::Node(Node* n) { 24 | init(); 25 | addChildren(n); 26 | } 27 | 28 | Node::~Node() { 29 | 30 | } 31 | 32 | Node* Node::Create(Node* n) { 33 | return new Node(n); 34 | } 35 | 36 | Node* Node::Create() { 37 | return new Node(); 38 | } 39 | 40 | void Node::Free(Node*& p) { 41 | if (p != NULL) { 42 | delete p; 43 | p = NULL; 44 | } 45 | } 46 | 47 | void Node::FreeAll(Node*& p) { 48 | if (p != NULL) { 49 | Node::FreeAll(p->next); 50 | Node::FreeAll(p->child); 51 | delete p; 52 | p = NULL; 53 | } 54 | } 55 | 56 | Node* Node::copy() { 57 | return new Node(*this); 58 | } 59 | 60 | Node* Node::copyAll() { 61 | Node* n = copy(); 62 | if (next != NULL) n->next = next->copyAll(); 63 | if (child != NULL) n->child = child->copyAll(); 64 | return n; 65 | } 66 | 67 | Node* Node::copyChild() { 68 | Node* n = copy(); 69 | n->next = NULL; 70 | if (child != NULL) n->child = child->copyAll(); 71 | return n; 72 | } 73 | 74 | 75 | void Node::replaceNext(Node* node) { 76 | Node* n = this->next; 77 | if (n == NULL) { printf("替换失败\n"); return; } 78 | next = node; 79 | node->next = n->next; 80 | Node::FreeAll(n->child); 81 | Node::Free(n); 82 | } 83 | 84 | void Node::replaceChild(Node* node) { 85 | Node* n = this->child; 86 | if (n == NULL) { printf("替换失败\n"); return; } 87 | child = node; 88 | Node::FreeAll(n); 89 | } 90 | 91 | void Node::replaceChildFirst(Node* node) { 92 | Node* n = this->child; 93 | if (n == NULL) { printf("替换失败\n"); return; } 94 | child = node; 95 | node->next = n->next; 96 | Node::FreeAll(n->child); 97 | Node::Free(n); 98 | } 99 | 100 | void Node::addChildren(Node* n) { 101 | if (child == NULL) { 102 | child = n; 103 | } else { 104 | child->addBrother(n); 105 | } 106 | } 107 | 108 | void Node::addBrother (Node* n) { 109 | Node* p = this; 110 | while (p->next != NULL) { 111 | p = p->next; 112 | } 113 | p->next = n; 114 | } 115 | 116 | void Node::print(int k) { 117 | if (getType() != node_t) { 118 | printSelf(); 119 | } else { 120 | el.print("("); 121 | Node* p = child; 122 | while (p != NULL) { 123 | p->print(k+1); 124 | p = p->next; 125 | } 126 | el.print(")"); 127 | } 128 | if (k == 0) printf("\n\n"); 129 | // for (int i = 0; i < k; ++i) 130 | // printf(" "); 131 | // printSelf(); 132 | // printf("\n"); 133 | // 134 | // Node* p = child; int t = 0; 135 | // while (p != NULL) { 136 | // p->print(k+1); 137 | // p = p->next; 138 | // ++t; 139 | // } 140 | // if (t >= 3) printf("\n"); 141 | } 142 | 143 | void Node::printSelf() { 144 | Node::el.print("Node"); 145 | } 146 | 147 | NodeType Node::getType() { 148 | return node_t; 149 | } 150 | 151 | bool Node::isSingle() { 152 | return next == NULL; 153 | } 154 | 155 | Node* Node::make_list(int num, ...) { 156 | va_list argp; Node* para = NULL; 157 | Node* ans = NULL; 158 | va_start( argp, num ); 159 | for (int i = 0; i < num; ++i) { 160 | para = va_arg( argp, Node* ); 161 | if (para == NULL) continue; 162 | if (!para->isSingle()) para = new Node(para); 163 | if ( ans == NULL ) 164 | ans = para; 165 | else ans->addBrother(para); 166 | } 167 | va_end( argp ); 168 | return ans; 169 | } 170 | 171 | Node* Node::makeList(int num, Node* plist[]) { 172 | Node* para = NULL; 173 | Node* ans = NULL; 174 | for (int i = 0; i < num; ++i) { 175 | para = plist[i]; 176 | if (para == NULL) continue; 177 | if (!para->isSingle()) para = new Node(para); 178 | if ( ans == NULL ) 179 | ans = para; 180 | else ans->addBrother(para); 181 | } 182 | return ans; 183 | } 184 | 185 | Node* Node::getList(Node* node) { 186 | if (!node->isSingle()) return new Node(node); 187 | return node; 188 | } 189 | 190 | bool Node::isNode() { 191 | return getType() == node_t; 192 | } 193 | 194 | bool Node::isIntNode() { 195 | return getType() == int_node_t; 196 | } 197 | 198 | bool Node::isFloatNode() { 199 | return getType() == float_node_t; 200 | } 201 | 202 | bool Node::isIDNode() { 203 | return getType() == id_node_t; 204 | } 205 | 206 | bool Node::isStringNode() { 207 | return getType() == string_node_t; 208 | } 209 | 210 | bool Node::isCharNode() { 211 | return getType() == char_node_t; 212 | } 213 | 214 | bool Node::isTypeNode() { 215 | return getType() == type_node_t; 216 | } 217 | 218 | 219 | std::string Node::getTypeName() { 220 | switch (getType()) { 221 | case node_t: return "Node"; 222 | case int_node_t: return "IntNode"; 223 | case string_node_t: return "StringNode"; 224 | case id_node_t: return "IDNode"; 225 | case char_node_t: return "CharNode"; 226 | case float_node_t: return "FloatNode"; 227 | case type_node_t: return "TypeNode"; 228 | } 229 | } 230 | 231 | std::string& Node::getStr() { 232 | std::cerr << "getStr() - 获取字符串错误, 该类型不正确: " << getTypeName() << std::endl; 233 | exit(1); 234 | } 235 | 236 | ElegantList Node::el; 237 | -------------------------------------------------------------------------------- /src/Model/StringNode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-22 22:00:32 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-16 22:42:02 6 | */ 7 | 8 | 9 | #include "StringNode.h" 10 | #include 11 | #include "elegantlist.hpp" 12 | #include "Utils/StringEscape.h" 13 | 14 | StringNode::StringNode(const char* _value){ 15 | string data = _value; 16 | if (data[0] == '@') 17 | this->value = StringEscape(data.substr(2, data.length()-3)); 18 | else 19 | this->value = StringEscape(data.substr(1, data.length()-2)); 20 | } 21 | 22 | StringNode::StringNode(char _value){ 23 | this->value = _value; 24 | } 25 | 26 | StringNode* StringNode::Create(const char* _value) { 27 | return new StringNode(_value); 28 | } 29 | 30 | StringNode* StringNode::Create(char _value) { 31 | return new StringNode(_value); 32 | } 33 | 34 | 35 | void StringNode::printSelf() { 36 | // printf("String %s", value.c_str()); 37 | Node::el.print("\"" + value + "\""); 38 | } 39 | 40 | NodeType StringNode::getType() { 41 | return string_node_t; 42 | } 43 | -------------------------------------------------------------------------------- /src/Model/TypeNode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-11-19 13:40:13 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-21 17:12:32 6 | */ 7 | 8 | #include "TypeNode.h" 9 | #include "CodeGenContext.h" 10 | #include "elegantlist.hpp" 11 | #include 12 | using namespace std; 13 | 14 | TypeNode* TypeNode::Create(const char* name, bool is_const, bool is_source) { 15 | return new TypeNode(name, is_const, is_source); 16 | } 17 | 18 | LValue TypeNode::typeGen(CodeGenContext* context) { 19 | LValue t = context->FindType(str); 20 | if (t == NULL) { 21 | cerr << "找不到该类型的定义:"; 22 | cerr << str.c_str() << endl; 23 | exit(1); 24 | } 25 | return t; 26 | } 27 | 28 | void TypeNode::addDimension() { 29 | ++dimension; 30 | str += "[]"; 31 | } 32 | 33 | 34 | NodeType TypeNode::getType() { 35 | return type_node_t; 36 | } 37 | 38 | string& TypeNode::getStr() { 39 | return str; 40 | } 41 | 42 | string& TypeNode::getTypeName() { 43 | return name; 44 | } 45 | 46 | void TypeNode::printSelf() { 47 | // printf("Type "); 48 | if (is_const) Node::el.print("const"); 49 | // printf("%s", str.c_str()); 50 | Node::el.print(str); 51 | } 52 | 53 | TypeNode::TypeNode(const char* name, bool is_const, bool is_source) { 54 | this->str = name; 55 | this->name = name; 56 | this->is_const = is_const; 57 | this->is_source = is_source; 58 | if (is_source) { 59 | this->str.insert(str.begin(), '*'); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Pass.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Pass.h" 3 | 4 | Pass::Pass (const FuncReg* macro_funcs) { 5 | AddOrReplaceMacros(macro_funcs); 6 | } 7 | 8 | Pass::Pass (const FuncReg* macro_funcs, const FuncReg* macro_funcs2) { 9 | AddOrReplaceMacros(macro_funcs); 10 | AddOrReplaceMacros(macro_funcs2); 11 | } 12 | 13 | Pass::~Pass () { 14 | 15 | } 16 | 17 | void Pass::Init() { 18 | 19 | } 20 | 21 | ICodeGenFunction* Pass::getMacro(const string& str) { 22 | auto func = macro_map.find(str); 23 | if (func != macro_map.end()) return func->second; 24 | else return NULL; 25 | } 26 | 27 | 28 | void Pass::AddOrReplaceMacros(const FuncReg* macro_funcs) { 29 | while (true) { 30 | const char* name = macro_funcs->name; 31 | CodeGenCFunction func = macro_funcs->func; 32 | if (name == 0) return; 33 | string fname = name; 34 | auto p = macro_map.find(fname); 35 | if (p != macro_map.end()) 36 | p->second = new CodeGenFunction(func); 37 | else 38 | macro_map[fname] = new CodeGenFunction(func); 39 | ++macro_funcs; 40 | } 41 | } 42 | 43 | void Pass::AddOrReplaceMacros(const string& name, ICodeGenFunction* func) { 44 | macro_map[name] = func; 45 | } 46 | 47 | void Pass::RemoveAllMacros() { 48 | macro_map.clear(); 49 | } 50 | 51 | 52 | void Pass::SaveMacros() { 53 | macro_save_stack.push(macro_map); 54 | } 55 | 56 | void Pass::RecoverMacros() { 57 | macro_map = macro_save_stack.top(); 58 | macro_save_stack.pop(); 59 | } 60 | -------------------------------------------------------------------------------- /src/PassManager.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PassManager.h" 3 | #include "ICodeGenContext.h" 4 | 5 | 6 | PassManager::PassManager () { 7 | 8 | } 9 | 10 | PassManager::~PassManager () { 11 | 12 | } 13 | 14 | 15 | void PassManager::NewPassList(const string& name, const vector& vec) { 16 | NewPassList(name, list(vec.begin(), vec.end())); 17 | } 18 | 19 | 20 | void PassManager::NewPassList(const string& name, const list& lst) { 21 | pass_lists[name] = lst; 22 | } 23 | 24 | 25 | list* PassManager::getPassList(const string& name) { 26 | auto idx = pass_lists.find(name); 27 | if (idx != pass_lists.end()) return &(idx->second); 28 | return NULL; 29 | } 30 | 31 | 32 | void PassManager::RunPassList(const string& name, Node* node, ICodeGenContext* ctx) { 33 | auto idx = pass_lists.find(name); 34 | if (idx != pass_lists.end()) { 35 | for (auto i : idx->second) { 36 | // 设置i为活动pass 37 | ctx->setNowPass(i); 38 | ctx->MacroMake(node); 39 | } 40 | } 41 | } 42 | 43 | void PassManager::RunPassListWithSet(const string& name, set& nodes, ICodeGenContext* ctx) { 44 | auto idx = pass_lists.find(name); 45 | if (idx != pass_lists.end()) { 46 | for (auto i : idx->second) { 47 | // 设置i为活动pass 48 | ctx->setNowPass(i); 49 | for (auto node : nodes) 50 | ctx->MacroMake(node); 51 | } 52 | } 53 | } 54 | 55 | 56 | extern const FuncReg macro_funcs[]; 57 | extern const FuncReg macro_classes[]; 58 | extern const FuncReg macro_prescan[]; 59 | extern const FuncReg macro_pretype[]; 60 | extern const FuncReg macro_defmacro[]; 61 | 62 | 63 | void PassManager::LoadDefaultLists() { 64 | list prescan = { new Pass(macro_defmacro), new Pass(macro_prescan), new Pass(macro_pretype) }; 65 | list main = { new Pass(macro_funcs, macro_classes) }; 66 | NewPassList("prescan", prescan); 67 | NewPassList("main", main); 68 | } 69 | -------------------------------------------------------------------------------- /src/RedCodeGen.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-09-23 22:57:41 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-11-25 22:03:20 6 | */ 7 | 8 | #include "RedCodeGen.h" 9 | #include "idtable.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #include "CodeGenContext.h" 17 | 18 | RedCodeGen::RedCodeGen() { 19 | 20 | } 21 | 22 | RedCodeGen* RedCodeGen::Create() { 23 | return new RedCodeGen(); 24 | } 25 | 26 | void RedCodeGen::Init() { 27 | if (this->context != NULL) { 28 | delete context; 29 | context = NULL; 30 | } 31 | this->context = new CodeGenContext(); 32 | pm.LoadDefaultLists(); 33 | this->context->setPassManager(&pm); 34 | } 35 | 36 | RedCodeGen::~RedCodeGen() { 37 | if (context != NULL) delete context; 38 | } 39 | 40 | 41 | void RedCodeGen::PreScan(Node* node) { 42 | pm.RunPassList("prescan", node, context); 43 | } 44 | 45 | void RedCodeGen::PreScan(std::set& nodes) { 46 | pm.RunPassListWithSet("prescan", nodes, context); 47 | } 48 | 49 | 50 | void RedCodeGen::MakeMeta(const char* outfile_name, const char* module_name) { 51 | string out_name = outfile_name; 52 | string mod_name = module_name; 53 | context->getLLCG()->MakeMetaModule(out_name, mod_name); 54 | } 55 | 56 | 57 | void RedCodeGen::Make(Node* node, const char* outfile_name, const char* module_name) { 58 | string mod_name = module_name; 59 | context->st->push(); // 进入文件局部符号表 60 | context->Init(); 61 | context->getLLCG()->BeginModule(mod_name); 62 | // 正式流程 63 | pm.RunPassList("main", node, context); 64 | string out_name = outfile_name; 65 | context->getLLCG()->VerifyAndWrite(out_name); 66 | context->st->pop(); // 离开该文件符号表 67 | } 68 | -------------------------------------------------------------------------------- /src/Utils/StringEscape.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StringEscape.h" 3 | #include 4 | #include 5 | 6 | char StringEscapeGetChar(const char*& p) { 7 | ++p; char c; 8 | switch(*p) { 9 | case 'a': c = '\a'; break; 10 | case 'b': c = '\b'; break; 11 | case 'f': c = '\f'; break; 12 | case 'n': c = '\n'; break; 13 | case 'r': c = '\r'; break; 14 | case 't': c = '\t'; break; 15 | case 'v': c = '\v'; break; 16 | case '0': c = '\0'; break; 17 | default: c = *p; 18 | } 19 | return c; 20 | } 21 | 22 | char* CharEscape(const char* str) { 23 | int len = strlen(str); 24 | char* ret = new char[len+1]; 25 | char* ans = ret; 26 | for (const char* p = str; *p != 0; ++p, ++ans) { 27 | if (*p != '\\') 28 | *ans = *p; 29 | else 30 | *ans = StringEscapeGetChar(p); 31 | } 32 | *ans = 0; 33 | return ret; 34 | } 35 | 36 | string StringEscape(const string& str) { 37 | char* c = CharEscape(str.c_str()); 38 | string s = c; 39 | delete[] c; 40 | return s; 41 | } 42 | -------------------------------------------------------------------------------- /src/Utils/StringEscape.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: sxf 3 | * @Date: 2015-10-25 09:21:30 4 | * @Last Modified by: sxf 5 | * @Last Modified time: 2015-12-14 17:16:11 6 | */ 7 | 8 | 9 | #ifndef STRING_ESCAPE_H 10 | #define STRING_ESCAPE_H 11 | 12 | #include 13 | using namespace std; 14 | 15 | /** 16 | * @brief 字符串转义函数 17 | */ 18 | char* CharEscape(const char* str); 19 | string StringEscape(const string& str); 20 | 21 | #endif // STRING_ESCAPE_H 22 | -------------------------------------------------------------------------------- /src/Utils/string_formatter.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elite-lang/RedApple/09a389e794075937cfd21b14873c439f9804b38f/src/Utils/string_formatter.h -------------------------------------------------------------------------------- /src/idmap.cpp: -------------------------------------------------------------------------------- 1 | #include "idmap.h" 2 | 3 | IDMap::IDMap() 4 | { 5 | } 6 | 7 | IDMap::~IDMap() 8 | { 9 | for (auto p : ID_map) { 10 | id* pid = p.second; 11 | delete pid; 12 | } 13 | } 14 | 15 | id* IDMap::find(const string& str) const { 16 | auto p = ID_map.find(str); 17 | if (p != ID_map.end()) 18 | return (*p).second; 19 | return NULL; 20 | } 21 | 22 | map& IDMap::getAll() { 23 | return ID_map; 24 | } 25 | 26 | void IDMap::insert(const string& str, int level, SymbolType type, LValue data) { 27 | id* i = new id(); 28 | i->level = level; 29 | i->type = type; 30 | i->data = data; 31 | ID_map[str] = i; 32 | } 33 | -------------------------------------------------------------------------------- /src/idmap.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #ifndef IDMAP_H 6 | #define IDMAP_H 7 | 8 | #include "LLCG/lvalue.h" 9 | 10 | 11 | /** 12 | * 符号表中符号的基本类型 13 | */ 14 | enum SymbolType 15 | { 16 | var_t, type_t, struct_t, enum_t, delegate_t, function_t, macro_t, map_t, conditions_t 17 | }; 18 | 19 | /** 20 | * @brief 栈式符号表返回的临时对象, 用来打包类型信息和值等, 无需释放资源 21 | */ 22 | struct id { 23 | int level; 24 | SymbolType type; 25 | LValue data; 26 | }; 27 | 28 | 29 | /** 30 | * @brief 一款简单的栈式符号表,代表栈的一层 31 | * @details 简单的栈式符号表,负责一层局部符号,用Map构建,而存储的内容则是void*,使用时必须强制类型转换 32 | */ 33 | class IDMap 34 | { 35 | public: 36 | IDMap(); 37 | ~IDMap(); 38 | 39 | /** 40 | * @brief 查找一个符号,若不存在返回空 41 | * 42 | * @param str 符号名 43 | * @return 返回对应的id结构体指针,未找到返回NULL 44 | */ 45 | id* find(const string& str) const; 46 | 47 | /** 48 | * @brief 返回当前表中全部元素 49 | */ 50 | map& getAll(); 51 | 52 | /** 53 | * @brief 插入一个符号 54 | * 55 | * @param str 名字 56 | * @param level 当前层次 57 | * @param type 枚举类型 58 | * @param data 数据指针 59 | */ 60 | void insert(const string& str, int level, SymbolType type, LValue data); 61 | private: 62 | map ID_map; 63 | }; 64 | 65 | #endif // IDMAP_H 66 | -------------------------------------------------------------------------------- /src/idtable.cpp: -------------------------------------------------------------------------------- 1 | #include "idtable.h" 2 | 3 | IDTable::IDTable() 4 | { 5 | ID_stack.push_back(IDMap()); 6 | } 7 | 8 | id* IDTable::find(const string& idname) const { 9 | for (auto p = ID_stack.rbegin(); p != ID_stack.rend(); ++p) { 10 | const IDMap& imap = *p; 11 | id* pid = imap.find(idname); 12 | if (pid != NULL) return pid; 13 | } 14 | return NULL; 15 | } 16 | 17 | map& IDTable::getAll(int level) { 18 | return ID_stack[level].getAll(); 19 | } 20 | 21 | void IDTable::insert(const string& str,SymbolType type, LValue data) { 22 | IDMap& imap = ID_stack.back(); 23 | imap.insert(str,getLevel(), type, data); 24 | } 25 | 26 | void IDTable::push() { 27 | ID_stack.push_back(IDMap()); 28 | } 29 | 30 | void IDTable::pop() { 31 | ID_stack.pop_back(); 32 | } 33 | 34 | int IDTable::getLevel() { 35 | return ID_stack.size()-1; 36 | } 37 | -------------------------------------------------------------------------------- /src/idtable.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "idmap.h" 3 | using namespace std; 4 | 5 | #ifndef IDTABLE_H 6 | #define IDTABLE_H 7 | 8 | 9 | /** 10 | * @brief 简易栈式符号表,需要在进入函数后手动压栈等操作 11 | */ 12 | class IDTable 13 | { 14 | public: 15 | IDTable(); 16 | 17 | /** 18 | * @brief 查找元素是否在符号表中 19 | * @details 查找元素是否在当前符号表中,若当前符号栈不只一层,还好向上层符号表进行查找 20 | * 21 | * @param str 要查找的符号名 22 | * @return 若找到,返回id结构体的指针,无需释放内存。未找到返回NULL 23 | */ 24 | id* find(const string& str) const; 25 | 26 | /** 27 | * @brief 返回一层的全部元素 28 | * 29 | * @param level 返回一层的全部元素,level是传入的层级 30 | * @return 返回的元素map 31 | */ 32 | map& getAll(int level); 33 | 34 | /** 35 | * @brief 插入一个元素 36 | * 37 | * @param str 要插入的名称 38 | * @param type 类型的枚举 39 | * @param data 数据指针 40 | */ 41 | void insert(const string& str,SymbolType type, LValue data); 42 | 43 | /** 44 | * @brief 压栈,一般在进入新的符号区域,例如函数体中 45 | */ 46 | void push(); 47 | 48 | /** 49 | * @brief 弹栈,在离开一个符号区域时需要手动调用 50 | */ 51 | void pop(); 52 | 53 | /** 54 | * @brief 获取当前层级 55 | */ 56 | int getLevel(); 57 | 58 | private: 59 | deque ID_stack; 60 | }; 61 | 62 | #endif // IDTABLE_H 63 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Model/nodes.h" 4 | #include "redapple_parser.hpp" 5 | #include "RedCodeGen.h" 6 | #include 7 | #define maxpath 1000 8 | using namespace std; 9 | 10 | const char help_message[] = "welcome for using Red Apple compiler v0.6!\nusage: red [options] src-files\n"; 11 | 12 | extern FILE* yyin; 13 | extern Node *programBlock; 14 | 15 | char* make_default_name(const char* filename) { 16 | int size = 0; 17 | for (const char* p = filename; *p != 0; ++p, ++size) 18 | if (*p == '.') break; 19 | char* str = new char[size+4]; 20 | strncpy(str, filename, size+1); 21 | str[size+1] = 'b'; 22 | str[size+2] = 'c'; 23 | str[size+3] = 0; 24 | return str; 25 | } 26 | 27 | Node* parseFile(const char* path) { 28 | FILE* file_in; 29 | if ((file_in = fopen(path, "r")) == NULL) { 30 | printf("找不到程序源文件: %s\n", path); 31 | return 0; 32 | } 33 | 34 | yyin = file_in; 35 | yyparse(); 36 | fclose(file_in); 37 | 38 | // 打印语法树 39 | printf("源文件 - %s\n", path); 40 | programBlock->print(0); 41 | return programBlock; 42 | } 43 | 44 | int main(int argc,const char *argv[]) 45 | { 46 | if (argc <= 1) printf(help_message); 47 | else { 48 | const char *file_in_name = argv[1]; 49 | Node* ans = parseFile(file_in_name); 50 | 51 | // 语法生成 52 | char* output_name = make_default_name(file_in_name); 53 | CodeGen* codegen = RedCodeGen::Create(); 54 | codegen->Init(); 55 | codegen->PreScan(ans); 56 | codegen->Make(ans, output_name); 57 | codegen->MakeMeta("meta.bc", "Meta"); 58 | delete codegen; 59 | 60 | /* you should close the file. */ 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /src/redapple_lex.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "Model/nodes.h" 4 | #include 5 | using namespace std; 6 | 7 | #include "redapple_parser.hpp" 8 | 9 | #define SAVE_TOKEN yylval.str = maketoken(yytext, yyleng) 10 | #define SAVE_STRING yylval.str = maketoken(yytext, yyleng) 11 | #define SAVE_STRING_NC yylval.str = maketoken(yytext, yyleng) 12 | extern "C" int yywrap() { return 1; } 13 | char* maketoken(const char* data, int len); 14 | %} 15 | 16 | %option yylineno 17 | 18 | %% 19 | 20 | "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/" ; /* 就是这种注释 */ 21 | 22 | #[^\n]*\n ; /* 井号注释 */ 23 | "//"[^\n]*\n ; /* 双线注释 */ 24 | 25 | [ \t\v\n\f] ; /* 过滤空白字符 */ 26 | 27 | /* 一些双元运算符 */ 28 | "++" return PP; 29 | "--" return SS; 30 | "<-" return LF; 31 | "->" return RF; 32 | "&&" return AND; 33 | "||" return OR; 34 | "!" return '!'; 35 | "::" return NSP; 36 | 37 | 38 | "+=" return PE; 39 | "-=" return SE; 40 | "*=" return ME; 41 | "/=" return DE; 42 | "&=" return AE; 43 | "|=" return OE; 44 | "^=" return XE; 45 | "%=" return MODE; 46 | "<<=" return FLE; 47 | ">>=" return FRE; 48 | 49 | 50 | /* 比较运算符 */ 51 | "==" return CEQ; 52 | "<=" return CLE; 53 | ">=" return CGE; 54 | "!=" return CNE; 55 | "<" return '<'; 56 | ">" return '>'; 57 | 58 | 59 | /* 界符 */ 60 | "(" return '('; 61 | ")" return ')'; 62 | "[" return '['; 63 | "]" return ']'; 64 | "{" return '{'; 65 | "}" return '}'; 66 | "." return '.'; 67 | "," return ','; 68 | "?" return '?'; 69 | ":" return ':'; 70 | ";" return ';'; 71 | "[]" return SZ; 72 | 73 | 74 | /* 基本运算符 */ 75 | "=" return '='; 76 | "+" return '+'; 77 | "-" return '-'; 78 | "*" return '*'; 79 | "/" return '/'; 80 | "%" return '%'; 81 | "^" return '^'; 82 | "&" return '&'; 83 | "|" return '|'; 84 | "~" return '~'; 85 | 86 | /* 宏运算符 */ 87 | "@" return '@'; 88 | ",@" return MBK; 89 | "`" return '`'; 90 | /* 下面声明要用到的关键字 */ 91 | 92 | /* 控制流 */ 93 | "if" return IF; 94 | "else" return ELSE; 95 | "while" return WHILE; 96 | "do" return DO; 97 | "until" return UNTIL; 98 | "goto" return GOTO; 99 | "for" return FOR; 100 | "foreach" return FOREACH; 101 | 102 | /* 退出控制 */ 103 | "break"|"continue"|"exit" SAVE_TOKEN; return KWS_EXIT; 104 | 105 | "return" return RETURN; 106 | 107 | /* 特殊运算符 */ 108 | "new" return NEW; 109 | "delete" return DELETE; 110 | "this" return THIS; 111 | 112 | /* 特殊定义 */ 113 | "delegate" return DELEGATE; 114 | "def" return DEF; 115 | "define" return DEFINE; 116 | "defmacro" return DEFMACRO; 117 | "import" return IMPORT; 118 | "using" return USING; 119 | "namespace" return NAMESPACE; 120 | "const" return CONST; 121 | "packed" return PACKED; 122 | "volatile" return VOLATILE; 123 | "woven" return WOVEN; 124 | 125 | "try"|"catch"|"finally"|"throw" SAVE_TOKEN; return KWS_ERROR; /* 异常控制 */ 126 | 127 | "null"|"true"|"false" SAVE_TOKEN; return KWS_TSZ; /* 特殊值 */ 128 | 129 | "struct"|"enum"|"union"|"module"|"interface"|"class" SAVE_TOKEN; return KWS_STRUCT; /* 结构声明 */ 130 | 131 | "public"|"private"|"protected" SAVE_TOKEN; return KWS_FWKZ; /* 访问控制 */ 132 | 133 | "static"|"extern"|"virtual"|"abstract"|"in"|"out" SAVE_TOKEN; return KWS_FUNC_XS; /* 函数修饰符 */ 134 | 135 | "var"|"auto" SAVE_TOKEN; return KWS_TYPE; /* 基本类型 */ 136 | 137 | [a-zA-Z_][a-zA-Z0-9_]* SAVE_TOKEN; return ID; /* 标识符 */ 138 | 139 | -?[0-9]*\.[0-9]* SAVE_TOKEN; return DOUBLE; 140 | -?[0-9]+ SAVE_TOKEN; return INTEGER; 141 | 0x[0-9A-Fa-f]+ SAVE_TOKEN; return INTEGER; 142 | 143 | \"(\\.|[^\\"])*\" SAVE_STRING; return STRING; /* 字符串 */ 144 | @\"(\\.|[^\\"])*\" SAVE_STRING_NC; return STRING; /* 无转义字符串 */ 145 | \'(\\.|.)\' SAVE_STRING; return CHAR; /* 字符 */ 146 | 147 | . printf("Unknown Token!\n"); yyterminate(); 148 | 149 | %% 150 | 151 | 152 | char* maketoken(const char* data, int len) { 153 | char* str = new char[len+1]; 154 | strncpy(str, data, len); 155 | str[len] = 0; 156 | return str; 157 | } 158 | -------------------------------------------------------------------------------- /src/redapple_parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "Model/nodes.h" 3 | #include 4 | using namespace std; 5 | 6 | #define YYERROR_VERBOSE 1 7 | 8 | Node *programBlock; /* the top level root node of our final AST */ 9 | 10 | extern int yylex(); 11 | extern int yylineno; 12 | extern char* yytext; 13 | extern int yyleng; 14 | 15 | void yyerror(const char *s); 16 | 17 | %} 18 | 19 | 20 | 21 | /* Represents the many different ways we can access our data */ 22 | 23 | %union { 24 | Node *nodes; 25 | char *str; 26 | int token; 27 | } 28 | 29 | 30 | 31 | /* Define our terminal symbols (tokens). This should 32 | 33 | match our tokens.l lex file. We also define the node type 34 | 35 | they represent. 36 | 37 | */ 38 | 39 | %token ID INTEGER DOUBLE 40 | %token CEQ CNE CGE CLE MBK 41 | %token '<' '>' '=' '+' '-' '*' '/' '%' '^' '&' '|' '~' '@' '?' ':' 42 | %token PP SS LF RF AND OR '!' NSP PE SE ME DE AE OE XE MODE FLE FRE SZ 43 | %token STRING CHAR 44 | %token IF ELSE WHILE DO UNTIL GOTO FOR FOREACH 45 | %token DELEGATE DEF DEFINE IMPORT USING NAMESPACE DEFMACRO CONST PACKED VOLATILE WOVEN 46 | %token RETURN NEW THIS DELETE 47 | %token KWS_EXIT KWS_ERROR KWS_TSZ KWS_STRUCT KWS_FWKZ KWS_FUNC_XS KWS_TYPE 48 | 49 | /* 50 | Define the type of node our nonterminal symbols represent. 51 | The types refer to the %union declaration above. Ex: when 52 | we call an ident (defined by union type ident) we are really 53 | calling an (NIdentifier*). It makes the compiler happy. 54 | */ 55 | 56 | %type program 57 | %type def_module_statement 58 | %type def_module_statements 59 | %type def_statement 60 | %type def_statements 61 | %type for_state 62 | %type if_state 63 | %type while_state 64 | %type dowhile_state 65 | %type dountil_state 66 | %type statement 67 | %type statements 68 | %type block 69 | %type types 70 | %type var_def 71 | %type marco_def 72 | %type macro_def_args 73 | %type macro_call 74 | %type func_def 75 | %type func_def_args 76 | %type func_def_xs 77 | %type numeric 78 | %type expr 79 | %type call_arg 80 | %type call_args 81 | %type return_state 82 | %type new_expr delete_expr 83 | %type var_exp 84 | %type macro_call_args 85 | %type list full_list woven_state 86 | 87 | 88 | 89 | //%type operator 这个设计容易引起规约冲突,舍弃 90 | /* Operator precedence for mathematical operators */ 91 | 92 | 93 | %left AE OE XE MODE FLE FRE 94 | %left PE SE 95 | %left ME DE 96 | %left '&' '|' 97 | %left CEQ CNE CLE CGE '<' '>' '=' 98 | %left '+' '-' 99 | %left '*' '/' '%' '^' 100 | %left '.' 101 | %right '~' PP SS 102 | %left '(' '[' ')' ']' 103 | %left MBK '@' 104 | 105 | %start program 106 | 107 | %% 108 | 109 | program : def_statements { programBlock = Node::getList($1); } 110 | ; 111 | 112 | def_module_statement : KWS_STRUCT ID '{' def_statements '}' { $$ = Node::make_list(3, IDNode::Create($1), IDNode::Create($2), $4); } 113 | | KWS_STRUCT ID ';' { $$ = Node::make_list(3, IDNode::Create($1), IDNode::Create($2), Node::Create()); } 114 | ; 115 | 116 | def_module_statements : def_module_statement { $$ = Node::getList($1); } 117 | | def_module_statements def_module_statement { $$ = $1; $$->addBrother(Node::getList($2)); } 118 | ; 119 | 120 | func_def_xs : KWS_FUNC_XS { $$ = IDNode::Create($1); } 121 | | func_def_xs KWS_FUNC_XS {$$ = $1; $$->addBrother(IDNode::Create($2)); } 122 | ; 123 | 124 | def_statement : var_def ';' { $$ = $1; } 125 | | func_def 126 | | marco_def 127 | | macro_call 128 | | '`' full_list { $$ = $2; } 129 | | def_module_statement 130 | | func_def_xs func_def { $$ = $2; $2->addBrother(Node::Create($1)); } 131 | | IMPORT STRING { $$ = Node::make_list(2, IDNode::Create("import"), IDNode::Create($2) ); } 132 | ; 133 | 134 | def_statements : def_statement { $$ = Node::getList($1); } 135 | | def_statements def_statement { $$ = $1; $$->addBrother(Node::getList($2)); } 136 | ; 137 | 138 | statements : statement { $$ = Node::getList($1); } 139 | | statements statement { $$ = $1; $$->addBrother(Node::getList($2)); } 140 | ; 141 | 142 | statement : def_statement 143 | | expr ';' { $$ = $1; } 144 | | block 145 | | if_state 146 | | while_state 147 | | dowhile_state 148 | | dountil_state 149 | | for_state 150 | | return_state 151 | | delete_expr ';' { $$ = $1; } 152 | ; 153 | 154 | if_state : IF '(' expr ')' statement { $$ = Node::make_list(3, IDNode::Create("if"), $3, $5); } 155 | | IF '(' expr ')' statement ELSE statement { $$ = Node::make_list(4, IDNode::Create("if"), $3, $5, $7); } 156 | ; 157 | 158 | while_state : WHILE '(' expr ')' statement { $$ = Node::make_list(3, IDNode::Create("while"), $3, $5); } 159 | ; 160 | 161 | dowhile_state : DO statement WHILE '(' expr ')' ';' { $$ = Node::make_list(3, IDNode::Create("dowhile"), $2, $5); } 162 | ; 163 | dountil_state : DO statement UNTIL '(' expr ')' ';' { $$ = Node::make_list(3, IDNode::Create("dountil"), $2, $5); } 164 | ; 165 | 166 | for_state : FOR '(' expr ';' expr ';' expr ')' statement { $$ = Node::make_list(5, IDNode::Create("for"), $3, $5, $7, $9); } 167 | | FOR '(' var_def ';' expr ';' expr ')' statement { $$ = Node::make_list(5, IDNode::Create("for"), Node::Create($3), $5, $7, $9); } 168 | ; 169 | 170 | return_state : RETURN ';' { $$ = IDNode::Create("return"); } 171 | | RETURN expr ';' { $$ = IDNode::Create("return"); $$->addBrother($2); } 172 | 173 | woven_state : WOVEN ID '(' call_args ')' { $$ = Node::make_list(2, IDNode::Create("woven"), IDNode::Create($2)); $$->addBrother($4); } 174 | ; 175 | 176 | block : '{' statements '}' { $$ = Node::Create($2); } 177 | | '{' '}' { $$ = Node::Create(); } 178 | ; 179 | 180 | types : ID { $$ = TypeNode::Create($1, false); } 181 | | CONST ID { $$ = TypeNode::Create($2, true); } 182 | | '*' ID { $$ = TypeNode::Create($2, false, true); } 183 | | CONST '*' ID { $$ = TypeNode::Create($3, true, true); } 184 | | types SZ { $$ = $1; ((TypeNode*)$1)->addDimension(); } 185 | ; 186 | 187 | var_def : types ID { $$ = Node::make_list(3, IDNode::Create("set"), $1, IDNode::Create($2)); } 188 | | types ID '=' expr { $$ = Node::make_list(4, IDNode::Create("set"), $1, IDNode::Create($2), $4); } 189 | ; 190 | 191 | macro_def_args : ID { $$ = IDNode::Create($1); } 192 | | macro_def_args ',' ID { $$ = $1; $1->addBrother(IDNode::Create($3)); } 193 | ; 194 | 195 | marco_def : DEFMACRO ID '(' macro_def_args ')' block 196 | { $$ = Node::make_list(4, IDNode::Create("defmacro"), IDNode::Create($2), $4, $6); } 197 | ; 198 | 199 | macro_call : '@' ID { $$ = IDNode::Create($2); } 200 | | macro_call '(' macro_call_args ')' { $$ = $1; $$->addBrother($3); } 201 | | macro_call block { $$ = $1; $$->addBrother(Node::getList($2)); } 202 | | macro_call ID block { $$ = $1; $$->addBrother(IDNode::Create($2)); $$->addBrother(Node::getList($3)); } 203 | ; 204 | 205 | func_def : types ID '(' func_def_args ')' block 206 | { $$ = Node::make_list(5, IDNode::Create("function"), $1, IDNode::Create($2), $4, $6); } 207 | | types ID '(' func_def_args ')' ';' 208 | { $$ = Node::make_list(5, IDNode::Create("function"), $1, IDNode::Create($2), $4, Node::Create()); } 209 | ; 210 | 211 | func_def_args : var_def { $$ = Node::Create(Node::Create($1)); } 212 | | func_def_args ',' var_def { $$ = $1; $$->addChildren(Node::Create($3)); } 213 | | %empty { $$ = Node::Create(); } 214 | ; 215 | 216 | 217 | new_expr : NEW types { $$ = Node::make_list(3, IDNode::Create("new"), $2, Node::Create()); } 218 | | NEW types '(' call_args ')' { $$ = Node::make_list(3, IDNode::Create("new"), $2, Node::Create($4)); } 219 | | new_expr '[' call_args ']' { $$ = $1; $1->addBrother(Node::Create($3)); } 220 | ; 221 | 222 | delete_expr : DELETE expr { $$ = Node::make_list(2, IDNode::Create("delete"), $2); } 223 | | DELETE '[' ']' expr { $$ = Node::make_list(2, IDNode::Create("delete[]"), $4); } 224 | ; 225 | 226 | numeric : INTEGER { $$ = IntNode::Create($1); } 227 | | DOUBLE { $$ = FloatNode::Create($1); } 228 | ; 229 | 230 | var_exp : ID { $$ = IDNode::Create($1); } 231 | | numeric 232 | | STRING { $$ = StringNode::Create($1); } 233 | | KWS_TSZ { $$ = IDNode::Create($1); } 234 | ; 235 | 236 | expr : expr '=' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("="), $1, $3); } 237 | | expr '(' call_args ')' { $$ = Node::make_list(2, IDNode::Create("call"), $1); $$->addBrother($3); } 238 | | expr '[' call_args ']' { $$ = Node::make_list(2, IDNode::Create("select"), $1); $$->addBrother($3); } 239 | | new_expr 240 | | var_exp 241 | | expr CEQ expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("=="), $1, $3); } 242 | | expr CNE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("!="), $1, $3); } 243 | | expr CLE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("<="), $1, $3); } 244 | | expr CGE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create(">="), $1, $3); } 245 | | expr '<' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("<"), $1, $3); } 246 | | expr '>' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create(">"), $1, $3); } 247 | | expr '<' '<' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("<<"), $1, $3); } 248 | | expr '>' '>' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create(">>"), $1, $3); } 249 | | expr '+' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("+"), $1, $3); } 250 | | expr '-' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("-"), $1, $3); } 251 | | expr '*' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("*"), $1, $3); } 252 | | expr '/' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("/"), $1, $3); } 253 | | expr '%' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("%"), $1, $3); } 254 | | expr '^' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("^"), $1, $3); } 255 | | expr '&' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("&"), $1, $3); } 256 | | expr '|' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("|"), $1, $3); } 257 | | expr PE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("+="), $1, $3); } 258 | | expr SE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("-="), $1, $3); } 259 | | expr ME expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("*="), $1, $3); } 260 | | expr DE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("/="), $1, $3); } 261 | | expr MODE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("%="), $1, $3); } 262 | | expr XE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("^="), $1, $3); } 263 | | expr AE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("&="), $1, $3); } 264 | | expr OE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("|="), $1, $3); } 265 | | expr FLE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("<<="), $1, $3); } 266 | | expr FRE expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create(">>="), $1, $3); } 267 | | expr '.' expr { $$ = Node::make_list(4, IDNode::Create("opt2"), IDNode::Create("."), $1, $3); } 268 | | '~' expr { $$ = Node::make_list(3, IDNode::Create("opt1"), IDNode::Create("~"), $2); } 269 | | PP expr { $$ = Node::make_list(3, IDNode::Create("opt1"), IDNode::Create("++"), $2); } 270 | | SS expr { $$ = Node::make_list(3, IDNode::Create("opt1"), IDNode::Create("--"), $2); } 271 | | expr PP { $$ = Node::make_list(3, IDNode::Create("opt1"), IDNode::Create("b++"), $1); } 272 | | expr SS { $$ = Node::make_list(3, IDNode::Create("opt1"), IDNode::Create("b--"), $1); } 273 | | '(' expr ')' /* ( expr ) */ { $$ = $2; } 274 | ; 275 | 276 | call_arg : expr { $$ = $1; } 277 | | ID '=' expr { $$ = Node::make_list(3, IDNode::Create("="), $1, $3); } 278 | ; 279 | 280 | call_args : %empty { $$ = NULL; } 281 | | call_arg { $$ = Node::getList($1); } 282 | | call_args ',' call_arg { $$ = $1; $$->addBrother(Node::getList($3)); } 283 | ; 284 | 285 | macro_call_args : %empty { $$ = Node::Create(); } 286 | | call_arg { $$ = Node::getList($1); } 287 | | macro_call { $$ = Node::getList($1); } 288 | | macro_call_args ',' call_arg { $$ = $1; $$->addBrother(Node::getList($3)); } 289 | | macro_call_args ',' macro_call { $$ = $1; $$->addBrother(Node::getList($3)); } 290 | ; 291 | 292 | list : var_exp 293 | | full_list 294 | | '!' types { $$ = $2; } 295 | | list var_exp { $$ = $1; $$->addBrother($2); } 296 | | list full_list { $$ = $1; $$->addBrother($2); } 297 | | list '!' types { $$ = $1; $$->addBrother($3); } 298 | ; 299 | 300 | full_list : '(' list ')' { $$ = Node::Create($2); } 301 | ; 302 | %% 303 | 304 | void yyerror(const char* s){ 305 | fprintf(stderr, "%s \n", s); 306 | fprintf(stderr, "line %d: ", yylineno); 307 | fprintf(stderr, "text %s \n", yytext); 308 | exit(1); 309 | } -------------------------------------------------------------------------------- /test1/test.red: -------------------------------------------------------------------------------- 1 | 2 | void hello(int k, int g) { 3 | printf("hello world"); 4 | } 5 | 6 | void main() { 7 | hello(1,2); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test1/test2.red: -------------------------------------------------------------------------------- 1 | 2 | void hello(int k, int g) { 3 | int y = k + g; 4 | printf("%d\n", y); 5 | if (k + g < 5) printf("right\n"); 6 | } 7 | 8 | 9 | void go(int k) { 10 | int a = 0; 11 | while (a < k) { 12 | printf("go-%d\n", a); 13 | a = a + 1; 14 | } 15 | } 16 | 17 | void print(int k) { 18 | for (int i = 0; i < 10; i = i+1) { 19 | printf("hello-%d\n",i); 20 | } 21 | } 22 | 23 | 24 | void main() { 25 | printf("hello world\n"); 26 | hello(1,2); 27 | print(9); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test1/test3.red: -------------------------------------------------------------------------------- 1 | 2 | 3 | void main() { 4 | pair a = new pair(); 5 | pair b = new pair(); 6 | a.x = 1; a.y = 0; 7 | b.x = 2; b.y = 10; 8 | printf("a.x = %d ", a.x); 9 | printf("a.y = %d\n", a.y); 10 | printf("b.x = %d ", b.x); 11 | printf("b.y = %d\n", b.y); 12 | printf("ans = %d\n", dot(a,b)); 13 | } 14 | 15 | 16 | int dot(pair a, pair b) { 17 | int k = a.x + b.y; 18 | printf("k = %d\n", k); 19 | return k; 20 | } 21 | 22 | struct pair { 23 | int x; 24 | int y; 25 | } 26 | -------------------------------------------------------------------------------- /test1/test4/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test : test4.o test5.o 3 | clang test4.o test5.o -o test 4 | 5 | test4.o : test4.bc 6 | llc-3.6 test4.bc -filetype=obj 7 | 8 | test5.o : test5.bc 9 | llc-3.6 test5.bc -filetype=obj 10 | 11 | test4.bc : test4.red 12 | ./redapple test4.red 13 | 14 | test5.bc : test5.red 15 | ./redapple test5.red 16 | -------------------------------------------------------------------------------- /test1/test4/test4.red: -------------------------------------------------------------------------------- 1 | import "test5.red" 2 | 3 | void main() { 4 | printf("hello world\n"); 5 | print(5); 6 | } 7 | -------------------------------------------------------------------------------- /test1/test4/test5.red: -------------------------------------------------------------------------------- 1 | 2 | void print(int k) { 3 | for (int i = 1; i <= k; i = i+1) { 4 | printf("hello-%d\n",i); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test1/test5/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test : meta.o test5.o 3 | clang++ meta.o test5.o -o test -L. -lruntime -ldyncall_s 4 | 5 | meta.o : meta.bc 6 | llc-3.6 meta.bc -filetype=obj 7 | 8 | test5.o : test5.bc 9 | llc-3.6 test5.bc -filetype=obj 10 | 11 | test5.bc meta.bc : test5.red 12 | ./redapple test5.red 13 | 14 | .PHONY: 15 | clean : 16 | -rm -rf *.bc *.o test -------------------------------------------------------------------------------- /test1/test5/test5.red: -------------------------------------------------------------------------------- 1 | 2 | void print(int k) { 3 | printf("hello-%d\n",k); 4 | } 5 | 6 | void main() { 7 | FunctionCall("print", 5); 8 | } 9 | -------------------------------------------------------------------------------- /test1/test6/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test : meta.o test6.o 3 | clang++ meta.o test6.o -o test -L. -lruntime -ldyncall_s 4 | 5 | meta.o : meta.bc 6 | llc-3.6 meta.bc -filetype=obj 7 | 8 | test6.o : test6.bc 9 | llc-3.6 test6.bc -filetype=obj 10 | 11 | test6.bc meta.bc : test6.red 12 | ./redapple test6.red 13 | 14 | .PHONY: 15 | clean : 16 | -rm -rf *.bc *.o test -------------------------------------------------------------------------------- /test1/test6/test6.red: -------------------------------------------------------------------------------- 1 | 2 | void print(int k) { 3 | @for_n (i, k) { 4 | printf("hello-%d\n", i); 5 | } 6 | } 7 | 8 | defmacro for_n (p, size, code) { 9 | for (int p = 1; p <= size; p = p+1) 10 | code; 11 | } 12 | 13 | 14 | void main() { 15 | FunctionCall("print", 5); 16 | } -------------------------------------------------------------------------------- /test1/test7/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test : meta.o test7.o 3 | clang++ meta.o test7.o -o test -L. -lruntime -ldyncall_s 4 | 5 | meta.o : meta.bc 6 | llc-3.6 meta.bc -filetype=obj 7 | 8 | test7.o : test7.bc 9 | llc-3.6 test7.bc -filetype=obj 10 | 11 | test7.bc meta.bc : test7.red 12 | ./redapple test7.red 13 | 14 | .PHONY: 15 | clean : 16 | -rm -rf *.bc *.o test -------------------------------------------------------------------------------- /test1/test7/test7.red: -------------------------------------------------------------------------------- 1 | `(function !void hello ((set !int k)) ( 2 | (call printf "hello world %d\n" k) 3 | )) 4 | 5 | void main() { 6 | int k = 0; 7 | int[] g = new int[10]; 8 | for (int i = 0; i < 10; ++i) { 9 | printf("%d\n", i); 10 | g[i] = ++k; 11 | hello(g[i]); 12 | } 13 | for (int j = 9; j >= 0; --j) { 14 | printf("%d\n", j); 15 | hello(g[j]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test1/test8/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test : meta.o test8.o 3 | clang++ meta.o test8.o -o test -L. -lruntime -ldyncall_s 4 | 5 | meta.o : meta.bc 6 | llc-3.6 meta.bc -filetype=obj 7 | 8 | test8.o : test8.bc 9 | llc-3.6 test8.bc -filetype=obj 10 | 11 | test8.bc meta.bc : test8.red 12 | ./redapple test8.red 13 | 14 | .PHONY: 15 | clean : 16 | -rm -rf *.bc *.o test -------------------------------------------------------------------------------- /test1/test8/declare.red: -------------------------------------------------------------------------------- 1 | 2 | extern void print(); 3 | 4 | -------------------------------------------------------------------------------- /test1/test8/test8.red: -------------------------------------------------------------------------------- 1 | import "declare.red" 2 | 3 | int main() { 4 | print(); 5 | } --------------------------------------------------------------------------------