diff --git a/.gitignore b/.gitignore index af9520e2cdaef62a4f3223d8ad9620d15ae14599..69e119b13c3a4684fae34e56b8eda332a0db3a30 100644 --- a/.gitignore +++ b/.gitignore @@ -128,4 +128,9 @@ m4/lt~obsolete.m4 # (meta build system like autotools, # can automatically generate from config.status script # (which is called by configure script)) -Makefile \ No newline at end of file +Makefile + +*.ll +*.bc +*.s +src/yacc_stuff/tokenizer.cpp diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..6feb2a46e3ba49c60586a39f70d4b8c891fd5f29 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "aloc启动", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/src/aloc", + "args": ["${workspaceFolder}/test/demoa+b.alo","--static","-L","${workspaceFolder}/build/src/lib"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/build", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "为 gdb 启用整齐打印", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index cc67606f330b4e5b4d643ce3adadee13122a081c..6d68035cdb5a9faf5dc3959684e90bde661d692a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,23 @@ { "python.linting.pylintEnabled": true, - "python.linting.enabled": true + "python.linting.enabled": true, + "files.associations": { + "*.s": "asm-intel-x86-generic", + "*.tcc": "cpp", + "numeric": "cpp", + "fstream": "cpp", + "iostream": "cpp", + "istream": "cpp", + "ostream": "cpp", + "shared_mutex": "cpp", + "system_error": "cpp", + "regex": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "*.def": "cpp", + "*.inc": "cpp", + "deque": "cpp", + "string": "cpp", + "vector": "cpp" + } } \ No newline at end of file diff --git a/configure.ac b/configure.ac index 1a8290500ce4a4654cba69de3f64b9fb51ed3a76..3b4eb5de4d6ea30227ff6fde4774f23030ea0f9d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_PREREQ([2.70]) +AC_PREREQ([2.69]) AC_INIT([AloLang Compiler], [Dev Beta], [https://github.com/XJTU-Youth/AloLang-Dev/issues]) AC_ARG_ENABLE([debug], @@ -17,12 +17,14 @@ AC_PROG_CXX AC_PROG_CC AC_PROG_LEX(noyywrap) AC_PROG_RANLIB - # Checks for libraries. # FIXME: Replace 'main' with a function in '-lboost_program_options': AC_CHECK_LIB([boost_program_options], [boost::program_options::strip_prefixes]) AC_CHECK_LIB([LLVM-11], [llvm::demangle]) + + + # Checks for header files. AC_CHECK_HEADERS([inttypes.h unistd.h]) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 5a680f317a65b94323cc494175b1bdab7f961590..161185990276a5f88afa463df6c278c972d9bc80 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,7 +1,7 @@ * [AloLang语言参考文档](/index) * [标准库](library/index) - * [alolang库:图](library/graph/index) - * [alolang库:math](library/math/index) + * [图](library/graph/index) + * [math](library/math/index) * [语言](language/index) * [预处理器](language/preprocessor/index) * [条件包含](language/preprocessor/conditional/index) @@ -11,52 +11,54 @@ * [TODO](language/initialization/index) * [Alolang关键字](language/keyword/index) * [类型关键字](language/keyword/type/index) - * [alolang关键字:long](language/keyword/type/long/index) - * [alolang关键字:anytype](language/keyword/type/anytype/index) - * [alolang关键字:float](language/keyword/type/float/index) - * [alolang关键字:enum](language/keyword/type/enum/index) - * [alolang关键字:void](language/keyword/type/void/index) - * [alolang关键字:char](language/keyword/type/char/index) - * [alolang关键字:bool](language/keyword/type/bool/index) - * [alolang关键字:struct](language/keyword/type/struct/index) - * [alolang关键字:string](language/keyword/type/string/index) - * [alolang关键字:signed](language/keyword/type/signed/index) - * [alolang关键字:double](language/keyword/type/double/index) - * [alolang关键字:int8_t](language/keyword/type/int8_t/index) - * [alolang关键词:unsigned](language/keyword/type/unsigned/index) - * [alolang关键字:int](language/keyword/type/int/index) - * [alolang关键字:int16_t](language/keyword/type/int16_t/index) - * [alolang关键字:array](language/keyword/type/array/index) - * [alolang关键字:int32_t](language/keyword/type/int32_t/index) - * [alolang关键词:auto](language/keyword/type/auto/index) + * [long](language/keyword/type/long/index) + * [anytype](language/keyword/type/anytype/index) + * [float](language/keyword/type/float/index) + * [enum](language/keyword/type/enum/index) + * [type](language/keyword/type/type/index) + * [void](language/keyword/type/void/index) + * [char](language/keyword/type/char/index) + * [bool](language/keyword/type/bool/index) + * [struct](language/keyword/type/struct/index) + * [string](language/keyword/type/string/index) + * [signed](language/keyword/type/signed/index) + * [double](language/keyword/type/double/index) + * [int8_t](language/keyword/type/int8_t/index) + * [unsigned](language/keyword/type/unsigned/index) + * [int](language/keyword/type/int/index) + * [int16_t](language/keyword/type/int16_t/index) + * [array](language/keyword/type/array/index) + * [int32_t](language/keyword/type/int32_t/index) + * [auto](language/keyword/type/auto/index) + * [空标识符 `_`](language/keyword/blank/index) * [代用运算符的关键字](language/keyword/alternative/index) - * [alolang关键字:and](language/keyword/alternative/and/index) - * [alolang关键字:not](language/keyword/alternative/not/index) - * [alolang关键字:xor](language/keyword/alternative/xor/index) - * [alolang关键字:or](language/keyword/alternative/or/index) + * [and](language/keyword/alternative/and/index) + * [not](language/keyword/alternative/not/index) + * [xor](language/keyword/alternative/xor/index) + * [or](language/keyword/alternative/or/index) * [运算符](language/keyword/operators/index) * [自修改运算符](language/keyword/operators/self_change/index) * [常量](language/keyword/literal/index) - * [alolang关键字:EOF](language/keyword/literal/EOF/index) - * [alolang关键字:false](language/keyword/literal/false/index) - * [alolang关键字:true](language/keyword/literal/true/index) + * [EOF](language/keyword/literal/EOF/index) + * [false](language/keyword/literal/false/index) + * [true](language/keyword/literal/true/index) * [语句声明关键字](language/keyword/statements/index) - * [alolang关键字:if](language/keyword/statements/if/index) - * [alolang关键字:for](language/keyword/statements/for/index) - * [alolang关键字:while](language/keyword/statements/while/index) - * [alolang关键字:do](language/keyword/statements/do/index) - * [alolang关键字:extern](language/keyword/statements/extern/index) - * [alolang关键字:else](language/keyword/statements/else/index) - * [alolang关键字:break](language/keyword/statements/break/index) - * [alolang关键字:goto](language/keyword/statements/goto/index) - * [alolang关键字:case](language/keyword/statements/case/index) - * [alolang关键字:foreach](language/keyword/statements/foreach/index) - * [alolang关键字:continue](language/keyword/statements/continue/index) - * [alolang关键字:export](language/keyword/statements/export/index) - * [alolang关键字:return](language/keyword/statements/return/index) - * [alolang关键字:catch](language/keyword/statements/catch/index) - * [alolang关键字:switch](language/keyword/statements/switch/index) - * [alolang关键字:try](language/keyword/statements/try/index) + * [if](language/keyword/statements/if/index) + * [for](language/keyword/statements/for/index) + * [while](language/keyword/statements/while/index) + * [do](language/keyword/statements/do/index) + * [extern](language/keyword/statements/extern/index) + * [else](language/keyword/statements/else/index) + * [break](language/keyword/statements/break/index) + * [goto](language/keyword/statements/goto/index) + * [case](language/keyword/statements/case/index) + * [foreach](language/keyword/statements/foreach/index) + * [continue](language/keyword/statements/continue/index) + * [export](language/keyword/statements/export/index) + * [return](language/keyword/statements/return/index) + * [catch](language/keyword/statements/catch/index) + * [switch](language/keyword/statements/switch/index) + * [try](language/keyword/statements/try/index) * [TODO](language/translation_phases/index) * [TODO](language/expressions/index) * [TODO](language/declarations/index) diff --git a/docs/index.html b/docs/index.html index 30e018f007364814b54ccbc656cd0ee61ff62f24..38f223cd3a9c6cf09a2c77515dd2f093228c280a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -30,6 +30,8 @@ - + + + diff --git a/docs/language/keyword/alternative/and/index.md b/docs/language/keyword/alternative/and/index.md index 3ff2b5e5c36b229fd23a35ae11251aa78a420632..5c934274f949ef6e634af11639876da710e0a2a5 100644 --- a/docs/language/keyword/alternative/and/index.md +++ b/docs/language/keyword/alternative/and/index.md @@ -1,4 +1,4 @@ -# alolang关键字:and +# and ## 用法 * 代用运算符:&& ## 示例 diff --git a/docs/language/keyword/alternative/not/index.md b/docs/language/keyword/alternative/not/index.md index d821decbf599f097956a525bbcd593b4b1ace1f1..b3de3d53a6086aaccc9299769c78a2ffb2b4a3e3 100644 --- a/docs/language/keyword/alternative/not/index.md +++ b/docs/language/keyword/alternative/not/index.md @@ -1,4 +1,4 @@ -# alolang关键字:not +# not ## 用法 * 代用运算符:! ## 示例 diff --git a/docs/language/keyword/alternative/or/index.md b/docs/language/keyword/alternative/or/index.md index 22494f62e553ad17b1998f2597d7bbefc93b2ad7..2bcbece30e6931b2e63a2752b253cdbcded80e45 100644 --- a/docs/language/keyword/alternative/or/index.md +++ b/docs/language/keyword/alternative/or/index.md @@ -1,4 +1,4 @@ -# alolang关键字:or +# or ## 用法 * 代用运算符:|| ## 示例 diff --git a/docs/language/keyword/alternative/xor/index.md b/docs/language/keyword/alternative/xor/index.md index fae51451a1eb7b6d3c920d3ab0d7181ccf2a6c1c..1f01e02100719050d048ad593941bd05f8c77abb 100644 --- a/docs/language/keyword/alternative/xor/index.md +++ b/docs/language/keyword/alternative/xor/index.md @@ -1,3 +1,3 @@ -# alolang关键字:xor +# xor ## 用法 * 代用运算符:^ \ No newline at end of file diff --git a/docs/language/keyword/blank/index.md b/docs/language/keyword/blank/index.md new file mode 100644 index 0000000000000000000000000000000000000000..fe0071b34d80d4f61d4bfae0a1adb7974f5fe355 --- /dev/null +++ b/docs/language/keyword/blank/index.md @@ -0,0 +1,14 @@ +# 空标识符 `_` + +AloLang语言中,单下划线`_`是一个特殊的标识符名称。你不应该将任何变量命名为`_`,因为它有特殊的用处。 + +单下划线`_`是空标识符,用于舍弃函数返回的某个返回值时使用。例子: + +``` +func return_three() -> int, int, int; //假设有一个返回三个int的函数 + +func main(){ + int a; + _, a, _ = return_three(); //我们只想用第二个返回值,丢弃第一个和第三个 +} +``` \ No newline at end of file diff --git a/docs/language/keyword/literal/EOF/index.md b/docs/language/keyword/literal/EOF/index.md index c0e89ce50189e5a9f6e045ae11fcc88e814ed629..8058f76442c110475b2092d21f2c26bc7c199633 100644 --- a/docs/language/keyword/literal/EOF/index.md +++ b/docs/language/keyword/literal/EOF/index.md @@ -1,4 +1,4 @@ -# alolang关键字:EOF +# EOF * 文件尾标识符 diff --git a/docs/language/keyword/literal/false/index.md b/docs/language/keyword/literal/false/index.md index 92187baec48338197f1c1f1c7976f38c07e8c7f5..f329e823fb6638c40802e74d42d7f715faade141 100644 --- a/docs/language/keyword/literal/false/index.md +++ b/docs/language/keyword/literal/false/index.md @@ -1,4 +1,4 @@ -# alolang关键字:false +# false * 布尔字面量 diff --git a/docs/language/keyword/literal/true/index.md b/docs/language/keyword/literal/true/index.md index f48833c1acf9590cd16cb6adbd233ef9d56d56d1..43fa7f490463b64aa329a40f048192abc004d267 100644 --- a/docs/language/keyword/literal/true/index.md +++ b/docs/language/keyword/literal/true/index.md @@ -1,4 +1,4 @@ -# alolang关键字:true +# true * 布尔字面量 diff --git a/docs/language/keyword/statements/break/index.md b/docs/language/keyword/statements/break/index.md index 4c671581c59aa7c233b395c1874c802c2345af3d..b5480315411715c6fe973de865c841f333765383 100644 --- a/docs/language/keyword/statements/break/index.md +++ b/docs/language/keyword/statements/break/index.md @@ -1,4 +1,4 @@ -# alolang关键字:break +# break * break语句: *1:break语句可以结束当前循环执行 *2:执行完break语句后,循环体中位于break语句就不会被执行 diff --git a/docs/language/keyword/statements/case/index.md b/docs/language/keyword/statements/case/index.md index 4706a939b9b10d04aa17c8ffecf045f255834408..be5b8aa771687958d681104cfbbe6568ed60586b 100644 --- a/docs/language/keyword/statements/case/index.md +++ b/docs/language/keyword/statements/case/index.md @@ -1,2 +1,2 @@ -# alolang关键字:case +# case * switch 语句:用作 case 标号的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/catch/index.md b/docs/language/keyword/statements/catch/index.md index 9180827c05a78a3c8bf41d8eb93dc18e44ea7b46..1acaf8ac2b55177b7807a3c765b3eb534f5c9ddb 100644 --- a/docs/language/keyword/statements/catch/index.md +++ b/docs/language/keyword/statements/catch/index.md @@ -1,2 +1,2 @@ -# alolang关键字:catch +# catch * 用于try-catch块 \ No newline at end of file diff --git a/docs/language/keyword/statements/continue/index.md b/docs/language/keyword/statements/continue/index.md index 5b17c45e68c900d6ff0ec798ce2a7f445db0840b..b46297701577b587ae05ac91107fd61db765f4d1 100644 --- a/docs/language/keyword/statements/continue/index.md +++ b/docs/language/keyword/statements/continue/index.md @@ -1,2 +1,2 @@ -# alolang关键字:continue +# continue * continue语句:跳过当前循环中的代码,强迫开始下一次循环。 \ No newline at end of file diff --git a/docs/language/keyword/statements/do/index.md b/docs/language/keyword/statements/do/index.md index 0cc3655790d0ff854c2adb89bf6cd2866d7e6cbe..2173ecfb632b35b883b0bbd99700d323bf333406 100644 --- a/docs/language/keyword/statements/do/index.md +++ b/docs/language/keyword/statements/do/index.md @@ -1,2 +1,2 @@ -# alolang关键字:do +# do * do-while 循环:该循环循环内容的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/else/index.md b/docs/language/keyword/statements/else/index.md index 26b9314279d5d3328566080501cf79d0068ba0fa..95a8145750941edc20d0d43bf8f9af6a28e3fe67 100644 --- a/docs/language/keyword/statements/else/index.md +++ b/docs/language/keyword/statements/else/index.md @@ -1,2 +1,2 @@ -# alolang关键字:else +# else * if语句:用于另一分支的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/export/index.md b/docs/language/keyword/statements/export/index.md index 7243710099cdb57048f164d496510246f46bf1d1..8ee897d75e32b2481532a9fe7d834ebcc285c966 100644 --- a/docs/language/keyword/statements/export/index.md +++ b/docs/language/keyword/statements/export/index.md @@ -1,2 +1,2 @@ -# alolang关键字:export +# export * 语言链接语句。 diff --git a/docs/language/keyword/statements/extern/index.md b/docs/language/keyword/statements/extern/index.md index f9ca999a2d7b9c029ef8a3fe2ee0149e353db9c4..94ef703d6d221a2564094fd8717ecda75953db6c 100644 --- a/docs/language/keyword/statements/extern/index.md +++ b/docs/language/keyword/statements/extern/index.md @@ -1,2 +1,2 @@ -# alolang关键字:extern +# extern * 语言链接语句。 diff --git a/docs/language/keyword/statements/for/index.md b/docs/language/keyword/statements/for/index.md index e63ffa858ae07dc45fa3be4498451877a83fe67d..9de2a9b619165ec4a691a0eab7a8b25f974eb608 100644 --- a/docs/language/keyword/statements/for/index.md +++ b/docs/language/keyword/statements/for/index.md @@ -1,2 +1,2 @@ -# alolang关键字:for +# for * for循环:用于此循环的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/foreach/index.md b/docs/language/keyword/statements/foreach/index.md index 154b3bb9b781262950281fc4ab4cf5e9d6f0bcee..2d1eb17ef2c47e500f79b02bf1438c91ad46902e 100644 --- a/docs/language/keyword/statements/foreach/index.md +++ b/docs/language/keyword/statements/foreach/index.md @@ -1,2 +1,2 @@ -# alolang关键字:foreach +# foreach * foreach循环:用于带有范围限制的foreach循环的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/goto/index.md b/docs/language/keyword/statements/goto/index.md index d9d94ec964a4ffa181880b4b2e12184a807d562b..8966368228aeb25b020f55d4f48454f1d0d5a174 100644 --- a/docs/language/keyword/statements/goto/index.md +++ b/docs/language/keyword/statements/goto/index.md @@ -1,4 +1,4 @@ -# alolang关键字:goto +# goto * goto语句:用于goto语句的声明 例子: diff --git a/docs/language/keyword/statements/if/index.md b/docs/language/keyword/statements/if/index.md index 88fbb741f166ca12d6177267f6d6784bce72480d..1838d625a518b81a91b269b3398daa321fcaca79 100644 --- a/docs/language/keyword/statements/if/index.md +++ b/docs/language/keyword/statements/if/index.md @@ -1,2 +1,2 @@ -# alolang关键字:if +# if * if语句:用于if语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/return/index.md b/docs/language/keyword/statements/return/index.md index 07c8cc23446a1047f176f03236e33e999bd19adc..553b91f5efb01f490d97b8aacb73884e9fd9f976 100644 --- a/docs/language/keyword/statements/return/index.md +++ b/docs/language/keyword/statements/return/index.md @@ -1,2 +1,2 @@ -# alolang关键字:return +# return * return语句:用于语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/switch/index.md b/docs/language/keyword/statements/switch/index.md index 5c2cdb409e346fca9b2ac5699e05bb8dac35136b..e41b5dbdb3cff843c660cbd877ba88d336243f68 100644 --- a/docs/language/keyword/statements/switch/index.md +++ b/docs/language/keyword/statements/switch/index.md @@ -1,2 +1,2 @@ -# alolang关键字:switch +# switch * switch语句:用于该语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/try/index.md b/docs/language/keyword/statements/try/index.md index 20af4b166e9f6ecebbfb02c0a8d1bcef10963d0a..ec7df3bb092653535ec565578741cbef5b215390 100644 --- a/docs/language/keyword/statements/try/index.md +++ b/docs/language/keyword/statements/try/index.md @@ -1,2 +1,2 @@ -# alolang关键字:try +# try * 用于try-catch块 \ No newline at end of file diff --git a/docs/language/keyword/statements/while/index.md b/docs/language/keyword/statements/while/index.md index a65549e6ef1df3417a0a016cfc40cc62e2d521e8..a8c40e6d39c6bd65edf2c96ebb4844c7100893d8 100644 --- a/docs/language/keyword/statements/while/index.md +++ b/docs/language/keyword/statements/while/index.md @@ -1,3 +1,3 @@ -# alolang关键字:while +# while * while 循环:该循环的声明 * do-while 循环:该循环终止条件的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/anytype/index.md b/docs/language/keyword/type/anytype/index.md index 2488a8716ef27f439fb4f2cdd5ae04736630600a..34865ea15fe9c33f3ac116e5f2d02faaab6878d0 100644 --- a/docs/language/keyword/type/anytype/index.md +++ b/docs/language/keyword/type/anytype/index.md @@ -1,4 +1,4 @@ -# alolang关键字:anytype +# anytype * 用于函数的任意类型传入,传出 * 用于接收函数传出值的临时变量,占位符类型说明符,等效于auto diff --git a/docs/language/keyword/type/array/index.md b/docs/language/keyword/type/array/index.md index 10857c783090331dbc2f3af3977007312096c130..7dd54506dac96b02deced99eb696e6951f7a9c36 100644 --- a/docs/language/keyword/type/array/index.md +++ b/docs/language/keyword/type/array/index.md @@ -1,4 +1,4 @@ -# alolang关键字:array +# array 用于对数组的声明,使用方法为array(元素类型,长度)。 diff --git a/docs/language/keyword/type/auto/index.md b/docs/language/keyword/type/auto/index.md index c94c56e5eb2b4b2e94acdb6d69f309c4e56fad3d..c424048fa8eab0ac1db53034fea1a3bd04803d53 100644 --- a/docs/language/keyword/type/auto/index.md +++ b/docs/language/keyword/type/auto/index.md @@ -1,4 +1,4 @@ -# alolang关键词:auto +# auto * 占位符类型说明符 diff --git a/docs/language/keyword/type/bool/index.md b/docs/language/keyword/type/bool/index.md index 6a66e009f6f21c366fb355a7d5d6e3ee29ceaa68..ea6a73fcbe71b7a47f405eda4a6940708288bf02 100644 --- a/docs/language/keyword/type/bool/index.md +++ b/docs/language/keyword/type/bool/index.md @@ -1,3 +1,3 @@ -# alolang关键字:bool +# bool *用于对bool类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/char/index.md b/docs/language/keyword/type/char/index.md index eb657d28151aeb0baae6d80505af726ca18b9ee8..6a3cb487b547fa02d3c042901a49b92c37057e2d 100644 --- a/docs/language/keyword/type/char/index.md +++ b/docs/language/keyword/type/char/index.md @@ -1,4 +1,4 @@ -# alolang关键字:char +# char * 用于char类型的声明。 diff --git a/docs/language/keyword/type/double/index.md b/docs/language/keyword/type/double/index.md index 6767579ae5052aec2c9cf58f93118dc2d53ba9e7..74bfbd33c831a323f4f85ce61aa420436c605285 100644 --- a/docs/language/keyword/type/double/index.md +++ b/docs/language/keyword/type/double/index.md @@ -1,3 +1,3 @@ -# alolang关键字:double +# double * 用于对双精度浮点数double类型的声明。 diff --git a/docs/language/keyword/type/enum/index.md b/docs/language/keyword/type/enum/index.md index 254e144459021ee330bf131dfb565b83914ff49e..234fdc194ae4a3ba1d8c03b295677d6b1679c37c 100644 --- a/docs/language/keyword/type/enum/index.md +++ b/docs/language/keyword/type/enum/index.md @@ -1,3 +1,3 @@ -# alolang关键字:enum +# enum * 用于对枚举的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/float/index.md b/docs/language/keyword/type/float/index.md index 0d028a703fe3bd4b281e27fd3e30f6d5e3a0b0a3..f6632979d1c331ae0c12dc61fb521954e59bcba2 100644 --- a/docs/language/keyword/type/float/index.md +++ b/docs/language/keyword/type/float/index.md @@ -1,3 +1,3 @@ -# alolang关键字:float +# float * 用于对单精度浮点数类型float的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/index.md b/docs/language/keyword/type/index.md index 8dad771cb8305724c4d589f2dc95cbf428c5a34e..f50c7ad7395513080200ff2d8a990b1e7edd7bd2 100644 --- a/docs/language/keyword/type/index.md +++ b/docs/language/keyword/type/index.md @@ -5,6 +5,7 @@ 包含下面这几种 ``` +type anytype array auto diff --git a/docs/language/keyword/type/int/index.md b/docs/language/keyword/type/int/index.md index 034f8af3419caef14f487f649f3816da0adf5a72..31378ca0d14840005847a197ed01d4144c6fdf0f 100644 --- a/docs/language/keyword/type/int/index.md +++ b/docs/language/keyword/type/int/index.md @@ -1,3 +1,3 @@ -# alolang关键字:int +# int * 用于对64位整数int类型的声明。 \ No newline at end of file diff --git a/docs/language/keyword/type/int16_t/index.md b/docs/language/keyword/type/int16_t/index.md index 273d20bd42a30503fcfbadb8fda5fe2241e8665e..8dae7632bc5d2087ab9f606fa76e7847f9c2d129 100644 --- a/docs/language/keyword/type/int16_t/index.md +++ b/docs/language/keyword/type/int16_t/index.md @@ -1,3 +1,3 @@ -# alolang关键字:int16_t +# int16_t * 用于对16位整数类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/int32_t/index.md b/docs/language/keyword/type/int32_t/index.md index 5d7f43f8140b8979c60d70077d7d11ab2503b778..a076f99f96f639bdf14c3a0ef5db389fae5a0a37 100644 --- a/docs/language/keyword/type/int32_t/index.md +++ b/docs/language/keyword/type/int32_t/index.md @@ -1,3 +1,3 @@ -# alolang关键字:int32_t +# int32_t * 用于对32位整数类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/int8_t/index.md b/docs/language/keyword/type/int8_t/index.md index 9955c017f9619666803fd68ad6d93fa757d5c72c..074768b4525973bb8c41a4378f4fc67bc92ff93c 100644 --- a/docs/language/keyword/type/int8_t/index.md +++ b/docs/language/keyword/type/int8_t/index.md @@ -1,3 +1,3 @@ -# alolang关键字:int8_t +# int8_t * 等效于char \ No newline at end of file diff --git a/docs/language/keyword/type/long/index.md b/docs/language/keyword/type/long/index.md index 9d50199cf3dc8f60ab9c6d54ed4b14df9907accc..cf1fd0a8d45219f957381368ac0f5196bc6580ed 100644 --- a/docs/language/keyword/type/long/index.md +++ b/docs/language/keyword/type/long/index.md @@ -1,3 +1,3 @@ -# alolang关键字:long +# long * 用于对long类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/signed/index.md b/docs/language/keyword/type/signed/index.md index 3715571ec56836611a9072c968251f43b094228a..40650cb2e229d0803e326a9ecf954a51a05ef37c 100644 --- a/docs/language/keyword/type/signed/index.md +++ b/docs/language/keyword/type/signed/index.md @@ -1,4 +1,4 @@ -# alolang关键字:signed +# signed * 用于表明一个变量位有符号类型 diff --git a/docs/language/keyword/type/string/index.md b/docs/language/keyword/type/string/index.md index 935151aed68f8436f795fb9bc13e1a041e9cabe1..b1782b9f03a6245ea51410ff116cd97629fa34e8 100644 --- a/docs/language/keyword/type/string/index.md +++ b/docs/language/keyword/type/string/index.md @@ -1,3 +1,3 @@ -# alolang关键字:string +# string * 用于对字符串类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/struct/index.md b/docs/language/keyword/type/struct/index.md index 73bdaaed104cc5cd1b477d088ff8c64fb813a5fc..eecdc5e442966e9aae177b6542b79e114137e20c 100644 --- a/docs/language/keyword/type/struct/index.md +++ b/docs/language/keyword/type/struct/index.md @@ -1,3 +1,3 @@ -# alolang关键字:struct +# struct * 用于对结构体的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/type/index.md b/docs/language/keyword/type/type/index.md new file mode 100644 index 0000000000000000000000000000000000000000..b56b89bd099da6d7932ac926029f69433e09ab98 --- /dev/null +++ b/docs/language/keyword/type/type/index.md @@ -0,0 +1,17 @@ +# type + +* 类型别名标识符 + +用于声明一个类型别名。通常用在泛型支持上。 + +示例 + +``` +type foo = float; +type bar = float; +//foo和bar都是float的别名,foo和float类型的变量可以相互隐式类型转换,bar和float也可以 +//但是foo和bar不能。foo类型变量和bar类型变量只能通过强制类型转换或者经由float进行转换 + +type numeric = anytype; +//numeric是一个可用于匹配int,double以及complex的泛型 +``` \ No newline at end of file diff --git a/docs/language/keyword/type/unsigned/index.md b/docs/language/keyword/type/unsigned/index.md index e60152442ccb88d3f39d6aa5667eef344b0142aa..239051582ac9bfe66b29ba18562a44b26db42434 100644 --- a/docs/language/keyword/type/unsigned/index.md +++ b/docs/language/keyword/type/unsigned/index.md @@ -1,4 +1,4 @@ -# alolang关键词:unsigned +# unsigned * 用于表明某个变量为无符号类型 diff --git a/docs/language/keyword/type/void/index.md b/docs/language/keyword/type/void/index.md index 513e5bcdcb2427d1bf6f7bc6a67cfc6754a67af7..575d9db1b840f051b0d940ffd3d2645f0fbc31c9 100644 --- a/docs/language/keyword/type/void/index.md +++ b/docs/language/keyword/type/void/index.md @@ -1,4 +1,4 @@ -# alolang关键字:void +# void * void类型,但是不能用于定义一个void类型的对象 * 无形参函数的传入列表(可省略) diff --git a/docs/library/graph/index.md b/docs/library/graph/index.md index 63456fbd3d9a7636308945db9210f786e7bb06d4..6a33e51814b0a3680fa93b894bd078c1377266a0 100644 --- a/docs/library/graph/index.md +++ b/docs/library/graph/index.md @@ -1,4 +1,4 @@ -# alolang库:图 +# 图 * 数据结构类型:图 diff --git a/docs/library/math/index.md b/docs/library/math/index.md index 291ae7af0d693bec13bcedcd76c3f7a2fced509e..c0cc1c37f554fa5ce31a97f482d0ef1e100d4763 100644 --- a/docs/library/math/index.md +++ b/docs/library/math/index.md @@ -1,4 +1,4 @@ -# alolang库:math +# math #### **abs(x)** diff --git a/src/CompileError.hpp b/src/CompileError.hpp index 89acd1b415fae05f1f718755a21687e6f6be288e..5e3da65e917dfb3e3c73a7c3f18672f2469b5a4d 100644 --- a/src/CompileError.hpp +++ b/src/CompileError.hpp @@ -8,10 +8,27 @@ class CompileError : public std::exception { private: std::string error; + std::string message; + std::string file; + uint64_t line; public: - const char *what() const throw() { return error.c_str(); } - CompileError(const char *whatError) { error = whatError; } - CompileError(const std::string &whatError) { error = whatError; } + const char *what() const throw() { return message.c_str(); } + CompileError(const char *whatError, std::string whatFile = "", + uint64_t whatLine = 0) + { + error = whatError; + file = whatFile; + line = whatLine; + message = file + ":" + std::to_string(line) + ": " + error; + } + CompileError(const std::string &whatError, std::string whatFile = "", + uint64_t whatLine = 0) + { + error = whatError; + file = whatFile; + line = whatLine; + message = file + ":" + std::to_string(line) + ": " + error; + } }; #endif diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 2b25b39ba4b06aa31bef2febd7537dcf5aa60819..de656c64d4af5cc2e642ecd0e7930e8c6f7668e7 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -14,73 +14,187 @@ #include #include +#include "ast/ClassAST.h" #include "ast/ExprAST.h" #include "ast/ExternAST.h" #include "ast/FunctionAST.h" #include "ast/TypeAST.h" +#include "ast/VariableDefExprAST.h" #include "utils.h" +#include #include #include void initInnerType(CompileUnit *unit) { - unit->types.insert( - std::pair("int", new TypeAST(unit, "int"))); - unit->types.insert( - std::pair("bool", new TypeAST(unit, "bool"))); + unit->types.insert(std::pair( + "int", llvm::Type::getInt64Ty(*unit->context))); + unit->types.insert(std::pair( + "double", llvm::Type::getDoubleTy(*unit->context))); + unit->types.insert(std::pair( + "bool", llvm::Type::getInt1Ty(*unit->context))); } -void scanToken(CompileUnit *unit) +void initInnerOperations(CompileUnit *unit) { - Token token; - do { - int tokenid = unit->lexer->yylex(); - token.type = TokenType(tokenid); - token.lineno = unit->lexer->lineno(); - switch (token.type) { - tok_fun: - tok_extern: - tok_return: - tok_return_type: - tok_eof: - break; - default: - token.tokenValue = unit->lexer->YYText(); - } - // Deal with numbers - if (token.type == tok_number) { - int numTypeFlag = 10; //进制数 - if (token.tokenValue.substr(0, 2) == "0x" || - token.tokenValue.substr(0, 2) == "0X") - numTypeFlag = 16; - else if (token.tokenValue.substr(0, 2) == "0b" || - token.tokenValue.substr(0, 2) == "0B") - numTypeFlag = 2; - else if (token.tokenValue.substr(0, 1) == "0") - numTypeFlag = 8; - char tmp[256]; - sprintf(tmp, "%ld", - strtol(token.tokenValue.c_str(), NULL, numTypeFlag)); - token.tokenValue = tmp; - } + // binOP + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "+"}, std::pair( + nullptr, new TypeAST(unit, "int")))); + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "-"}, std::pair( + nullptr, new TypeAST(unit, "int")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "*"}, std::pair( + nullptr, new TypeAST(unit, "int")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "/"}, std::pair( + nullptr, new TypeAST(unit, "double")))); + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "%"}, std::pair( + nullptr, new TypeAST(unit, "int")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", ">"}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "<"}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", ">="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); - // Debug token dump - std::cout << token.dump() << std::endl; + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "<="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "!="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); - unit->tokenList.push_back(token); - } while (token.type != tok_eof); + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "=="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + // double + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "+"}, std::pair( + nullptr, new TypeAST(unit, "double")))); + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "-"}, std::pair( + nullptr, new TypeAST(unit, "double")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "*"}, std::pair( + nullptr, new TypeAST(unit, "double")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "/"}, std::pair( + nullptr, new TypeAST(unit, "double")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", ">"}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "<"}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", ">="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "<="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "!="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"double", "double", "=="}, std::pair( + nullptr, new TypeAST(unit, "bool")))); +} +void scanToken(CompileUnit *unit) +{ + for (Tline line : unit->srclines) { + std::istringstream is(line.second); + FlexLexer * lexer = new yyFlexLexer(is, std::cerr); + Token token; + + while (1) { + int tokenid = lexer->yylex(); + token.type = TokenType(tokenid); + token.file = line.first.first; + token.lineno = line.first.second; + token.tokenValue = lexer->YYText(); + // Deal with numbers + if (token.type == tok_number) { + int numTypeFlag = 10; //进制数 + if (token.tokenValue.substr(0, 2) == "0x" || + token.tokenValue.substr(0, 2) == "0X") + numTypeFlag = 16; + else if (token.tokenValue.substr(0, 2) == "0b" || + token.tokenValue.substr(0, 2) == "0B") + numTypeFlag = 2; + else if (token.tokenValue.substr(0, 1) == "0") + numTypeFlag = 8; + char tmp[256]; + if (token.tokenValue.find(".") != std::string::npos) + sprintf(tmp, "%f", strtod(token.tokenValue.c_str(), NULL)); + else + sprintf( + tmp, "%ld", + strtol(token.tokenValue.c_str(), NULL, numTypeFlag)); + token.tokenValue = tmp; + } else if (token.type == tok_str) { + std::string str = token.tokenValue; + token.tokenValue = str.substr(1, str.length() - 2); + } + + // Debug token dump + // std::cout << token.dump() << std::endl; + if (token.type == tok_eof) + break; + unit->tokenList.push_back(token); + } + } + Token TEOF; + TEOF.type = tok_eof; + unit->tokenList.push_back(TEOF); unit->icurTok = unit->tokenList.begin(); } -CompileUnit::CompileUnit(std::string name, std::string source) +CompileUnit::CompileUnit(std::string Iname, std::vector lines) { - this->name = name; - this->source = source; - this->sis = std::istringstream(source); - this->lexer = new yyFlexLexer(sis, std::cerr); - context = new llvm::LLVMContext(); - module = new llvm::Module("test.ll", *context); + name = Iname; + srclines = lines; + context = new llvm::LLVMContext(); + module = new llvm::Module(name, *context); } CompileUnit::~CompileUnit() {} @@ -97,16 +211,20 @@ void CompileUnit::compile() { std::cout << "Start compiling:" << name << std::endl; initInnerType(this); + initInnerOperations(this); scanToken(this); - do { + while (icurTok->type != tok_eof) { switch (icurTok->type) { case tok_fun: { - FunctionAST * func_ast = FunctionAST::ParseFunction(this); - llvm::Function *func = func_ast->Codegen(); + FunctionAST *func_ast = FunctionAST::ParseFunction(this); + functions.insert(std::pair( + func_ast->getDemangledName(), func_ast)); + // llvm::Function *func = func_ast->Codegen(); /*llvm::Type* type=llvm::FunctionType::get(llvm::Type::getVoidTy(*context), false); - module->getOrInsertGlobal(func_ast->proto->name, func->getType()); + module->getOrInsertGlobal(func_ast->proto->name, + func->getType()); llvm::GlobalVariable *gVar=module->getNamedGlobal(func_ast->proto->name); @@ -115,23 +233,54 @@ void CompileUnit::compile() break; } case tok_extern: { + ExternAST *externast = ExternAST::ParseExtern(this); + externs.insert(std::pair( + externast->getDemangledName(), externast)); + break; + } + case tok_identifier: { + //全局变量 + VariableDefExprAST *var = + VariableDefExprAST::ParseVar(this, nullptr); Token token = next_tok(); - if (token.type == tok_eof) { - CompileError e("Unexpected EOF in funtion body, line " + - std::to_string(token.lineno)); - throw e; - } - if (token.type == tok_fun) { - ExternAST::ParseExtern(this)->Codegen(); - } - // todo:对导出非函数符号的处理 + globalVariables.insert( + std::pair(var->idName, var)); break; } - default: - - std::cerr << "unexpected token:" << icurTok->dump() << std::endl; + case tok_key_class: { + ClassAST *classAST = ClassAST::ParseClass(this); + classes.insert(std::pair( + classAST->className, classAST)); + classesO.push_back(classAST); + break; } - } while (next_tok().type != tok_eof); + default: { + CompileError e("unexpected token:" + icurTok->dump()); + throw e; + } + } + } + std::cout << "Start codegen:" << name << std::endl; + /*for (ClassAST *classAST : classesO) { + llvm::Type *classType = classAST->Codegen(); + }*/ + + std::map::iterator gVar_iter; + for (gVar_iter = globalVariables.begin(); + gVar_iter != globalVariables.end(); gVar_iter++) { + gVar_iter->second->Codegen(nullptr); + } + std::map::iterator extern_iter; + for (extern_iter = externs.begin(); extern_iter != externs.end(); + extern_iter++) { + extern_iter->second->Codegen(); + } + std::map::iterator function_iter; + for (function_iter = functions.begin(); function_iter != functions.end(); + function_iter++) { + function_iter->second->Codegen(); + } + build(); } diff --git a/src/CompileUnit.h b/src/CompileUnit.h index af1c1dc3e9c655cd4448137b15aca44b5298685c..7c620ab9ca54e2c3e86c21de5072479bb94cde46 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -9,6 +9,7 @@ #define COMPILER_COMPILEUNIT_H_ #include "Token.h" +#include "preprocessor.h" #include #include #include @@ -16,24 +17,36 @@ #include class TypeAST; +class FunctionAST; +class ExternAST; +class VariableDefExprAST; +class ClassAST; class CompileUnit { public: - CompileUnit(std::string name, std::string source); + CompileUnit(std::string name, std::vector lines); virtual ~CompileUnit(); void compile(); Token next_tok(); void build(); - FlexLexer * lexer; - std::string name; - std::string source; - std::istringstream sis; - llvm::LLVMContext * context; - llvm::Module * module; - std::vector tokenList; - std::vector::iterator icurTok; - std::map types; + std::string name; + std::vector srclines; + llvm::LLVMContext * context; + llvm::Module * module; + std::vector tokenList; + std::vector::iterator icurTok; + std::map classes; + std::vector classesO; + std::map globalVariables; + std::vector globalVariablesO; + std::map functions; + std::map externs; + std::map, std::pair> + binOperators; // LHS type,RHS type,binOP + std::map types; // Codgen用 + std::map> + globalVariablesValue; // Codgen用 }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 4193a27ecca7d6eca141b1de8675ad953a041359..325ae091924fc5f4fc560a65acadf56cb8eb82d3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,12 @@ AUTOMAKE_OPTIONS = foreign subdir-objects bin_PROGRAMS = aloc aloc_SOURCES = aloc.cpp CompileUnit.cpp preprocessor.cpp Token.cpp utils.cpp\ - ast/AssignmentAST.cpp ast/BaseAST.cpp ast/BinaryExprAST.cpp ast/BoolExprAST.cpp ast/CallExprAST.cpp ast/CodeBlockAST.cpp\ - ast/ExprAST.cpp ast/ExternAST.cpp ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.cpp ast/PrototypeAST.cpp\ - ast/TypeAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp yacc_stuff/tokenizer.lpp + ast/BaseAST.cpp ast/BinaryExprAST.cpp ast/BoolExprAST.cpp\ + ast/CallExprAST.cpp ast/ClassAST.cpp ast/CodeBlockAST.cpp ast/DoubleExprAST.cpp ast/EmptyExprAST.cpp\ + ast/ExprAST.cpp ast/ExternAST.cpp ast/FunctionAST.cpp ast/IntExprAST.cpp\ + ast/IfExprAST.cpp ast/MemberExprAST.cpp ast/PrototypeAST.cpp\ + ast/ReturnExprAST.cpp ast/TypeAST.cpp ast/VariableDefExprAST.cpp ast/VariableExprAST.cpp\ + ast/WhileExprAST.cpp ast/UnaryExprAST.cpp yacc_stuff/tokenizer.lpp AM_LFLAGS = -o lex.yy.c @@ -13,4 +16,5 @@ libLLVM := $(shell llvm-config --libs) includeLLVM := $(shell llvm-config --includedir) aloc_CPPFLAGS = $(cxxflagsLLVM) -I$(includeLLVM) -I$(srcdir) -fexceptions -aloc_LDFLAGS = $(ldflagsLLVM) $(libLLVM) -lboost_program_options +aloc_LDFLAGS = $(ldflagsLLVM) #$(libLLVM) -lboost_program_options +aloc_LDADD = -lLLVM-11 -lboost_program_options \ No newline at end of file diff --git a/src/Token.cpp b/src/Token.cpp index 166410f2213c92b23317e06d369e70030fbcc0f4..bc963b83ef748cbcf660bce28cd805203de1c544 100644 --- a/src/Token.cpp +++ b/src/Token.cpp @@ -51,9 +51,6 @@ std::string Token::dump() case tok_return: typeStr = "tok_return"; break; - case tok_return_type: - typeStr = "tok_return_type"; - break; case tok_syntax: typeStr = "tok_syntax"; break; @@ -96,10 +93,14 @@ std::string Token::dump() case tok_key_switch: typeStr = "tok_key_switch"; break; + case tok_key_class: + typeStr = "tok_key_class"; + break; default: typeStr = "not defined"; } - ss << std::left << "Line " << std::setw(6) << lineno - << " type:" << std::setw(16) << typeStr << " data:" << tokenValue; + ss << std::right << std::setw(25) << file << ":" << std::left + << std::setw(6) << lineno << " type:" << std::setw(16) << typeStr + << " data:" << tokenValue; return ss.str(); } diff --git a/src/Token.h b/src/Token.h index 5eb95465b177c8d2d4ea526a6b96634a4a05f084..7943dd79b996258597eee1a554e3260a5f6b9884 100644 --- a/src/Token.h +++ b/src/Token.h @@ -19,7 +19,6 @@ enum TokenType { tok_number, tok_type, tok_return, - tok_return_type, tok_syntax, tok_str, tok_key_op, @@ -33,7 +32,8 @@ enum TokenType { tok_key_goto, tok_key_if, tok_key_while, - tok_key_switch + tok_key_switch, + tok_key_class }; class Token @@ -45,6 +45,7 @@ class Token TokenType type; std::string tokenValue; uint64_t lineno; + std::string file; }; #endif /* COMPILER_TOKEN_H_ */ diff --git a/src/aloc.cpp b/src/aloc.cpp index 1cacf19887b5afe66da3684d99db29e21c19a7bd..b8ee59e8a956abf2e0e2dd8b3ecab8a371db74c1 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -101,12 +101,12 @@ int main(int argc, char *argv[]) } std::string buff; //源码 std::getline(fin, buff, char(EOF)); - std::string preProcessed; + std::vector preProcessed; fin.close(); // std::string header = "%import types\n"; // buff = header + buff; try { - preProcessed = preProcess(buff, 0); + preProcessed = preProcess(buff, 0, input_file_name); // cout << preProcessed; // todo:这行代码写的极不规范,尽快修改 CompileUnit(input_file_name, preProcessed).compile(); diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp deleted file mode 100644 index bb278eee57679793c610fa70521c2a8488a1084e..0000000000000000000000000000000000000000 --- a/src/ast/AssignmentAST.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * AssignmentAST.cpp - * - * Created on: Feb 17, 2021 - * Author: zbc - */ - -#include "AssignmentAST.h" -#include "../CompileError.hpp" -#include "CodeBlockAST.h" -#include "VariableExprAST.h" - -AssignmentAST::AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, - ExprAST *RHS) - : ExprAST(unit) -{ - this->LHS = LHS; - this->RHS = RHS; -} - -AssignmentAST::~AssignmentAST() -{ - // TODO Auto-generated destructor stub -} - -AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, - CodeBlockAST * codeblock, - const std::string &LHS) -{ - - unit->next_tok(); - CodeBlockAST *curCodeBlock = codeblock; - while (curCodeBlock != nullptr) { - auto varAST = curCodeBlock->namedValues.find(LHS); - if (varAST == curCodeBlock->namedValues.end()) { - curCodeBlock = curCodeBlock->parent; - } else { - return new AssignmentAST( - unit, varAST->second, - ExprAST::ParseExpression(unit, codeblock, false)); - } - } - CompileError e("can't find variable:" + LHS); - throw e; -} - -llvm::Value *AssignmentAST::Codegen(llvm::IRBuilder<> *builder) -{ - llvm::Value *value = RHS->Codegen(builder); - builder->CreateStore(value, LHS->alloca); // todo:对函数参数赋值 - return value; -} diff --git a/src/ast/AssignmentAST.h b/src/ast/AssignmentAST.h deleted file mode 100644 index b4aac759ce9b352090d3e9dc99667fcd892021b9..0000000000000000000000000000000000000000 --- a/src/ast/AssignmentAST.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * AssignmentAST.h - * - * Created on: Feb 17, 2021 - * Author: zbc - */ - -#ifndef SRC_AST_ASSIGNMENTAST_H_ -#define SRC_AST_ASSIGNMENTAST_H_ - -#include "ExprAST.h" - -class VariableExprAST; -class AssignmentAST : public ExprAST -{ - public: - AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, ExprAST *RHS); - virtual ~AssignmentAST(); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - static AssignmentAST *ParseAssignment(CompileUnit * unit, - CodeBlockAST * codeblock, - const std::string &LHS); - VariableExprAST * LHS; //左侧变量 - ExprAST * RHS; -}; - -#endif /* SRC_AST_ASSIGNMENTAST_H_ */ diff --git a/src/ast/BaseAST.h b/src/ast/BaseAST.h index a4d27249a8007e96819d0d0e4270d1ad41f9dd79..33d4f13f77b92493e0619c89eea9f427c56acd16 100644 --- a/src/ast/BaseAST.h +++ b/src/ast/BaseAST.h @@ -3,11 +3,11 @@ #include "./../CompileUnit.h" #include "./../Token.h" +#include #include #include #include #include -#include class BaseAST { diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index b68634594180ae16aabecb0227db4fd0baaa44e1..4f5dd4ac9e0f6175a41f261f7f164f1990c5342d 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -7,6 +7,11 @@ #include "BinaryExprAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" +#include "MemberExprAST.h" +#include "TypeAST.h" +#include "UnaryExprAST.h" +#include "VariableExprAST.h" BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, ExprAST *RHS) @@ -15,7 +20,6 @@ BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, this->binOP = binOP; this->LHS = LHS; this->RHS = RHS; - this->type = LHS->type; } BinaryExprAST::~BinaryExprAST() @@ -23,34 +27,182 @@ BinaryExprAST::~BinaryExprAST() // TODO Auto-generated destructor stub } -llvm::Value *BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) +llvm::Value * +BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, + llvm::IRBuilder<> *builder) { - llvm::Value *L = LHS->Codegen(builder); - llvm::Value *R = RHS->Codegen(builder); - if (L == nullptr || R == 0) - return 0; - if (binOP == "+") { - return builder->CreateAdd(L, R); - } else if (binOP == "-") { - return builder->CreateSub(L, R); - } else if (binOP == "*") { - return builder->CreateMul(L, R); - } else if (binOP == "/") { - return builder->CreateFDiv(L, R); - } else if (binOP == "==") { - return builder->CreateICmpEQ(L, R); - } else if (binOP == "!=") { - return builder->CreateICmpNE(L, R); - } else if (binOP == ">") { - return builder->CreateICmpSGT(L, R); - } else if (binOP == "<") { - return builder->CreateICmpSLT(L, R); - } else if (binOP == ">=") { - return builder->CreateICmpSGE(L, R); - } else if (binOP == "<=") { - return builder->CreateICmpSLE(L, R); + if (LHS->type[0]->name == "int" && RHS->type[0]->name == "int") { + if (binOP == "+") { + return builder->CreateAdd(L, R); + } else if (binOP == "-") { + return builder->CreateSub(L, R); + } else if (binOP == "*") { + return builder->CreateMul(L, R); + } else if (binOP == "/") { + TypeAST * doubleType = new TypeAST(unit, "double"); + llvm::Value *lv = builder->CreateSIToFP(L, doubleType->Codegen()); + llvm::Value *rv = builder->CreateSIToFP(R, doubleType->Codegen()); + return (builder->CreateFDiv(lv, rv)); + } else if (binOP == "%") { + return builder->CreateSRem(L, R); + } else if (binOP == "==") { + return builder->CreateICmpEQ(L, R); + } else if (binOP == "!=") { + return builder->CreateICmpNE(L, R); + } else if (binOP == ">") { + return builder->CreateICmpSGT(L, R); + } else if (binOP == "<") { + return builder->CreateICmpSLT(L, R); + } else if (binOP == ">=") { + return builder->CreateICmpSGE(L, R); + } else if (binOP == "<=") { + return builder->CreateICmpSLE(L, R); + } + } else if (LHS->type[0]->name == "double" && + RHS->type[0]->name == "double") { + if (binOP == "+") { + return builder->CreateFAdd(L, R); + } else if (binOP == "-") { + return builder->CreateFSub(L, R); + } else if (binOP == "*") { + return builder->CreateFMul(L, R); + } else if (binOP == "/") { + return builder->CreateFDiv(L, R); + } else if (binOP == "==") { + return builder->CreateFCmpOEQ(L, R); + } else if (binOP == "!=") { + return builder->CreateFCmpONE(L, R); + } else if (binOP == ">") { + return builder->CreateFCmpOGT(L, R); + } else if (binOP == "<") { + return builder->CreateFCmpOLT(L, R); + } else if (binOP == ">=") { + return builder->CreateFCmpOGE(L, R); + } else if (binOP == "<=") { + return builder->CreateFCmpOLE(L, R); + } + } + return nullptr; +} +std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector result; + + if (binOP == "=") { + std::vector RHSV = RHS->CodegenChain(builder); + std::vector LHS; + ExprAST * curExpr = this->LHS; + while (curExpr != nullptr) { + LHS.push_back(curExpr); + curExpr = curExpr->subExpr; + } + if (RHSV.size() != LHS.size()) { + CompileError e("the length of expression isn't equal."); + throw e; + } + for (unsigned int i = 0; i < LHS.size(); i++) { + ExprAST * curAST = LHS[i]; + std::vector chain; + llvm::Value * pointer; + bool pointerFlag; + if (UnaryExprAST *v = dynamic_cast(curAST)) { + if (v->op != "*") { + CompileError e("Operator " + v->op + + " can not be used as assignment"); + throw e; + } else { + pointer = v->operand->Codegen(builder)[0]; + } + } else { + while (true) { + chain.push_back(curAST); + if (MemberExprAST *v = + dynamic_cast(curAST)) { + if (v->isPointer) { + pointerFlag = true; + chain.push_back(v->LHS); + break; + } + curAST = v->LHS; + } else if (VariableExprAST *v = + dynamic_cast(curAST)) { + pointerFlag = false; + break; + } else { + CompileError e("Unknown AST."); + throw e; + } + } + std::string curType, startType; + if (pointerFlag) { + ExprAST *start = chain[chain.size() - 1]; + pointer = start->Codegen(builder)[0]; + curType = start->type[0]->pointee->baseClass; + startType = start->type[0]->pointee->name; + } else { + VariableExprAST *start = dynamic_cast( + chain[chain.size() - 1]); + pointer = start->getAlloca(); + curType = start->type[0]->baseClass; + startType = start->type[0]->name; + } + std::vector idx; + for (int i = chain.size() - 2; i >= 0; i--) { + MemberExprAST *v = dynamic_cast(chain[i]); + std::string member = v->member; + ClassAST * baseClass = unit->classes[curType]; + auto memberAST = baseClass->members.find(member); + if (memberAST == baseClass->members.end()) { + CompileError e("Member" + member + " not found."); + throw e; + } + unsigned int index = std::distance( + std::begin(baseClass->members), memberAST); + idx.push_back(index); + curType = baseClass->members[member]->variableType->name; + } + std::vector idxl; + llvm::IntegerType * itype = + llvm::IntegerType::get(*unit->context, 32); + + idxl.push_back(llvm::ConstantInt::get(itype, 0, true)); + for (unsigned int pid : idx) { + idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); + } + if (idx.size() != 0) { + auto typeAST = unit->types.find(startType); + + pointer = + builder->CreateGEP(typeAST->second, pointer, idxl); + } + } + + builder->CreateStore(RHSV[i], pointer); + } } else { - CompileError e("Unknown operator:" + binOP); - throw e; + std::vector L = LHS->CodegenChain(builder); + std::vector R = RHS->CodegenChain(builder); + if (L.size() != 1 || R.size() != 1) { + CompileError e("Bin Expr length != 1"); + throw e; + } + std::string LHStype = LHS->type[0]->name; + std::string RHStype = RHS->type[0]->name; + auto operate = unit->binOperators.find({LHStype, RHStype, binOP}); + if (operate == unit->binOperators.end()) { + CompileError e("Unknown operator " + binOP + "with type " + + LHStype + " and " + RHStype); + throw e; + } + this->type.push_back(operate->second.second); + if (operate->second.first == nullptr) { + //内置运算符 + result.push_back(processInnerBinaryOperator(L[0], R[0], builder)); + } else { + //用户定义运算符 + CompileError e("User-def operator not implemented"); + throw e; + } } + return result; } diff --git a/src/ast/BinaryExprAST.h b/src/ast/BinaryExprAST.h index 7f6113d8f3ab35c06d38a3a612b9fa099616690a..2641b760ecab4c30ddc84871eacb9ab27149f4f3 100644 --- a/src/ast/BinaryExprAST.h +++ b/src/ast/BinaryExprAST.h @@ -16,11 +16,15 @@ class BinaryExprAST : public ExprAST BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, ExprAST *RHS); virtual ~BinaryExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); std::string binOP; ExprAST * LHS; ExprAST * RHS; + + private: + llvm::Value *processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, + llvm::IRBuilder<> *builder); }; #endif /* COMPILER_AST_BINARYEXPRAST_H_ */ diff --git a/src/ast/BoolExprAST.cpp b/src/ast/BoolExprAST.cpp index e0037e51844ec785f70fad240e0fbabd779c4e08..5b9f7d4956276db7b1f8ba1e322db85dcf7afc77 100644 --- a/src/ast/BoolExprAST.cpp +++ b/src/ast/BoolExprAST.cpp @@ -6,11 +6,12 @@ */ #include "BoolExprAST.h" +#include "TypeAST.h" BoolExprAST::BoolExprAST(CompileUnit *unit, bool val) : ExprAST(unit) { this->val = val; - type = "bool"; + type.push_back(new TypeAST(unit, "bool")); } BoolExprAST::~BoolExprAST() @@ -18,9 +19,11 @@ BoolExprAST::~BoolExprAST() // TODO Auto-generated destructor stub } -llvm::Value *BoolExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector BoolExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 1); - llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); - return res; + std::vector result; + llvm::IntegerType * type = llvm::IntegerType::get(*unit->context, 1); + llvm::ConstantInt * res = llvm::ConstantInt::get(type, val, true); + result.push_back(res); + return result; } diff --git a/src/ast/BoolExprAST.h b/src/ast/BoolExprAST.h index 09ee1a22d79b22df5b43cf1402ac046015232aeb..ada577d32b0cebf63c799b231e371855b703e91a 100644 --- a/src/ast/BoolExprAST.h +++ b/src/ast/BoolExprAST.h @@ -15,8 +15,8 @@ class BoolExprAST : public ExprAST public: BoolExprAST(CompileUnit *unit, bool val); virtual ~BoolExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); - bool val; + std::vector Codegen(llvm::IRBuilder<> *builder); + bool val; }; #endif /* SRC_AST_BOOLEXPRAST_H_ */ diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index c82dc4da3d433749b6be9e8e3b5c26d40b52f4e0..5fe2ced3ddb9df2cec1bd2a0caaeb1c9a5fd425f 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -7,24 +7,19 @@ #include "CallExprAST.h" #include "../CompileError.hpp" +#include "ExternAST.h" +#include "FunctionAST.h" #include #include "../utils.h" CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, - std::vector &args) + ExprAST *args) : ExprAST(unit) { - std::vector argStr; - for (ExprAST *ast : args) { - argStr.push_back(ast->type); - } - if (callee != "main") { - this->callee = demangle(callee, argStr); - } - - this->args = args; + this->callee = callee; + this->args = args; std::cout << std::left << std::setw(35) << "Function call found:" << this->callee << std::endl; } @@ -34,24 +29,58 @@ CallExprAST::~CallExprAST() // TODO Auto-generated destructor stub } -llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Function *CalleeF = unit->module->getFunction(callee); - if (CalleeF == 0) { - CompileError e("Function " + callee + " not found"); - throw e; + std::vector result; + std::vector argsV = args->CodegenChain(builder); + + std::vector argStr; + for (TypeAST *ast : args->type) { + argStr.push_back(ast); + } + std::string dname = demangle(callee, argStr); + if (callee == "main") { + dname = "main"; } - std::vector argsV; + PrototypeAST *proto = nullptr; - // If argument mismatch error. - if (CalleeF->arg_size() != args.size()) { - CompileError e("Incorrect arguments passed"); + auto externAST = unit->externs.find(dname); + if (externAST != unit->externs.end()) { + proto = externAST->second->proto; + } + + auto functionAST = unit->functions.find(dname); + if (functionAST != unit->functions.end()) { + proto = functionAST->second->proto; + } + + if (proto == nullptr) { + CompileError e("Function " + dname + " not found."); throw e; } + type = proto->returnTypes; - for (unsigned i = 0, e = args.size(); i != e; ++i) { - argsV.push_back(args[i]->Codegen(builder)); + llvm::Function *CalleeF = unit->module->getFunction(dname); + if (CalleeF == 0) { + CompileError e("Function " + dname + " not found in LLVM IR"); + throw e; } + llvm::Value *retD = builder->CreateCall(CalleeF, argsV); + if (proto->returnDirectly) { + result.push_back(retD); + } else { + for (unsigned i = 0; i < type.size(); i++) { + /*llvm::IntegerType *type = + llvm::IntegerType::get(*unit->context, 32); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, i, true);*/ + llvm::Value *member = builder->CreateExtractValue(retD, {i}); - return builder->CreateCall(CalleeF, argsV); + /*llvm::Value *member_ptr = builder->CreateGEP( + CalleeF->getReturnType(), retD, + {llvm::ConstantInt::get(type, 0, true), res});*/ + result.push_back(member); + // builder->CreateLoad(member_ptr); + } + } + return result; } diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index 3cfdd5b140923a07681e173d8d42d55c1438097e..2c5531bfc5656a22b84765499ddac8d1520bbc14 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -13,13 +13,12 @@ class CallExprAST : public ExprAST { public: - CallExprAST(CompileUnit *unit, const std::string &callee, - std::vector &args); + CallExprAST(CompileUnit *unit, const std::string &callee, ExprAST *args); virtual ~CallExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); - std::string callee; - std::vector args; + std::string callee; + ExprAST * args; }; #endif /* COMPILER_AST_CALLEXPRAST_H_ */ diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9f935f5eda454831705e75ea2d2c784697b89da --- /dev/null +++ b/src/ast/ClassAST.cpp @@ -0,0 +1,125 @@ +/* + * ClassAST.cpp + * + * Created on: Feb 22, 2021 + * Author: zbc + */ + +#include "ClassAST.h" +#include "../CompileError.hpp" +#include "TypeAST.h" + +ClassAST::ClassAST(CompileUnit *unit, const std::string &className, + std::map members, + std::vector genericTypes) + : BaseAST(unit) +{ + this->className = className; + this->members = members; + this->genericTypes = genericTypes; +} + +ClassAST::~ClassAST() +{ + // TODO Auto-generated destructor stub +} + +ClassAST *ClassAST::ParseClass(CompileUnit *unit) +{ + Token token = unit->next_tok(); + if (token.type != tok_identifier) { + CompileError e("Expected identifier", token.file, token.lineno); + throw e; + } + std::string className = token.tokenValue; + std::vector genericTypes; + std::cout << std::left << std::setw(35) + << "Class definition found:" << className << std::endl; + token = unit->next_tok(); + if (token.type == tok_syntax && token.tokenValue == "<") { + token = unit->next_tok(); + while (!(token.type == tok_syntax && token.tokenValue == ">")) { + if (token.type == tok_identifier) { + genericTypes.push_back(token.tokenValue); + } + unit->next_tok(); + token = *unit->icurTok; + } + token = unit->next_tok(); + } + if (token.type != tok_syntax || token.tokenValue != "{") { + CompileError e("Expected {", token.file, token.lineno); + throw e; + } + std::map members; + while (true) { + token = unit->next_tok(); + //解析成员方法,成员变量 + if (token.type == tok_syntax && token.tokenValue == "}") { + break; + } + VariableDefExprAST *memberDef = + VariableDefExprAST::ParseVar(unit, nullptr); + members.insert(std::pair( + memberDef->idName, memberDef)); + } + token = unit->next_tok(); + ClassAST *classAST = new ClassAST(unit, className, members, genericTypes); + return classAST; +} + +TypeAST *ClassAST::getRealType(TypeAST * type, + std::vector igenericTypes) +{ + if (type->pointee != nullptr) { + type->pointee = getRealType(type->pointee, igenericTypes); + } + for (unsigned int i = 0; i < type->genericTypes.size(); i++) { + type->genericTypes[i] = + getRealType(type->genericTypes[i], igenericTypes); + } + auto it = find(genericTypes.begin(), genericTypes.end(), type->name); + + type->initName(); + + if (it != genericTypes.end()) { + //泛型 + int index = it - genericTypes.begin(); + return igenericTypes[index]; + } else { + return type; + } +} + +llvm::Type *ClassAST::Codegen(std::vector igenericTypes) +{ + if (igenericTypes.size() != genericTypes.size()) { + CompileError e("generic isn't equal"); + throw e; + } + std::string name = className; + if (igenericTypes.size() != 0) { + name += "<"; + for (unsigned int i = 0; i < igenericTypes.size() - 1; i++) { + name += igenericTypes[i]->name + ","; + } + name += igenericTypes[igenericTypes.size() - 1]->name + ">"; + } + + llvm::StructType *llvm_S = + llvm::StructType::create(*unit->context, className); + unit->types.insert(std::pair(name, llvm_S)); + std::vector sMembers; + std::map::iterator member_iter; + for (member_iter = members.begin(); member_iter != members.end(); + member_iter++) { + + VariableDefExprAST *memberVariable = member_iter->second; + TypeAST * mType = + getRealType(memberVariable->variableType, igenericTypes); + sMembers.push_back(mType->Codegen()); + } + llvm_S->setBody(sMembers); + + return llvm_S; +} diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h new file mode 100644 index 0000000000000000000000000000000000000000..4ef01e14da2f3688bf21879c87309f32f14ebb71 --- /dev/null +++ b/src/ast/ClassAST.h @@ -0,0 +1,29 @@ +/* + * ClassAST.h + * + * Created on: Feb 22, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_CLASSAST_H_ +#define SRC_AST_CLASSAST_H_ + +#include "BaseAST.h" +#include "VariableDefExprAST.h" + +class ClassAST : public BaseAST +{ + public: + ClassAST(CompileUnit *unit, const std::string &className, + std::map members, + std::vector genericTypes); + virtual ~ClassAST(); + llvm::Type *Codegen(std::vector genericTypes); + TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); + static ClassAST * ParseClass(CompileUnit *unit); + std::map members; + std::vector genericTypes; + std::string className; +}; + +#endif /* SRC_AST_CLASSAST_H_ */ diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 44374a4f6f999658629faf32fa5222aeced26b80..7c599dbe0b1d99855a96349172c01e66b2e6664b 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -7,6 +7,7 @@ #include "CodeBlockAST.h" #include "../CompileError.hpp" +#include "VariableDefExprAST.h" #include CodeBlockAST::CodeBlockAST(CompileUnit *unit, std::vector body, @@ -25,25 +26,43 @@ CodeBlockAST::~CodeBlockAST() // TODO Auto-generated destructor stub } -CodeBlockAST *CodeBlockAST::ParseCodeBlock( - CompileUnit *unit, std::string name, CodeBlockAST *parent, - std::map namedValues) +CodeBlockAST * +CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, + CodeBlockAST * parent, + const std::vector args) { + Token token = *unit->icurTok; CodeBlockAST *codeblock = new CodeBlockAST(unit, std::vector(), name, parent); - codeblock->namedValues = namedValues; - std::vector &body = codeblock->body; - while (true) { - Token inBlockToken = *(unit->icurTok + 1); - if (inBlockToken.type == tok_eof) { - CompileError e("Unexpexted EOF in function body"); - throw e; + if (token.type == tok_syntax && token.tokenValue == "{") { + std::vector &body = codeblock->body; + for (VariableDefExprAST *argDef : args) { + argDef->codeblock = codeblock; + body.push_back(argDef); } - if (inBlockToken.type == tok_syntax && inBlockToken.tokenValue == "}") { - unit->next_tok(); - break; + //解析块内语句 + Token inBlockToken = unit->next_tok(); + while (true) { + inBlockToken = *(unit->icurTok); + if (inBlockToken.type == tok_eof) { + CompileError e("Unexpexted EOF in function body"); + throw e; + } + if (inBlockToken.type == tok_syntax && + inBlockToken.tokenValue == "}") { + unit->next_tok(); + break; + } + body.push_back(ExprAST::ParseExpression(unit, codeblock, true)); } + } else { + std::vector &body = codeblock->body; + for (VariableDefExprAST *argDef : args) { + argDef->codeblock = codeblock; + body.push_back(argDef); + } + //解析块内语句 body.push_back(ExprAST::ParseExpression(unit, codeblock, true)); } return codeblock; @@ -57,11 +76,19 @@ llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) builder->SetInsertPoint(bb); for (ExprAST *expr : body) { - expr->Codegen(builder); + expr->CodegenChain(builder); } - // builder->CreateRetVoid(); // todo:待处理 + // builder->CreateRetVoid(); // todo:待处理,main特判 + // std::cout << name << std::string(function->getName()) << std::endl; if (parent == nullptr) { - builder->CreateRetVoid(); + if (std::string(function->getName()) == "main") { + + llvm::IntegerType *type = + llvm::IntegerType::get(*unit->context, 32); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, 0, true); + + builder->CreateRet(res); + } } return bb; diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 0d976ef77d6ea8dbd5661fd12dd262903988194d..6ec37d027e2aa5d9494387796838238e341ae12c 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -13,7 +13,7 @@ #include "llvm/IR/Instructions.h" #include -class VariableExprAST; +class VariableDefExprAST; class CodeBlockAST : public BaseAST { public: @@ -22,17 +22,18 @@ class CodeBlockAST : public BaseAST virtual ~CodeBlockAST(); static CodeBlockAST * ParseCodeBlock(CompileUnit *unit, std::string name, - CodeBlockAST * parent = nullptr, - std::map namedValues = - std::map()); + CodeBlockAST * parent = nullptr, + const std::vector args = + std::vector()); llvm::BasicBlock *Codegen(llvm::Function *function); - llvm::IRBuilder<> * builder; - std::vector body; - std::map namedValues; - std::string name; - CodeBlockAST * parent; - llvm::BasicBlock * endBB; + llvm::IRBuilder<> * builder; + std::vector body; + std::map> + namedValues; // Codegen阶段用 + std::string name; + CodeBlockAST * parent; + llvm::BasicBlock *endBB; }; #endif /* COMPILER_AST_CODEBLOCKAST_H_ */ diff --git a/src/ast/DoubleExprAST.cpp b/src/ast/DoubleExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f31d35cae9ccf5020fa43225bf1f51403b73d981 --- /dev/null +++ b/src/ast/DoubleExprAST.cpp @@ -0,0 +1,29 @@ +/* + * DoubleExprAST.cpp + * + * Created on: Feb 28, 2021 + * Author: zbc + */ + +#include "DoubleExprAST.h" +#include "TypeAST.h" + +DoubleExprAST::DoubleExprAST(CompileUnit *unit, double val) : ExprAST(unit) +{ + this->val = val; + this->type.push_back(new TypeAST(unit, "double")); +} + +DoubleExprAST::~DoubleExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector DoubleExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector result; + llvm::Type * rtype = llvm::Type::getDoubleTy(*unit->context); + llvm::Value * res = llvm::ConstantFP::get(rtype, val); + result.push_back(res); + return result; +} diff --git a/src/ast/DoubleExprAST.h b/src/ast/DoubleExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..58d22946ce84b197ead6525932d003b1898418d5 --- /dev/null +++ b/src/ast/DoubleExprAST.h @@ -0,0 +1,23 @@ +/* + * DoubleExprAST.h + * + * Created on: Feb 28, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_DOUBLEEXPRAST_H_ +#define SRC_AST_DOUBLEEXPRAST_H_ + +#include "ExprAST.h" + +class DoubleExprAST : public ExprAST +{ + public: + DoubleExprAST(CompileUnit *unit, double val); + virtual ~DoubleExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); + + double val; +}; + +#endif /* SRC_AST_DOUBLEEXPRAST_H_ */ diff --git a/src/ast/EmptyExprAST.cpp b/src/ast/EmptyExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0191eab757952be1193c098bfe09bf2d0255f71f --- /dev/null +++ b/src/ast/EmptyExprAST.cpp @@ -0,0 +1,23 @@ +/* + * EmptyExprAST.cpp + * + * Created on: Feb 24, 2021 + * Author: zbc + */ + +#include "EmptyExprAST.h" + +EmptyExprAST::EmptyExprAST(CompileUnit *unit) : ExprAST(unit) +{ + // TODO Auto-generated constructor stub +} + +EmptyExprAST::~EmptyExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector EmptyExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + return std::vector(); +} diff --git a/src/ast/EmptyExprAST.h b/src/ast/EmptyExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..b096ba5a77ef4a083525e30d653ea35b88402b83 --- /dev/null +++ b/src/ast/EmptyExprAST.h @@ -0,0 +1,21 @@ +/* + * EmptyExprAST.h + * + * Created on: Feb 24, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_EMPTYEXPRAST_H_ +#define SRC_AST_EMPTYEXPRAST_H_ + +#include "ExprAST.h" + +class EmptyExprAST : public ExprAST +{ + public: + EmptyExprAST(CompileUnit *unit); + virtual ~EmptyExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); +}; + +#endif /* SRC_AST_EMPTYEXPRAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index c9e0524c2dd70d8ec0d78e6e9ffc82a8e733a189..b227f253ec4e02d855f5437d05b8681ceb562398 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -1,31 +1,74 @@ #include "ExprAST.h" #include "../CompileError.hpp" #include "../utils.h" -#include "AssignmentAST.h" #include "BinaryExprAST.h" #include "BoolExprAST.h" #include "CallExprAST.h" #include "CodeBlockAST.h" +#include "DoubleExprAST.h" +#include "EmptyExprAST.h" #include "IfExprAST.h" #include "IntExprAST.h" +#include "MemberExprAST.h" +#include "ReturnExprAST.h" +#include "UnaryExprAST.h" +#include "VariableDefExprAST.h" #include "VariableExprAST.h" +#include "WhileExprAST.h" #include -int GetTokPrecedence(Token tok) +std::map BinopPrecedence; +std::map LUnaryopPrecedence; +std::map RUnaryopPrecedence; + +void initTokPrecedence() +{ + BinopPrecedence["="] = 1; + + BinopPrecedence[","] = 2; + BinopPrecedence["||"] = 3; + + BinopPrecedence["&&"] = 4; + + BinopPrecedence["|"] = 5; + + BinopPrecedence["^"] = 6; + + BinopPrecedence["&"] = 7; + + BinopPrecedence["=="] = 8; + BinopPrecedence["!="] = 8; + + BinopPrecedence[">"] = 9; + BinopPrecedence["<"] = 9; + BinopPrecedence[">="] = 9; + BinopPrecedence["<="] = 9; + + BinopPrecedence[">>"] = 9; + BinopPrecedence["<<"] = 9; + + BinopPrecedence["+"] = 10; + BinopPrecedence["-"] = 10; + + BinopPrecedence["*"] = 11; + BinopPrecedence["/"] = 11; + BinopPrecedence["%"] = 11; + + BinopPrecedence[".*"] = 12; + + BinopPrecedence["."] = 14; + BinopPrecedence["->"] = 14; + + LUnaryopPrecedence["*"] = 13; + LUnaryopPrecedence["!"] = 13; + LUnaryopPrecedence["&"] = 13; +} + +int GetBinTokPrecedence(Token tok) { if (tok.type != tok_syntax) { return -1; } - std::map BinopPrecedence; - BinopPrecedence["=="] = 100; - BinopPrecedence[">"] = 100; - BinopPrecedence["<"] = 100; - BinopPrecedence[">="] = 100; - BinopPrecedence["<="] = 100; - BinopPrecedence["+"] = 200; - BinopPrecedence["-"] = 200; - BinopPrecedence["*"] = 300; - BinopPrecedence["/"] = 300; int TokPrec = BinopPrecedence[tok.tokenValue]; if (TokPrec <= 0) { @@ -34,9 +77,36 @@ int GetTokPrecedence(Token tok) return TokPrec; } +int GetLUnaryTokPrecedence(Token tok) +{ + if (tok.type != tok_syntax) { + return -1; + } + + int TokPrec = LUnaryopPrecedence[tok.tokenValue]; + if (TokPrec <= 0) { + return -1; + } + return TokPrec; +} + +int GetRUnaryTokPrecedence(Token tok) +{ + if (tok.type != tok_syntax) { + return -1; + } + + int TokPrec = RUnaryopPrecedence[tok.tokenValue]; + if (TokPrec <= 0) { + return -1; + } + return TokPrec; +} + ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) { - // TODO Auto-generated constructor stub + subExpr = nullptr; + initTokPrecedence(); } ExprAST::~ExprAST() @@ -44,36 +114,53 @@ ExprAST::~ExprAST() // TODO Auto-generated destructor stub } -ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) +ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, + bool root) { + ExprAST *result; // todo:除了函数调用之外的语句解析 - Token token = unit->next_tok(); + Token token = *unit->icurTok; switch (token.type) { case tok_number: { - return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); + unit->next_tok(); + if (token.tokenValue.find(".") == std::string::npos) { + result = new IntExprAST(unit, + strtol(token.tokenValue.c_str(), NULL, 10)); + } else { + result = + new DoubleExprAST(unit, std::stod(token.tokenValue.c_str())); + } + break; } case tok_key_literal: { + unit->next_tok(); if (token.tokenValue == "true") { - return new BoolExprAST(unit, true); + result = new BoolExprAST(unit, true); } else { - return new BoolExprAST(unit, false); + result = new BoolExprAST(unit, false); } break; } case tok_key_if: { - return IfExprAST::ParseIfExpr(unit, codeblock); + result = IfExprAST::ParseIfExpr(unit, codeblock); + break; + } + case tok_key_while: { + result = WhileExprAST::ParseWhileExpr(unit, codeblock); + break; } case tok_syntax: { if (token.tokenValue == "(") { - ExprAST *result = ParseExpression(unit, codeblock, false); - token = unit->next_tok(); + unit->next_tok(); + result = ParseExpression(unit, codeblock, false); + token = *unit->icurTok; if (token.type != tok_syntax || token.tokenValue != ")") { CompileError e("missing ')'"); throw e; } - return result; + unit->next_tok(); } else { - std::cerr << "error3:" << token.dump() << std::endl; + result = new EmptyExprAST(unit); } break; } @@ -81,72 +168,73 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) //函数调用或定义 std::string idName = token.tokenValue; token = *(unit->icurTok + 1); - if (token.type == tok_identifier) { - //定义 - std::string valName = token.tokenValue; - unit->next_tok(); - VariableExprAST *varAST = - VariableExprAST::ParseVar(unit, codeblock, valName, idName); - codeblock->namedValues.insert( - std::pair(valName, varAST)); - return varAST; - } else if (token.tokenValue == "=") { - //赋值 - return AssignmentAST::ParseAssignment(unit, codeblock, idName); - } else if (token.tokenValue == "(") { + if (token.tokenValue == "(") { //函数调用 - unit->next_tok(); - std::vector args; + token = unit->next_tok(); + ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); + result = new CallExprAST(unit, idName, args); + } else { + //变量或变量定义 + int i = 1, ci = 1; while (true) { - Token nextToken = *(unit->icurTok + 1); - - if (nextToken.type == tok_syntax && - nextToken.tokenValue == ")") { - unit->next_tok(); + token = *(unit->icurTok + i); + if (token.type == tok_syntax) { + if (token.tokenValue == "*" && root) { + i++; + ci++; + continue; + } + if (token.tokenValue != "<") { + //变量 + unit->next_tok(); + result = new VariableExprAST(unit, codeblock, idName); + } else if (token.tokenValue == "<") { + //变量定义 + result = VariableDefExprAST::ParseVar(unit, codeblock); + } + break; + } else if (token.type == tok_identifier && i == ci) { + //变量定义 + result = VariableDefExprAST::ParseVar(unit, codeblock); break; } - if (nextToken.type == tok_syntax && - nextToken.tokenValue == ",") { - unit->next_tok(); - continue; - } - - ExprAST *arg = ExprAST::ParseExpression(unit, codeblock, false); - args.push_back(arg); - // todo:异常处理 - } - - return new CallExprAST(unit, idName, args); - } else { - //变量 - CodeBlockAST *curCodeBlock = codeblock; - while (curCodeBlock != nullptr) { - auto varAST = curCodeBlock->namedValues.find(idName); - if (varAST == curCodeBlock->namedValues.end()) { - curCodeBlock = curCodeBlock->parent; - } else { - return varAST->second; - } + i++; } - CompileError e("can't find variable:" + idName); - throw e; } break; } + case tok_return: { + return ReturnExprAST::ParseReturnExprAST(unit, codeblock); + } default: { - CompileError e("不期待的token:" + token.dump()); + CompileError e("不期待的token:" + token.dump(), token.file, + token.lineno); throw e; } } - return nullptr; + /*if (token.type == tok_syntax && token.tokenValue == ",") { + unit->next_tok(); + ExprAST *subExpr = ParseBinOpRHS(unit, codeblock, 200, result); + if (BinaryExprAST *v = dynamic_cast(subExpr)) { + subExpr = v->RHS; + } + result->subExpr = subExpr; + }*/ + return result; } static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, int ExprPrec, ExprAST *LHS) { + ExprAST *cExpr = LHS; while (1) { - Token token = *(unit->icurTok + 1); - int TokPrec = GetTokPrecedence(token); + Token token = *unit->icurTok; + int TokPrec; + if (LHS == nullptr) { + TokPrec = GetLUnaryTokPrecedence(token); + } else { + TokPrec = GetBinTokPrecedence(token); + } if (TokPrec < ExprPrec) { return LHS; } @@ -156,34 +244,82 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, if (!RHS) return nullptr; - int NextPrec = GetTokPrecedence(*(unit->icurTok + 1)); + int NextPrec = GetBinTokPrecedence(*(unit->icurTok)); if (TokPrec < NextPrec) { RHS = ParseBinOpRHS(unit, codeblock, TokPrec + 1, RHS); if (RHS == nullptr) { return nullptr; } } - LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); + if (token.tokenValue == ",") { + cExpr->subExpr = RHS; + cExpr = RHS; + } else if (token.tokenValue == ".") { + if (VariableExprAST *v = dynamic_cast(RHS)) { + LHS = new MemberExprAST(unit, LHS, v->idName, false); + } else { + CompileError e("成员方法调用未实现"); + throw e; + } + } else if (token.tokenValue == "->") { + if (VariableExprAST *v = dynamic_cast(RHS)) { + LHS = new MemberExprAST(unit, LHS, v->idName, true); + } else { + CompileError e("成员方法调用未实现"); + throw e; + } + } else if (dynamic_cast(LHS) != nullptr && + GetLUnaryTokPrecedence(token) != -1) { + //左一元运算符 + LHS = new UnaryExprAST(unit, token.tokenValue, RHS, true); + } else if (dynamic_cast(RHS) != nullptr && + GetRUnaryTokPrecedence(token) != -1) { + //右一元运算符 + LHS = new UnaryExprAST(unit, token.tokenValue, LHS, false); + } else { + LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); + } } } ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root) { - ExprAST *LHS = ParsePrimary(unit, codeblock); - if (LHS == nullptr) { - return nullptr; - } - ExprAST *result = ParseBinOpRHS(unit, codeblock, 0, LHS); + ExprAST *result = ParsePrimary(unit, codeblock, root); + + /*while (unit->icurTok->type == tok_syntax && + unit->icurTok->tokenValue == ".") { + LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); + }*/ + + result = ParseBinOpRHS(unit, codeblock, 0, result); + if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } + if (WhileExprAST *v = dynamic_cast(result)) { + return result; //跳过分号 + } + Token token = *(unit->icurTok); if (root) { - Token token = unit->next_tok(); if (token.type != tok_syntax || token.tokenValue != ";") { - CompileError e("丟失分号: \"" + token.dump() + "\" 前"); + CompileError e("丟失分号: \"" + token.dump() + "\" 前", token.file, + token.lineno); throw e; } + unit->next_tok(); + } + return result; +} + +std::vector ExprAST::CodegenChain(llvm::IRBuilder<> *builder) +{ + std::vector result = this->Codegen(builder); + if (subExpr != nullptr) { + std::vector subResult = subExpr->Codegen(builder); + std::vector subType = subExpr->type; + result.insert(result.end(), subResult.begin(), subResult.end()); + type.insert(type.end(), subType.begin(), subType.end()); } return result; } diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index 3bf5b6d0ee537e4ad75369aab9060415c5e435f1..f76f396af5897ecb45bd094bac1ab939b3590864 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -9,11 +9,16 @@ class ExprAST : public BaseAST public: ExprAST(CompileUnit *unit); virtual ~ExprAST(); - virtual llvm::Value *Codegen(llvm::IRBuilder<> *builder) = 0; + virtual std::vector Codegen(llvm::IRBuilder<> *builder) = 0; + std::vector CodegenChain(llvm::IRBuilder<> *builder); static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); - static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock); - std::string type; + static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, + bool root = false); + std::vector type; + ExprAST * subExpr; }; +static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, + int ExprPrec, ExprAST *LHS); #endif /* COMPILER_AST_ASTEXPR_H_ */ diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 63823fd20e5e68bff54493ca8015cb19860e208f..3f6c5bd50d720c80cdc27a3fb17d45caa1d38160 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -21,11 +21,40 @@ ExternAST::~ExternAST() ExternAST *ExternAST::ParseExtern(CompileUnit *unit) { + bool C = false; + bool S = false; + if ((unit->icurTok + 1)->type == tok_str) { + Token flag = unit->next_tok(); + if (flag.tokenValue == "S") { + S = true; + } else if (flag.tokenValue == "C") { + C = true; + } else { + CompileError e("Unknown flag:" + flag.tokenValue,flag.file,flag.lineno); + throw e; + } + } + unit->next_tok(); PrototypeAST *proto = PrototypeAST::ParsePrototype(unit, false); - std::cout << std::left << std::setw(35) << "Function extern found:" << proto->name << std::endl; + if (S) { + proto->returnDirectly = true; + } + // todo:对externC的处理 + std::cout << std::left << std::setw(35) + << "Function extern found:" << proto->name << std::endl; + Token token = *(unit->icurTok); + if (token.type != tok_syntax || token.tokenValue != ";") { + CompileError e("丟失分号: \"" + token.dump() + "\" 前", token.file, + token.lineno); + throw e; + } + token = unit->next_tok(); + return new ExternAST(unit, proto); } +std::string ExternAST::getDemangledName() { return proto->demangledName; } + llvm::Function *ExternAST::Codegen() { proto->Codegen(); diff --git a/src/ast/ExternAST.h b/src/ast/ExternAST.h index aa47819c6c3a7c31b3dd38208dcf10dcd4d4e2a3..6549d762bea6766ba13ec89588d5a549596eb088 100644 --- a/src/ast/ExternAST.h +++ b/src/ast/ExternAST.h @@ -19,6 +19,7 @@ class ExternAST : public BaseAST static ExternAST *ParseExtern(CompileUnit *unit); llvm::Function * Codegen(); PrototypeAST * proto; + std::string getDemangledName(); }; #endif /* COMPILER_AST_EXTERNAST_H_ */ diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index 932dabf52029a25b95df420aea5f9de36ae945e2..8d70a59ae3015143c93c8e9fe197c7bc5aa0b7a4 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -9,6 +9,7 @@ #include "../CompileError.hpp" #include "CodeBlockAST.h" #include "PrototypeAST.h" +#include "VariableDefExprAST.h" #include "VariableExprAST.h" #include #include @@ -41,14 +42,14 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) PrototypeAST *protoType = PrototypeAST::ParsePrototype(unit, true); std::cout << std::left << std::setw(35) << "Function definition found:" << protoType->name << std::endl; - std::map namedValues; + std::vector args; for (unsigned int i = 0; i < protoType->args.size(); i++) { - std::pair arg = protoType->args[i]; - namedValues.insert(std::pair( - arg.second, - new VariableExprAST(unit, arg.second, arg.first, nullptr, i))); + std::pair arg = protoType->args[i]; + args.push_back(new VariableDefExprAST(unit, nullptr, arg.second, + arg.first, nullptr, i)); } CodeBlockAST *body = - CodeBlockAST::ParseCodeBlock(unit, "entry", nullptr, namedValues); + CodeBlockAST::ParseCodeBlock(unit, "entry", nullptr, args); return new FunctionAST(unit, protoType, body); } +std::string FunctionAST::getDemangledName() { return proto->demangledName; } diff --git a/src/ast/FunctionAST.h b/src/ast/FunctionAST.h index 7e68aafd9ef48e38d703ed5fae9bd05260d10b59..ea78823191735f0fd36e6ec7e28b43769d19e6d1 100644 --- a/src/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -20,6 +20,7 @@ class FunctionAST : public BaseAST FunctionAST(CompileUnit *unit, PrototypeAST *proto, CodeBlockAST *body); virtual ~FunctionAST(); llvm::Function *Codegen(); + std::string getDemangledName(); PrototypeAST * proto; CodeBlockAST * body; diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index f3199563aa7f5709218e4a7324e30d47929fa7f9..d7997867fd34c2259592f77218e21d0996250500 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -27,28 +27,33 @@ IfExprAST::~IfExprAST() IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) { - ExprAST *condition = ExprAST::ParseExpression(unit, parent, false); unit->next_tok(); + ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); CodeBlockAST *thenBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); CodeBlockAST *elseBlock = nullptr; if ((unit->icurTok + 1)->type == tok_key_else) { - unit->next_tok(); unit->next_tok(); elseBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); } return new IfExprAST(unit, parent, condition, thenBlock, elseBlock); } -llvm::Value *IfExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector IfExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Function * function = builder->GetInsertBlock()->getParent(); - llvm::Value * conditionValue = condition->Codegen(builder); + llvm::Function *function = builder->GetInsertBlock()->getParent(); + std::vector conditionValues = + condition->CodegenChain(builder); + if (conditionValues.size() != 1) { + CompileError e("Multi/Void type in condition found."); + throw e; + } + llvm::Value * conditionValue = conditionValues[0]; llvm::BasicBlock *MergeBB = llvm::BasicBlock::Create(*unit->context, "", function); llvm::BasicBlock *thenBB = thenBlock->Codegen(function); if (elseBlock != nullptr) { llvm::BasicBlock *elseBB = elseBlock->Codegen(function); - builder->CreateCondBr(condition->Codegen(builder), thenBB, elseBB); + builder->CreateCondBr(conditionValue, thenBB, elseBB); builder->SetInsertPoint(elseBlock->endBB); builder->CreateBr(MergeBB); } else { @@ -58,5 +63,5 @@ llvm::Value *IfExprAST::Codegen(llvm::IRBuilder<> *builder) builder->CreateBr(MergeBB); builder->SetInsertPoint(MergeBB); parent->endBB = MergeBB; - return nullptr; + return std::vector(); } diff --git a/src/ast/IfExprAST.h b/src/ast/IfExprAST.h index 1919a20f9fc9979992b9d62ab75312f27a42facf..b34dfed8f68495019f3d7d9cd31a63468a1dc1c9 100644 --- a/src/ast/IfExprAST.h +++ b/src/ast/IfExprAST.h @@ -18,11 +18,11 @@ class IfExprAST : public ExprAST CodeBlockAST *thenBlock, CodeBlockAST *elseBlock); virtual ~IfExprAST(); static IfExprAST *ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - ExprAST * condition; - CodeBlockAST * thenBlock; - CodeBlockAST * elseBlock; - CodeBlockAST * parent; + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * condition; + CodeBlockAST * thenBlock; + CodeBlockAST * elseBlock; + CodeBlockAST * parent; }; #endif /* SRC_AST_IFEXPRAST_H_ */ diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 2f14ef569fc1fca81bc298634003a0048dee91d0..7353b5fb6bbd0e434311eb5ad17a08634eb09ab5 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -6,13 +6,12 @@ */ #include "IntExprAST.h" -#include -#include +#include "TypeAST.h" IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) { - this->val = val; - this->type = "int"; + this->val = val; + this->type.push_back(new TypeAST(unit, "int")); } IntExprAST::~IntExprAST() @@ -20,9 +19,11 @@ IntExprAST::~IntExprAST() // TODO Auto-generated destructor stub } -llvm::Value *IntExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector IntExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 64); - llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); - return res; + std::vector result; + llvm::IntegerType *rtype = llvm::IntegerType::get(*unit->context, 64); + llvm::ConstantInt *res = llvm::ConstantInt::get(rtype, val, true); + result.push_back(res); + return result; } diff --git a/src/ast/IntExprAST.h b/src/ast/IntExprAST.h index 5f3d289230c04221481057da23f3dd87af9fb5bb..33c7578616691c690b07926e769e503cf62156c1 100644 --- a/src/ast/IntExprAST.h +++ b/src/ast/IntExprAST.h @@ -15,7 +15,7 @@ class IntExprAST : public ExprAST public: IntExprAST(CompileUnit *unit, long long val); virtual ~IntExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); long long val; }; diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b460a1553d3525ea722073368fdab0521f7ebcb5 --- /dev/null +++ b/src/ast/MemberExprAST.cpp @@ -0,0 +1,56 @@ +/* + * MemberExprAST.cpp + * + * Created on: Feb 25, 2021 + * Author: zbc + */ + +#include "MemberExprAST.h" +#include "../CompileError.hpp" +#include "ClassAST.h" +#include "TypeAST.h" + +MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *LHS, + std::string member, bool isPointer) + : ExprAST(unit) +{ + this->LHS = LHS; + this->member = member; + this->isPointer = isPointer; +} + +MemberExprAST::~MemberExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + if (isPointer) { + CompileError e("未实现."); + throw e; + } + std::vector result; + std::vector bases = LHS->Codegen(builder); + if (bases.size() != 1) { + CompileError e("Multi/Void type found."); + throw e; + } + + llvm::Value *base = bases[0]; + + ClassAST *baseClass = unit->classes[LHS->type[0]->baseClass]; + auto memberAST = baseClass->members.find(member); + if (memberAST == baseClass->members.end()) { + CompileError e("Member " + member + " not found."); + throw e; + } + unsigned int index = + std::distance(std::begin(baseClass->members), memberAST); + + type.push_back(baseClass->getRealType( + baseClass->members[member]->variableType, LHS->type[0]->genericTypes)); + llvm::Value *member = builder->CreateExtractValue(base, {index}); + result.push_back(member); + return result; +} diff --git a/src/ast/MemberExprAST.h b/src/ast/MemberExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..410e5f468ee9b9b2614128e6d8032bfce05d1399 --- /dev/null +++ b/src/ast/MemberExprAST.h @@ -0,0 +1,25 @@ +/* + * MemberExprAST.h + * + * Created on: Feb 25, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_MEMBEREXPRAST_H_ +#define SRC_AST_MEMBEREXPRAST_H_ + +#include "ExprAST.h" + +class MemberExprAST : public ExprAST +{ + public: + MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member, + bool isPointer); + virtual ~MemberExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * LHS; + std::string member; + bool isPointer; +}; + +#endif /* SRC_AST_MEMBEREXPRAST_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 44829dbc419ab138d103156caa22614efa2503ab..044efe5873a4f0e95bc520addbfe169c5afdc549 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -14,11 +14,23 @@ PrototypeAST::PrototypeAST( CompileUnit *unit, const std::string &name, - const std::vector> &args) + const std::vector> &args, + const std::vector & returnTypes) : BaseAST(unit) { - this->name = name; - this->args = args; + this->name = name; + this->args = args; + this->returnDirectly = false; + this->returnTypes = returnTypes; + std::vector argStr; + for (std::pair pair : args) { + argStr.push_back(pair.first); + } + if (name != "main") { + this->demangledName = demangle(name, argStr); + } else { + this->demangledName = "main"; + } } PrototypeAST::~PrototypeAST() @@ -28,9 +40,8 @@ PrototypeAST::~PrototypeAST() PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) { - std::vector> args; - std::vector argStr; - Token token = unit->next_tok(); // identifier. + std::vector> args; + Token token = unit->next_tok(); if (token.type != tok_identifier) { std::cerr << "error1" << std::endl; // TODO:异常处理 @@ -45,22 +56,19 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } while (true) { - if (FnName == "main") { - token = unit->next_tok(); // ). - break; - } token = unit->next_tok(); if (token.type == tok_syntax && token.tokenValue == ",") { continue; } if (token.type == tok_syntax && token.tokenValue == ")") { + unit->next_tok(); break; } - std::string type = token.tokenValue; + TypeAST *type = TypeAST::ParseType(unit); // todo:错误处理 - token = unit->next_tok(); - std::string name = token.tokenValue; - std::pair pair; + token = *unit->icurTok; + std::string name = token.tokenValue; + std::pair pair; pair.first = type; pair.second = name; args.push_back(pair); @@ -69,74 +77,86 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) std::cout << "error3" << std::endl; // TODO:异常处理 } - for (std::pair pair : args) { - argStr.push_back(pair.first); - } - if (FnName != "main") { - FnName = demangle(FnName, argStr); - } - token = unit->next_tok(); // -> or ; or { - if (token.type == tok_return_type) { + token = *(unit->icurTok); // -> or ; or { + std::vector returnTypes; + if (token.type == tok_syntax && token.tokenValue == "->") { + unit->next_tok(); + int bc = 0; while (true) { - // todo:解析返回类型 - token = unit->next_tok(); // identifier. + // todo:大量异常处理 + token = *unit->icurTok; if (token.type == tok_syntax) { - if (token.tokenValue == "{") { - if (!hasBody) { - CompileError e("Unexpected function body"); - throw e; - } - break; - } - if (token.tokenValue == ";") { - if (hasBody) { - CompileError e("Unexpected ;"); - throw e; - } + if (token.tokenValue == "(") { + bc++; + unit->next_tok(); + continue; + } else if (token.tokenValue == ")") { + bc--; + unit->next_tok(); + continue; + } else if (token.tokenValue == ",") { + unit->next_tok(); + continue; + } else { break; } } + returnTypes.push_back(TypeAST::ParseType(unit)); } } else { if (token.tokenValue == "{") { if (!hasBody) { - CompileError e("Unexpected function body"); + CompileError e("Unexpected function body", token.file, + token.lineno); throw e; } } if (token.tokenValue == ";") { if (hasBody) { - CompileError e("Unexpected ;"); + CompileError e("Unexpected ;", token.file, token.lineno); throw e; } } } - return new PrototypeAST(unit, FnName, args); + return new PrototypeAST(unit, FnName, args, returnTypes); } llvm::Function *PrototypeAST::Codegen() { - // Make the function type: double(double,double) etc. - /* - llvm::FunctionType *FT = - llvm::FunctionType::get(Type::getDoubleTy(TheContext),llvm::Doubles, - false); - */ std::vector llvmArgs; for (int i = 0; i < args.size(); i++) { - auto typeAST = unit->types.find(args[i].first); - if (typeAST == unit->types.end()) { - CompileError e("can't find type:" + args[i].first); + llvmArgs.push_back(args[i].first->Codegen()); + } + llvm::Type *returnType; + if (returnDirectly) { + if (returnTypes.size() > 1) { + CompileError e("return more than one type:"); throw e; + } else if (returnTypes.size() == 0) { + returnType = llvm::Type::getVoidTy(*unit->context); + } else { + returnType = returnTypes[0]->Codegen(); + } + + } else { + if (name != "main") { + llvm::StructType *llvm_S = llvm::StructType::create(*unit->context); + std::vector members; + for (TypeAST *member : returnTypes) { + members.push_back(member->Codegen()); + } + llvm_S->setBody(members); + returnType = llvm_S; + } else { + returnType = llvm::IntegerType::get(*unit->context, 32); } - llvmArgs.push_back(typeAST->second->Codegen()); } - llvm::FunctionType *FT = llvm::FunctionType::get( - llvm::Type::getVoidTy(*unit->context), llvmArgs, false); + llvm::FunctionType *FT = + llvm::FunctionType::get(returnType, llvmArgs, false); llvm::Function *F = llvm::Function::Create( - FT, llvm::GlobalValue::ExternalLinkage, name, unit->module); + FT, llvm::GlobalValue::ExternalLinkage, demangledName, unit->module); // If F conflicted, there was already something named 'Name'. If it has a // body, don't allow redefinition or reextern. @@ -160,6 +180,7 @@ llvm::Function *PrototypeAST::Codegen() }*/ // todo:参数处理 // Set names for all arguments. + unsigned Idx = 0; for (llvm::Function::arg_iterator AI = F->arg_begin(); Idx != args.size(); ++AI, ++Idx) { diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index d7a2a96c29244821d32071f0672e56a631a046d9..886d3f750c92d03faed8b65ec5e7955ba2323ced 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -14,12 +14,18 @@ class PrototypeAST : public BaseAST { public: PrototypeAST(CompileUnit *unit, const std::string &name, - const std::vector> &args); + const std::vector> &args, + const std::vector &returnTypes); virtual ~PrototypeAST(); llvm::Function * Codegen(); static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody); - std::vector> args; - std::string name; + std::vector> args; + + std::string demangledName; + + std::vector returnTypes; + std::string name; + bool returnDirectly; //直接返回 }; #endif /* COMPILER_AST_PROTOTYPEAST_H_ */ diff --git a/src/ast/ReturnExprAST.cpp b/src/ast/ReturnExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d375cb250ad0954221f440e69a699b03186fb6a --- /dev/null +++ b/src/ast/ReturnExprAST.cpp @@ -0,0 +1,79 @@ +/* + * ReturnExprAST.cpp + * + * Created on: Feb 24, 2021 + * Author: zbc + */ + +#include "ReturnExprAST.h" + +ReturnExprAST::ReturnExprAST(CompileUnit *unit) : ExprAST(unit) +{ + returnExpr = nullptr; + // TODO Auto-generated constructor stub +} + +ReturnExprAST::~ReturnExprAST() +{ + // TODO Auto-generated destructor stub +} + +ReturnExprAST *ReturnExprAST::ParseReturnExprAST(CompileUnit * unit, + CodeBlockAST *codeblock) +{ + unit->next_tok(); + ReturnExprAST *result = new ReturnExprAST(unit); + if (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ";") { + result->returnExpr = nullptr; + } else { + result->returnExpr = ExprAST::ParseExpression(unit, codeblock, false); + } + return result; +} + +std::vector ReturnExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::Function *function = builder->GetInsertBlock()->getParent(); + + if (returnExpr != nullptr) { + std::vector returnValue = + returnExpr->CodegenChain(builder); + + llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + + llvm::StructType *sType = (llvm::StructType *)function->getReturnType(); + llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); + for (int i = 0; i < returnValue.size(); i++) { + llvm::IntegerType *type = + llvm::IntegerType::get(*unit->context, 32); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, i, true); + + llvm::Value *member_ptr = builder->CreateGEP( + sType, alloca, {llvm::ConstantInt::get(type, 0, true), res}); + builder->CreateStore(returnValue[i], member_ptr); + // builder->CreateLoad(member_ptr); + } + builder->CreateRet(builder->CreateLoad(alloca)); + } else { + std::vector returnValue = std::vector(); + + llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + + llvm::StructType *sType = (llvm::StructType *)function->getReturnType(); + llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); + for (int i = 0; i < returnValue.size(); i++) { + llvm::IntegerType *type = + llvm::IntegerType::get(*unit->context, 32); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, i, true); + + llvm::Value *member_ptr = builder->CreateGEP( + sType, alloca, {llvm::ConstantInt::get(type, 0, true), res}); + builder->CreateStore(returnValue[i], member_ptr); + // builder->CreateLoad(member_ptr); + } + builder->CreateRet(builder->CreateLoad(alloca)); + } + return std::vector(); +} diff --git a/src/ast/ReturnExprAST.h b/src/ast/ReturnExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..bd6b9f1d12e41172acea5112f24c78b4f8e35a7e --- /dev/null +++ b/src/ast/ReturnExprAST.h @@ -0,0 +1,24 @@ +/* + * ReturnExprAST.h + * + * Created on: Feb 24, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_RETURNEXPRAST_H_ +#define SRC_AST_RETURNEXPRAST_H_ + +#include "ExprAST.h" + +class ReturnExprAST : public ExprAST +{ + public: + ReturnExprAST(CompileUnit *unit); + virtual ~ReturnExprAST(); + static ReturnExprAST * ParseReturnExprAST(CompileUnit * unit, + CodeBlockAST *codeblock); + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * returnExpr; +}; + +#endif /* SRC_AST_RETURNEXPRAST_H_ */ diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index ab55cee9170a935e7a08e24106154a475b36b3b1..b6235b932a4dda81faf0d50f34f9ed3b7e2a19a0 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -6,11 +6,38 @@ */ #include "TypeAST.h" +#include "../CompileError.hpp" +#include "ClassAST.h" #include "CompileUnit.h" -TypeAST::TypeAST(CompileUnit *unit, std::string name) : BaseAST(unit) +TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, + std::vector genericTypes) + : BaseAST(unit) { - this->name = name; + this->baseClass = baseClass; + this->genericTypes = genericTypes; + this->pointee = nullptr; + initName(); + //生成name +} + +void TypeAST::initName() +{ + this->name = baseClass; + if (genericTypes.size() != 0) { + this->name += "<"; + for (unsigned int i = 0; i < genericTypes.size() - 1; i++) { + this->name += genericTypes[i]->name + ","; + } + this->name += genericTypes[genericTypes.size() - 1]->name + ">"; + } +} + +TypeAST::TypeAST(CompileUnit *unit, TypeAST *pointee) : BaseAST(unit) +{ + this->pointee = pointee; + //生成name + this->name = pointee->name + "*"; } TypeAST::~TypeAST() @@ -19,19 +46,53 @@ TypeAST::~TypeAST() } llvm::Type *TypeAST::Codegen() { - //内置类型处理 - if (name == "int") { - return llvm::Type::getInt64Ty(*unit->context); - } else if (name == "bool") { - return llvm::Type::getInt1Ty(*unit->context); + if (pointee == nullptr) { + //非指针类型 + auto typeAST = unit->types.find(name); + if (typeAST == unit->types.end()) { + //没有找到实例化过的泛型 + auto classAST = unit->classes.find(baseClass); + if (classAST == unit->classes.end()) { + CompileError e("can't find class:" + baseClass); + throw e; + } else { + llvm::Type *classType = classAST->second->Codegen(genericTypes); + return classType; + //构建泛型 + } + } else { + return typeAST->second; + } } else { - //用户定义的类型 - llvm::StructType *llvm_S = - llvm::StructType::create(*unit->context, name); - std::vector members; - for (TypeAST *member : innerType) { - members.push_back(member->Codegen()); + return llvm::PointerType::get(pointee->Codegen(), 0); + } +} + +TypeAST *TypeAST::ParseType(CompileUnit *unit) +{ + Token token = *unit->icurTok; + if (token.type != tok_identifier) { + CompileError e("Expected type but got " + token.dump(), token.file, + token.lineno); + throw e; + } + std::string baseClass = token.tokenValue; + std::vector genericTypes; + + token = unit->next_tok(); + if (token.type == tok_syntax && token.tokenValue == "<") { + + unit->next_tok(); + while (!(token.type == tok_syntax && token.tokenValue == ">")) { + genericTypes.push_back(TypeAST::ParseType(unit)); + token = *unit->icurTok; } - return llvm_S; + token = unit->next_tok(); + } + TypeAST *result = new TypeAST(unit, baseClass, genericTypes); + while (token.type == tok_syntax && token.tokenValue == "*") { + result = new TypeAST(unit, result); + token = unit->next_tok(); } + return result; } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 111f12842c66d4a9abfa07de39c3a5c733da5390..ea0269ab6ed1d7cdd9b2342c9b4d3d75f4baaa06 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -13,11 +13,19 @@ class TypeAST : public BaseAST { public: - TypeAST(CompileUnit *unit, std::string name); + TypeAST(CompileUnit *unit, std::string baseClass, + std::vector genericTypes = std::vector()); + TypeAST(CompileUnit *unit, TypeAST *pointee); virtual ~TypeAST(); + static TypeAST *ParseType(CompileUnit *unit); + void initName(); + llvm::Type * Codegen(); std::string name; + std::string baseClass; std::vector innerType; + std::vector genericTypes; + TypeAST * pointee; //指向的类型 }; #endif /* SRC_AST_TYPEAST_H_ */ diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1aa70f976584d15fc2055a6dadb2b66b3f1e94c4 --- /dev/null +++ b/src/ast/UnaryExprAST.cpp @@ -0,0 +1,120 @@ +/* + * UnaryExprAST.cpp + * + * Created on: Feb 21, 2021 + * Author: zbc + */ + +#include "UnaryExprAST.h" +#include "../CompileError.hpp" +#include "ClassAST.h" +#include "MemberExprAST.h" +#include "TypeAST.h" +#include "VariableExprAST.h" + +UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, + ExprAST *operand, bool leftop) + : ExprAST(unit) +{ + this->op = op; + this->operand = operand; + this->leftop = leftop; + /*if (op == "!") { + this->type.push_back(new TypeAST(unit, "bool")); + } else if (op == "&") { + this->type.push_back(new TypeAST(unit, "bool")); + } else { + CompileError e("一元运算符:" + op + "未实现"); + throw e; + }*/ +} + +UnaryExprAST::~UnaryExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector result; + if (op == "&") { + if (VariableExprAST *v = dynamic_cast(operand)) { + result.push_back(v->getAlloca()); + this->type.push_back(new TypeAST(unit, operand->type[0])); + } else if (MemberExprAST *v = dynamic_cast(operand)) { + llvm::Value * pointer; + std::vector chain; + ExprAST * curAST = operand; + while (true) { + chain.push_back(curAST); + if (MemberExprAST *v = dynamic_cast(curAST)) { + curAST = v->LHS; + } else if (VariableExprAST *v = + dynamic_cast(curAST)) { + break; + } else { + CompileError e("Unknown AST."); + throw e; + } + } + VariableExprAST *start = + dynamic_cast(chain[chain.size() - 1]); + pointer = start->getAlloca(); + std::vector idx; + std::string curType = start->type[0]->baseClass; + for (int i = chain.size() - 2; i >= 0; i--) { + MemberExprAST *v = dynamic_cast(chain[i]); + std::string member = v->member; + ClassAST * baseClass = unit->classes[curType]; + auto memberAST = baseClass->members.find(member); + if (memberAST == baseClass->members.end()) { + CompileError e("Member" + member + " not found."); + throw e; + } + unsigned int index = + std::distance(std::begin(baseClass->members), memberAST); + idx.push_back(index); + curType = baseClass->members[member]->variableType->name; + } + std::vector idxl; + llvm::IntegerType * itype = + llvm::IntegerType::get(*unit->context, 32); + + idxl.push_back(llvm::ConstantInt::get(itype, 0, true)); + for (unsigned int pid : idx) { + idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); + } + if (idx.size() != 0) { + pointer = builder->CreateGEP(start->type[0]->Codegen(), pointer, + idxl); + } + result.push_back(pointer); + } else { + CompileError e("& can only be used with variable"); + throw e; + } + } else { + //值操作 + std::vector Rs = operand->CodegenChain(builder); + if (Rs.size() != 1) { + CompileError e("Unary Expr length != 1"); + throw e; + } + + if (op == "!") { + this->type.push_back(new TypeAST(unit, "bool")); + result.push_back(builder->CreateXor(Rs[0], 1)); + } else if (op == "*") { + if (operand->type[0]->pointee == nullptr) { + CompileError e("operator * must be used on pointer"); + throw e; + } + this->type.push_back(operand->type[0]->pointee); + result.push_back(builder->CreateLoad(Rs[0])); + } else { + CompileError e("一元运算符:" + op + "未实现"); + throw e; + } + } + return result; +} diff --git a/src/ast/UnaryExprAST.h b/src/ast/UnaryExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..7db1f325375782b300f9304ca7a2b8d7aa2403aa --- /dev/null +++ b/src/ast/UnaryExprAST.h @@ -0,0 +1,25 @@ +/* + * UnaryExprAST.h + * + * Created on: Feb 21, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_UNARYEXPRAST_H_ +#define SRC_AST_UNARYEXPRAST_H_ + +#include "ExprAST.h" + +class UnaryExprAST : public ExprAST +{ + public: + UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand, + bool leftop); + virtual ~UnaryExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); + std::string op; + ExprAST * operand; + bool leftop; +}; + +#endif /* SRC_AST_UNARYEXPRAST_H_ */ diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f7c1c299284a4730dcd5b891f44cf1d92b88242a --- /dev/null +++ b/src/ast/VariableDefExprAST.cpp @@ -0,0 +1,127 @@ +/* + * VariableDefExprAST.cpp + * + * Created on: Jan 23, 2021 + * Author: zbc + */ + +#include "VariableDefExprAST.h" + +#include "../CompileError.hpp" +#include "CodeBlockAST.h" +#include "IntExprAST.h" +#include "TypeAST.h" +#include +#include + +VariableDefExprAST::VariableDefExprAST(CompileUnit * unit, + CodeBlockAST * codeblock, + const std::string &idName, TypeAST *type, + ExprAST *initValue, int argID) + : ExprAST(unit) +{ + this->codeblock = codeblock; + this->idName = idName; + this->alloca = nullptr; + this->initValue = initValue; + this->argID = argID; + this->variableType = type; +} + +VariableDefExprAST::~VariableDefExprAST() +{ + // TODO Auto-generated destructor stub +} + +static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, + llvm::Function * function, + const std::string &VarName, + TypeAST * typeAST) +{ + llvm::IRBuilder<> builder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + return builder.CreateAlloca(typeAST->Codegen(), 0, VarName.c_str()); +} + +std::vector +VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + if (codeblock == nullptr) { + llvm::GlobalVariable *gVar = new llvm::GlobalVariable( + *unit->module, variableType->Codegen(), false, + llvm::GlobalValue::ExternalLinkage, nullptr, idName); + // todo:初始填0 + if (variableType->name == "int") { + llvm::IntegerType *itype = + llvm::IntegerType::get(*unit->context, 64); + llvm::ConstantInt *res = llvm::ConstantInt::get(itype, 0, true); + gVar->setInitializer(res); + } else if (variableType->name == "double") { + llvm::Type * ftype = llvm::Type::getDoubleTy(*unit->context); + llvm::Constant *res = llvm::ConstantFP::get(ftype, 0); + gVar->setInitializer(res); + } else if (variableType->name == "bool") { + llvm::IntegerType *itype = + llvm::IntegerType::get(*unit->context, 1); + llvm::ConstantInt *res = llvm::ConstantInt::get(itype, 0, true); + gVar->setInitializer(res); + } + unit->globalVariablesValue.insert( + std::pair>( + idName, + std::pair(variableType, gVar))); + //全局变量 + } else { + //局部变量 + llvm::BasicBlock *insertBlock = builder->GetInsertBlock(); + llvm::Function * function = insertBlock->getParent(); + alloca = CreateEntryBlockAlloca(unit, function, idName, variableType); + if (argID != -1) { + builder->CreateStore(function->getArg(argID), alloca); + } + if (initValue != nullptr) { + std::vector ivalues = + initValue->CodegenChain(builder); + if (ivalues.size() != 1) { + CompileError e("Multi/Void type in init found."); + throw e; + } + builder->CreateStore(ivalues[0], alloca); + } + codeblock->namedValues.insert( + std::pair>( + idName, std::pair(variableType, + alloca))); + } + return std::vector(); +} + +VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, + CodeBlockAST *codeblock) +{ + TypeAST *typeAST = TypeAST::ParseType(unit); + + Token nexToken = *(unit->icurTok); + std::string idName = nexToken.tokenValue; + nexToken = unit->next_tok(); + ExprAST *initValue = nullptr; + + if (nexToken.type != tok_syntax || nexToken.tokenValue != ";") { + if (nexToken.type == tok_syntax && nexToken.tokenValue == "=") { + if (codeblock == nullptr) { + CompileError e("全局变量初始化未实现"); + throw e; + } + unit->next_tok(); + initValue = ExprAST::ParseExpression(unit, codeblock, false); + } else { + CompileError e("Unknown token:" + nexToken.dump(),nexToken.file,nexToken.lineno); + throw e; + } + } + + std::cout << std::left << std::setw(35) + << "Variable definition found:" << idName + << " with type:" << typeAST->name << std::endl; + return new VariableDefExprAST(unit, codeblock, idName, typeAST, initValue); +} diff --git a/src/ast/VariableDefExprAST.h b/src/ast/VariableDefExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..ba8dfa0e5128400f3cad81046ff3037aa2c119c6 --- /dev/null +++ b/src/ast/VariableDefExprAST.h @@ -0,0 +1,30 @@ +/* + * VariableDefExprAST.h + * + * Created on: Jan 23, 2021 + * Author: zbc + */ + +#ifndef COMPILER_AST_VARIABLEDEFEXPRAST_H_ +#define COMPILER_AST_VARIABLEDEFEXPRAST_H_ +#include "ExprAST.h" + +class VariableDefExprAST : public ExprAST +{ + public: + VariableDefExprAST(CompileUnit *unit, CodeBlockAST *codeblock, + const std::string &idName, TypeAST *type, + ExprAST *initValue, int argID = -1); + virtual ~VariableDefExprAST(); + static VariableDefExprAST *ParseVar(CompileUnit * unit, + CodeBlockAST *codeblock); + std::vector Codegen(llvm::IRBuilder<> *builder); + CodeBlockAST * codeblock; + std::string idName; + llvm::AllocaInst * alloca; + ExprAST * initValue; + TypeAST * variableType; + int argID; //函数的参数号,函数内变量为-1 +}; + +#endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index c94c51174ffb3ee0e7d2fc5f0657dac54f78a631..fbe3c5d0ae9a8810a30e61ab80e34cd84d32c3c6 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -13,16 +13,13 @@ #include "TypeAST.h" #include -VariableExprAST::VariableExprAST(CompileUnit *unit, const std::string &idName, - const std::string &type, ExprAST *initValue, - int argID) +VariableExprAST::VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, + const std::string &idName) : ExprAST(unit) { this->idName = idName; - this->type = type; + this->codeblock = codeblock; this->alloca = nullptr; - this->initValue = initValue; - this->argID = argID; } VariableExprAST::~VariableExprAST() @@ -30,56 +27,41 @@ VariableExprAST::~VariableExprAST() // TODO Auto-generated destructor stub } -static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, - llvm::Function * function, - const std::string &VarName, - const std::string &type) +llvm::Value *VariableExprAST::getAlloca() { - llvm::IRBuilder<> builder(&function->getEntryBlock(), - function->getEntryBlock().begin()); - auto typeAST = unit->types.find(type); - if (typeAST == unit->types.end()) { - CompileError e("can't find type:" + type); - throw e; + if (alloca != nullptr) { + return alloca; } - - return builder.CreateAlloca(typeAST->second->Codegen(), 0, VarName.c_str()); -} - -llvm::Value *VariableExprAST::Codegen(llvm::IRBuilder<> *builder) -{ - if (alloca == nullptr) { - llvm::BasicBlock *insertBlock = builder->GetInsertBlock(); - llvm::Function * function = insertBlock->getParent(); - alloca = CreateEntryBlockAlloca(unit, function, idName, type); - if (argID != -1) { - builder->CreateStore(function->getArg(argID), alloca); - } - if (initValue != nullptr) { - builder->CreateStore(initValue->Codegen(builder), alloca); + //找局部变量 + CodeBlockAST *curCodeBlock = codeblock; + while (curCodeBlock != nullptr) { + auto varAST = curCodeBlock->namedValues.find(idName); + if (varAST == curCodeBlock->namedValues.end()) { + curCodeBlock = curCodeBlock->parent; + } else { + alloca = varAST->second.second; + type.push_back(varAST->second.first); + if (varAST->second.first->name == "") { + std::cout << "fuck" << std::endl; + } + return alloca; } } - return builder->CreateLoad(alloca); + //找全局变量 + auto gVar = unit->globalVariablesValue.find(idName); + if (gVar == unit->globalVariablesValue.end()) { + CompileError e("can't find variable:" + idName); + throw e; + } else { + type.push_back(gVar->second.first); + alloca = gVar->second.second; + return alloca; + } } -VariableExprAST *VariableExprAST::ParseVar(CompileUnit * unit, - CodeBlockAST *codeblock, - std::string idName, std::string type) +std::vector VariableExprAST::Codegen(llvm::IRBuilder<> *builder) { - std::cout << std::left << std::setw(35) - << "Variable definition found:" << idName << " with type:" << type - << std::endl; - Token nexToken = *(unit->icurTok + 1); - ExprAST *initValue = nullptr; - - if (nexToken.type != tok_syntax || nexToken.tokenValue != ";") { - if (nexToken.type == tok_syntax && nexToken.tokenValue == "=") { - unit->next_tok(); - initValue = ExprAST::ParseExpression(unit, codeblock, false); - } else { - CompileError e("Unknown token:" + nexToken.dump()); - throw e; - } - } - return new VariableExprAST(unit, idName, type, initValue); + std::vector result; + result.push_back(builder->CreateLoad(getAlloca())); + return result; } diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index 0356ad875bc3548a539757a743aa52097635dcc5..5b4de5e6629f888db40a8302fb96e1a6ca262a9c 100644 --- a/src/ast/VariableExprAST.h +++ b/src/ast/VariableExprAST.h @@ -12,17 +12,16 @@ class VariableExprAST : public ExprAST { public: - VariableExprAST(CompileUnit *unit, const std::string &idName, - const std::string &type, ExprAST *initValue, - int argID = -1); + VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, + const std::string &idName); virtual ~VariableExprAST(); - static VariableExprAST *ParseVar(CompileUnit *unit, CodeBlockAST *codeblock, - std::string idName, std::string type); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - std::string idName; - llvm::Value * alloca; - ExprAST * initValue; - int argID; //函数的参数号,函数内变量为-1 + llvm::Value * getAlloca(); + std::vector Codegen(llvm::IRBuilder<> *builder); + std::string idName; + CodeBlockAST * codeblock; + + private: + llvm::Value *alloca; }; #endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index bad61c28ce2bedd3ad6872ae96cbb3b42094a0cc..585ade162a9dd780a5b2e1fefc137e948ecaf3e5 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -6,10 +6,16 @@ */ #include "WhileExprAST.h" +#include "../CompileError.hpp" +#include "CodeBlockAST.h" -WhileExprAST::WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock) +WhileExprAST::WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock, + ExprAST *condition, CodeBlockAST *body) : ExprAST(unit) { + this->condition = condition; + this->body = body; + this->parent = codeblock; } WhileExprAST::~WhileExprAST() @@ -17,7 +23,40 @@ WhileExprAST::~WhileExprAST() // TODO Auto-generated destructor stub } -llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector WhileExprAST::Codegen(llvm::IRBuilder<> *builder) { - return nullptr; + llvm::Function * function = builder->GetInsertBlock()->getParent(); + llvm::BasicBlock *MergeBB = + llvm::BasicBlock::Create(*unit->context, "", function); + llvm::BasicBlock *condBB = + llvm::BasicBlock::Create(*unit->context, "", function); + + llvm::BasicBlock *bodyBB = body->Codegen(function); + builder->CreateBr(condBB); + + // builder->SetInsertPoint(body->endBB); + builder->SetInsertPoint(condBB); + std::vector conditionValues = + condition->CodegenChain(builder); + if (conditionValues.size() != 1) { + CompileError e("Multi/Void type in condition found."); + throw e; + } + builder->CreateCondBr(conditionValues[0], bodyBB, MergeBB); + + builder->SetInsertPoint(body->endBB); + builder->CreateBr(condBB); + + builder->SetInsertPoint(MergeBB); + parent->endBB = MergeBB; + return std::vector(); +} + +WhileExprAST *WhileExprAST::ParseWhileExpr(CompileUnit * unit, + CodeBlockAST *parent) +{ + unit->next_tok(); + ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); + CodeBlockAST *body = CodeBlockAST::ParseCodeBlock(unit, "", parent); + return new WhileExprAST(unit, parent, condition, body); } diff --git a/src/ast/WhileExprAST.h b/src/ast/WhileExprAST.h index a6a4e2afccff45ab788f32ee2e17ab0ccbf1257e..543da09a41197611c0aabfe67de8cffbed8a1c55 100644 --- a/src/ast/WhileExprAST.h +++ b/src/ast/WhileExprAST.h @@ -13,9 +13,15 @@ class WhileExprAST : public ExprAST { public: - WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock); + WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock, ExprAST *condition, + CodeBlockAST *body); virtual ~WhileExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); + static WhileExprAST * ParseWhileExpr(CompileUnit * unit, + CodeBlockAST *parent); + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * condition; + CodeBlockAST * body; + CodeBlockAST * parent; }; #endif /* SRC_AST_WHILEEXPRAST_H_ */ diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 93f61924f6a895f6a5ca7f7b0fb817028c6d4094..2fab4eec8ab5527d0c1a9571b9ad39ec9c9f4b85 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -3,6 +3,7 @@ extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } extern void _alolang_12testPrintInt3int(long long a) { printf("%lld\n", a); } +extern void _alolang_15testPrintDouble6double(double a) { printf("%lf\n", a); } extern void _alolang_13testPrintBool4bool(int a) { if (a) { @@ -18,3 +19,10 @@ extern int _alolang_10testGetInt() scanf("%d", &a); return a; } + +extern double _alolang_13testGetDouble() +{ + double a; + scanf("%lf", &a); + return a; +} \ No newline at end of file diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 0cb64e1095561e2917d330c7f25d24310fa63c01..2e5be87785def17314480878f09845248b17ad1a 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -32,7 +32,7 @@ std::pair genFactor(const std::string &line) } } -std::string processPreInstruction(const std::string &line, int cnt) +std::vector processPreInstruction(const std::string &line, int cnt, int lineno) { std::pair instruction = genFactor(line); //解析后的预编译指令 @@ -45,7 +45,7 @@ std::string processPreInstruction(const std::string &line, int cnt) std::string importFileContent; std::getline(t_fin__, importFileContent, char(EOF)); t_fin__.close(); - return preProcess(importFileContent, cnt + 1); + return preProcess(importFileContent, cnt + 1, instruction.second); } else if (instruction.first == "def") { //解析宏定义 std::string var, data; @@ -68,7 +68,7 @@ std::string processPreInstruction(const std::string &line, int cnt) data = instruction.second.substr(i + 1, len - i - 1); } variable[var] = data; - return ""; + return std::vector{Tline(std::pair("",lineno),"")}; } else if (instruction.first == "rmdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -80,7 +80,7 @@ std::string processPreInstruction(const std::string &line, int cnt) throw e; //找不到宏定义 } - return ""; + return std::vector{Tline(std::pair("",lineno),"")}; } else if (instruction.first == "ifdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -93,7 +93,7 @@ std::string processPreInstruction(const std::string &line, int cnt) closeifstack++; } currentifstack++; - return ""; + return std::vector{Tline(std::pair("",lineno),"")}; } else if (instruction.first == "ifndef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -106,7 +106,7 @@ std::string processPreInstruction(const std::string &line, int cnt) closeifstack++; } currentifstack++; - return ""; + return std::vector{Tline(std::pair("",lineno),"")}; } else if (instruction.first == "endif") { if (currentifstack == 0) { CompileError e("no second instruction"); @@ -116,7 +116,7 @@ std::string processPreInstruction(const std::string &line, int cnt) closeifstack--; } currentifstack--; - return ""; + return std::vector{Tline(std::pair("",lineno),"")}; } else { CompileError e("Unrecognized preprocessor command"); throw e; @@ -158,59 +158,71 @@ std::string doReplace(std::string &line) } //递归预处理 -std::string preProcess(const std::string &code, int cnt) +std::vector preProcess(const std::string &code, int cnt, std::string FN) { if (cnt == 128) { CompileError e("preprocessor recursion too deep"); throw e; } std::istringstream buft_fin__(code); - std::stringstream preprocessoroutput; + // std::stringstream preprocessoroutput; + std::vector processedLines; std::string temp; bool isCommented = false; + int lineno = 0; while (std::getline(buft_fin__, temp)) { + lineno++; if (closeifstack > 0 && temp.substr(0, 6) != "%endif" && temp.substr(0, 7) != "%ifndef" && temp.substr(0, 6) != "%ifdef") { continue; } if (temp[0] == '%') { - std::string processedPreInstruction = - processPreInstruction(temp, cnt); + auto processedPreInstruction = + processPreInstruction(temp, cnt, lineno); if (processedPreInstruction.size() > 0) - preprocessoroutput << processedPreInstruction << std::endl; + std::move(processedPreInstruction.begin(), processedPreInstruction.end(), std::back_inserter(processedLines)); } else { std::string replaced = doReplace(temp); //处理块注释 - long unsigned int position = replaced.find("*/"); + std::string result = ""; + + //处理行注释 + bool flag = false; + std::string resulta = replaced; + long unsigned int position = replaced.find("//"); if (position != replaced.npos) { + resulta = replaced.substr(0, position); + } + position = resulta.find("/*"); + if (position != resulta.npos) { + result += resulta.substr(0, position); + isCommented = true; + flag = true; + } + + position = resulta.find("*/"); + if (position != resulta.npos) { if (!isCommented) { - // TODO:错误处理 + CompileError e("Haven't been commented"); + throw e; } - replaced = replaced.substr(position + 2, - replaced.length() - position - 2); + result += resulta.substr(position + 2, + resulta.length() - position - 2); isCommented = false; + flag = true; } - if (isCommented) { - replaced = ""; - } - position = replaced.find("/*"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); - isCommented = true; + if (!flag) { + result = resulta; } - - //处理行注释 - position = replaced.find("//"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); + if (isCommented) { + result = ""; } - - int plen = replaced.length(); + int plen = result.length(); if (plen > 0) { - preprocessoroutput << replaced << std::endl; + processedLines.push_back(Tline(std::pair(FN,lineno),result)); } } temp.erase(); } - return preprocessoroutput.str(); + return processedLines; } diff --git a/src/preprocessor.h b/src/preprocessor.h index a89cba39dbf2a4a26998e8523d0211dc60472720..6d56b80744c2a2fb799db53f12e2a97eb449fc6a 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -4,9 +4,14 @@ #include #include #include +#include +#include #include #include -std::string preProcess(const std::string &code, int cnt); +typedef std::pair,std::string> Tline; + +std::vector preProcess(const std::string &code, int cnt, std::string FN); + #endif diff --git a/src/utils.cpp b/src/utils.cpp index 9a25a2d2d1b5d58db41fe61304ea8595b2aef6dd..65a81c796d57a6ea0b1ff3f08d744e6a0eaede9d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -5,7 +5,7 @@ * Author: zbc */ #include "CompileError.hpp" -#include "llvm/IR/Instructions.h" +#include "ast/TypeAST.h" #include #include #include @@ -14,19 +14,14 @@ char syntax[] = {'!', '%', '^', '&', '*', '(', ')', '+', '=', '{', '}', '|', '~', '[', ']', '\\', ';', '\'', ':', '"', ',', '<', '>', '?', '.', '/', '#', ' '}; -struct Variable { - std::string type; - llvm::AllocaInst value; -}; - -std::string demangle(const std::string & fnName, - const std::vector &argTypes) +std::string demangle(const std::string & fnName, + const std::vector &argTypes) { std::stringstream ss; ss << "_alolang_"; ss << fnName.length() << fnName; - for (std::string word : argTypes) { - ss << word.length() << word; //得到类型 + for (TypeAST *word : argTypes) { + ss << word->name.length() << word->name; //得到类型 } return ss.str(); } diff --git a/src/utils.h b/src/utils.h index 354081eec12f934ac26e166e165903706e40e7ed..2532903573307d1c0ddd2994c9ba375f56f2627c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,11 +8,12 @@ #ifndef COMPILER_UTILS_H_ #define COMPILER_UTILS_H_ +#include #include #include -std::string demangle(const std::string & fnName, - const std::vector &argTypes); +std::string demangle(const std::string & fnName, + const std::vector &argTypes); bool isSyntax(char c); void skipSpace(const std::vector &words, long unsigned int &i); diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 2157e17258d2eae69b32d5f95bfc40af3a43c1f1..f2f0d44d564babde562b98c94b73231d291362c0 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -30,12 +30,13 @@ while token = tok_key_while; return token case|switch token = tok_key_switch; return token; --> token = tok_return_type; return token; +class token = tok_key_class; return token; + fun token = tok_fun; return token; func token = tok_fun; return token; extern token = tok_extern; return token; -return token = tok_extern; return token; -[a-zA-Z_][a-zA-Z_]* token = tok_identifier; return token; +return token = tok_return; return token; +[a-zA-Z_][a-zA-Z_0-9]* token = tok_identifier; return token; 0b[01]+ token = tok_number; return token; 0x[1-9a-fA-F][0-9a-fA-F]* token = tok_number; return token; 0B[01]+ token = tok_number; return token; @@ -44,7 +45,7 @@ return token = tok_extern; return token [1-9][0-9.]* token = tok_number; return token; 0 token = tok_number; return token; - +-> token = tok_syntax; return token; == token = tok_syntax; return token; != token = tok_syntax; return token; \>= token = tok_syntax; return token; diff --git a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md index 351a4da9b45497279e23b3dfb47ba3d2dad60c37..72af2c038dc6671c8ed1cff5cb6e88d37f7a0347 100644 --- a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md +++ b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md @@ -4,9 +4,33 @@ All notable changes to the "alolang" extension will be documented in this file. Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. -## [Dev Beta 0.0.1] +## Dev Beta 0.0.5 + +- Added support for class + +## Dev Beta 0.0.4 + +- Added support for extern behavior + +## Dev Beta 0.0.3 + +- Bugfix + - Highlight for function mis behaving + +## Dev Beta 0.0.2 + +- Added support for + - Comment toggling + - Brackets definition + - Autoclosing + - Autosurrounding + - Folding + - Word pattern + - Indentation Rules + +## Dev Beta 0.0.1 - Initial release - Working on compiler, will integrate after compiler is stable. - May have many bugs -- Added syntax highlighting feature \ No newline at end of file +- Added syntax highlighting feature diff --git a/syntax_highlight_plugin/vscode/alolang/README.md b/syntax_highlight_plugin/vscode/alolang/README.md index d8cad1613c03406401ccfb6e7275200dc8ae2be7..8a021690d4bb3c9758f15695f075f34d6be68a14 100644 --- a/syntax_highlight_plugin/vscode/alolang/README.md +++ b/syntax_highlight_plugin/vscode/alolang/README.md @@ -31,6 +31,14 @@ Waiting to be reported. ## Release Notes +### Dev Beta 0.0.5 + +- Added support for class + +### Dev Beta 0.0.4 + +- Added support for extern behavior + ### Dev Beta 0.0.3 - Bugfix diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.4.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.4.vsix new file mode 100644 index 0000000000000000000000000000000000000000..c001e2121a9c972a15504f35ef5a27d45ef50683 Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.4.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.5.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.5.vsix new file mode 100644 index 0000000000000000000000000000000000000000..e7db80742e7897a32d7f94a9517250c9efaa7b40 Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.5.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.6.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.6.vsix new file mode 100644 index 0000000000000000000000000000000000000000..87b9d2484e323132342bc3c5938d9ed08edbc79a Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.6.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/package.json b/syntax_highlight_plugin/vscode/alolang/package.json index 586e2c7a0a7840f994c4c7510f892194fae3dc95..b4d50f1ccbd3438576d9244d56db0515de4df808 100644 --- a/syntax_highlight_plugin/vscode/alolang/package.json +++ b/syntax_highlight_plugin/vscode/alolang/package.json @@ -2,7 +2,7 @@ "name": "alolang", "displayName": "AloLang", "description": "Syntax Highlight for AloLang", - "version": "0.0.3", + "version": "0.0.6", "publisher": "AloLangDevTeam", "license": "GPLv3", "repository": { @@ -10,7 +10,7 @@ "url": "https://gitee.com/alolang-dev-team/AloLang-Dev.git" }, "engines": { - "vscode": "^1.53.0" + "vscode": "^1.50.0" }, "categories": [ "Programming Languages" diff --git a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json index c6bf74977bc2153c83769158980547af6c5bc579..f2b738b8557a9c7ba46a6dbdd37b73f6b01826a1 100644 --- a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json +++ b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json @@ -85,15 +85,18 @@ }, { "comment": "Function declarations", - "match": "^(\\bextern\\b)?\\s*(\\bfunc\\b|\\bfun\\b)(?:\\s+([a-zA-Z_]\\w*)(?=\\())?", + "match": "^(\\bextern\\b)?\\s*(\\\"\\w+\\\")?\\s*(\\bfunc\\b|\\bfun\\b)(?:\\s+([a-zA-Z_]\\w*)(?=\\())?", "captures": { "1": { "name": "keyword.extern.alolang" }, "2": { - "name": "keyword.function.alolang" + "name": "string.quoted.double.alolang" }, "3": { + "name": "keyword.function.alolang" + }, + "4": { "name": "entity.name.function" } } @@ -200,6 +203,10 @@ { "name": "keyword.const.alolang", "match": "\\bconst\\b" + }, + { + "name": "keyword.class.alolang", + "match": "\\bclass\\b" } ] }, diff --git a/test/classanytype.alo b/test/classanytype.alo new file mode 100644 index 0000000000000000000000000000000000000000..92f0abc934229c7b34b5dcad12ec38a39f33e181 --- /dev/null +++ b/test/classanytype.alo @@ -0,0 +1,33 @@ +extern func testPrintInt(int i); + +class node { + node* pred; + node* succ; + A data; +} + +func main() { + node test1; + node test2; + node test3; + + test1.pred = &test2; + test1.succ = &test3; + + test1.data = 1; + test1.pred->data = 2; + test1.succ->data = 3; + + int* testint1 = &(test1.data); + + testPrintInt(test1.data); + testPrintInt(test2.data); + testPrintInt(test3.data); + testPrintInt((*(test1.succ)).data); + testPrintInt((*(test1.pred)).data); + testPrintInt(*testint1); + + if (true) + testPrintInt(114514); + +} \ No newline at end of file diff --git a/test/classcheck.alo b/test/classcheck.alo new file mode 100644 index 0000000000000000000000000000000000000000..1f3b4327c48aab1ac30e470f50bc825c8ecb554a --- /dev/null +++ b/test/classcheck.alo @@ -0,0 +1,24 @@ +extern func testPrintInt(int i); + +class foo { + int a; + int b; +} + +class bar { + foo F; +} + +func main(){ + foo A; + bar B; + A.a = 3; + A.b = 4; + B.F = A; + testPrintInt(B.F.a); + testPrintInt(A.b); + A.a = 4; + A.b = 5; + // A.c = 999; + // testPrintInt(A.c); +} \ No newline at end of file diff --git a/test/demo.alo.bc b/test/demo.alo.bc deleted file mode 100644 index ffd4e6f941f3c13189aea70f4c68225e07b58813..0000000000000000000000000000000000000000 Binary files a/test/demo.alo.bc and /dev/null differ diff --git a/test/demo.alo.ll b/test/demo.alo.ll deleted file mode 100644 index d7385b51352e9a6bb003ca427dff73bfc3c08a51..0000000000000000000000000000000000000000 --- a/test/demo.alo.ll +++ /dev/null @@ -1,26 +0,0 @@ -; ModuleID = './../test/demo.alo.bc' -source_filename = "test.ll" - -declare void @_alolang_8testPuts() - -declare void @_alolang_12testPrintInt3int(i64) - -define void @_alolang_4demo() { -entry: - call void @_alolang_8testPuts() - call void @_alolang_12testPrintInt3int(i64 1) - call void @_alolang_12testPrintInt3int(i64 11) - call void @_alolang_12testPrintInt3int(i64 511) - call void @_alolang_12testPrintInt3int(i64 2) - call void @_alolang_12testPrintInt3int(i64 65536) - call void @_alolang_12testPrintInt3int(i64 -1) - call void @_alolang_12testPrintInt3int(i64 8192) - call void @_alolang_12testPrintInt3int(i64 -1) - ret void -} - -define void @main() { -entry: - call void @_alolang_4demo() - ret void -} diff --git a/test/demo.alo.s b/test/demo.alo.s deleted file mode 100644 index 3797bac22709d5405c4f150c7ea56d989e203239..0000000000000000000000000000000000000000 --- a/test/demo.alo.s +++ /dev/null @@ -1,51 +0,0 @@ - .text - .file "test.ll" - .globl _alolang_4demo # -- Begin function _alolang_4demo - .p2align 4, 0x90 - .type _alolang_4demo,@function -_alolang_4demo: # @_alolang_4demo - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - callq _alolang_8testPuts@PLT - movl $1, %edi - callq _alolang_12testPrintInt3int@PLT - movl $11, %edi - callq _alolang_12testPrintInt3int@PLT - movl $511, %edi # imm = 0x1FF - callq _alolang_12testPrintInt3int@PLT - movl $2, %edi - callq _alolang_12testPrintInt3int@PLT - movl $65536, %edi # imm = 0x10000 - callq _alolang_12testPrintInt3int@PLT - movq $-1, %rdi - callq _alolang_12testPrintInt3int@PLT - movl $8192, %edi # imm = 0x2000 - callq _alolang_12testPrintInt3int@PLT - movq $-1, %rdi - callq _alolang_12testPrintInt3int@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end0: - .size _alolang_4demo, .Lfunc_end0-_alolang_4demo - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - callq _alolang_4demo@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end1: - .size main, .Lfunc_end1-main - .cfi_endproc - # -- End function - .section ".note.GNU-stack","",@progbits diff --git a/test/demoa+b.alo b/test/demoa+b.alo index c99fc1282ebb823a3d71405c2a6412757f5f468a..d79af8a7c8379a0aadfe99772b7d9905068741de 100644 --- a/test/demoa+b.alo +++ b/test/demoa+b.alo @@ -1,14 +1,29 @@ -extern func testPrintInt(int i); -extern func testGetInt(); +extern func testPrintDouble(double i); +extern "S" func testGetDouble() -> double; func main() { - int a = 2; - int b; - int c; + double a = 2.0; + double b; + double c; - b = 9; + b = 9.0; c = a + b; - testPrintInt(c); + testPrintDouble(c); + + a = testGetDouble(); + b = testGetDouble(); + testPrintDouble(a); + testPrintDouble(b); + // c = a & b; + // testPrintInt(c); + // c = a | b; + // testPrintInt(c); + c = a + b; + testPrintDouble(c); + c = a - b; + testPrintDouble(c); + c = a * b; + testPrintDouble(c); } \ No newline at end of file diff --git a/test/demoa+b.alo.bc b/test/demoa+b.alo.bc deleted file mode 100644 index 6c8af1b2dbe4bfa2c9c82bf5b6ac876b72dd0172..0000000000000000000000000000000000000000 Binary files a/test/demoa+b.alo.bc and /dev/null differ diff --git a/test/demoa+b.alo.ll b/test/demoa+b.alo.ll deleted file mode 100644 index 865e9b0fa5f874a9db10a097d963702c6e794d8b..0000000000000000000000000000000000000000 --- a/test/demoa+b.alo.ll +++ /dev/null @@ -1,25 +0,0 @@ -; ModuleID = './../test/demoa+b.alo.bc' -source_filename = "test.ll" - -declare void @_alolang_12testPrintInt3int(i64) - -declare void @_alolang_10testGetInt() - -define void @main() { -entry: - %c = alloca i64, align 8 - %b = alloca i64, align 8 - %a = alloca i64, align 8 - store i64 2, i64* %a, align 4 - %0 = load i64, i64* %a, align 4 - %1 = load i64, i64* %b, align 4 - %2 = load i64, i64* %c, align 4 - store i64 9, i64* %b, align 4 - %3 = load i64, i64* %a, align 4 - %4 = load i64, i64* %b, align 4 - %5 = add i64 %3, %4 - store i64 %5, i64* %c, align 4 - %6 = load i64, i64* %c, align 4 - call void @_alolang_12testPrintInt3int(i64 %6) - ret void -} diff --git a/test/demoa+b.alo.s b/test/demoa+b.alo.s deleted file mode 100644 index bd3b29f00ee02e3599c76702a20b4dde466bc0bd..0000000000000000000000000000000000000000 --- a/test/demoa+b.alo.s +++ /dev/null @@ -1,23 +0,0 @@ - .text - .file "test.ll" - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# %bb.0: # %entry - subq $24, %rsp - .cfi_def_cfa_offset 32 - movq $2, (%rsp) - movq $9, 8(%rsp) - movq $11, 16(%rsp) - movl $11, %edi - callq _alolang_12testPrintInt3int@PLT - addq $24, %rsp - .cfi_def_cfa_offset 8 - retq -.Lfunc_end0: - .size main, .Lfunc_end0-main - .cfi_endproc - # -- End function - .section ".note.GNU-stack","",@progbits diff --git a/test/globalvar.alo b/test/globalvar.alo new file mode 100644 index 0000000000000000000000000000000000000000..bafc3e9e5f9db5f516d440281cd8055505a8c6e7 --- /dev/null +++ b/test/globalvar.alo @@ -0,0 +1,16 @@ +int a; + +extern func testPrintInt(int i); + +func rec(){ + if (a < 10){ + testPrintInt(a); + a = a + 1; + rec(); + } +} + +func main(){ + testPrintInt(a); + rec(); +} \ No newline at end of file diff --git a/test/loop.alo b/test/loop.alo new file mode 100644 index 0000000000000000000000000000000000000000..8dd4128b2530c481fd672a45e62dfd6e11f7f8f0 --- /dev/null +++ b/test/loop.alo @@ -0,0 +1,9 @@ +extern func testPrintInt(int a); + +func main() { + int a = 0; + while (a < 10){ + testPrintInt(a); + a = a + 1; + } +} \ No newline at end of file diff --git a/test/module b/test/module deleted file mode 100644 index 3652e2bb98e105ca5b954fdb3381dd4958d191c8..0000000000000000000000000000000000000000 Binary files a/test/module and /dev/null differ diff --git a/test/module.ll b/test/module.ll deleted file mode 100644 index 8eb421453407f66cab9e392b0be421781f39050e..0000000000000000000000000000000000000000 --- a/test/module.ll +++ /dev/null @@ -1,24 +0,0 @@ -; ModuleID = './module' -source_filename = "test.ll" - -@0 = private unnamed_addr constant [17 x i8] c"just for debug!\0A\00", align 1 - -define void @testPuts() { -entry: - %0 = call i32 @puts(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @0, i32 0, i32 0)) - ret void -} - -declare i32 @puts(i8*) - -define void @demo() { -entry: - call void @testPuts() - ret void -} - -define void @main() { -entry: - call void @demo() - ret void -} diff --git a/test/module.s b/test/module.s deleted file mode 100644 index 2ec427bf097065710cb5360116c49bc62c3c6223..0000000000000000000000000000000000000000 --- a/test/module.s +++ /dev/null @@ -1,58 +0,0 @@ - .text - .file "test.ll" - .globl testPuts # -- Begin function testPuts - .p2align 4, 0x90 - .type testPuts,@function -testPuts: # @testPuts - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - leaq .L__unnamed_1(%rip), %rdi - callq puts@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end0: - .size testPuts, .Lfunc_end0-testPuts - .cfi_endproc - # -- End function - .globl demo # -- Begin function demo - .p2align 4, 0x90 - .type demo,@function -demo: # @demo - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - callq testPuts@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end1: - .size demo, .Lfunc_end1-demo - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - callq demo@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end2: - .size main, .Lfunc_end2-main - .cfi_endproc - # -- End function - .type .L__unnamed_1,@object # @0 - .section .rodata.str1.1,"aMS",@progbits,1 -.L__unnamed_1: - .asciz "just for debug!\n" - .size .L__unnamed_1, 17 - - .section ".note.GNU-stack","",@progbits diff --git a/test/mulret.alo b/test/mulret.alo new file mode 100644 index 0000000000000000000000000000000000000000..bafe5e730271f739d6d5a38d502d23619da0a6ec --- /dev/null +++ b/test/mulret.alo @@ -0,0 +1,14 @@ +extern func testPrintInt(int i); +extern "S" func testGetInt() -> int; + +func swap(int a, int b) -> int, int { + return b/*,a*/; +} + +func main() { + int a = testGetInt(); + int b = testGetInt(); + a, b= swap(a, b); + testPrintInt(a); + testPrintInt(b); +} \ No newline at end of file diff --git a/test/override.alo b/test/override.alo new file mode 100644 index 0000000000000000000000000000000000000000..1516221335f8f6fa904f37c67fe38a7584a7a5f9 --- /dev/null +++ b/test/override.alo @@ -0,0 +1,14 @@ +extern func testPrintInt(int i); + +func demo(int a){ + testPrintInt(1); +} + +func demo(int a, int b){ + testPrintInt(2); +} + +func main(){ + demo(1); + demo(1,2); +} \ No newline at end of file diff --git a/test/perfcheck/demo.alo b/test/perfcheck/demo.alo new file mode 100644 index 0000000000000000000000000000000000000000..1011d7d1663e13920e94071afddb563c36e9b4c2 --- /dev/null +++ b/test/perfcheck/demo.alo @@ -0,0 +1,12 @@ +extern func testPrintInt(int i); + +func main() { + int a = 1; + int b = 1; + int c; + while (a < 4611686018427387903){ + c=a+b; + a,b = c,a; + } + testPrintInt(a); +} \ No newline at end of file diff --git a/test/perfcheck/demo.c b/test/perfcheck/demo.c new file mode 100644 index 0000000000000000000000000000000000000000..bbfaf198d141e90a524c2cbb1a7e9c9487e4cccc --- /dev/null +++ b/test/perfcheck/demo.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + long long int a = 1; + long long int b = 1; + long long int c; + while (a < 4611686018427387903) { + c = a + b; + b = a; + a = c; + } + printf("a = %lld\n", a); + return 0; +} \ No newline at end of file diff --git a/test/perfcheck/demo.py b/test/perfcheck/demo.py new file mode 100755 index 0000000000000000000000000000000000000000..05a458900412dae123b2d62ce6f179795859ce7c --- /dev/null +++ b/test/perfcheck/demo.py @@ -0,0 +1,6 @@ +#!/usr/bin/python + +a = 0 +while a < 100000000: + a = a + 1 +print(a) \ No newline at end of file diff --git a/test/recursion.alo.bc b/test/recursion.alo.bc deleted file mode 100644 index 28a1a316d9bdb5f60fcabcb8dbbbe50153a247e4..0000000000000000000000000000000000000000 Binary files a/test/recursion.alo.bc and /dev/null differ diff --git a/test/recursion.alo.ll b/test/recursion.alo.ll deleted file mode 100644 index 60cd6912318db2af2149872b2d12f75745b42e7d..0000000000000000000000000000000000000000 --- a/test/recursion.alo.ll +++ /dev/null @@ -1,32 +0,0 @@ -; ModuleID = './../test/recursion.alo.bc' -source_filename = "test.ll" - -declare void @_alolang_12testPrintInt3int(i64) - -define void @_alolang_3rec3int(i64 %a) { -entry: - %a1 = alloca i64, align 8 - store i64 %a, i64* %a1, align 4 - %0 = load i64, i64* %a1, align 4 - %1 = icmp slt i64 %0, 10 - br i1 %1, label %3, label %2 - -2: ; preds = %3, %entry - ret void - -3: ; preds = %entry - %4 = load i64, i64* %a1, align 4 - call void @_alolang_12testPrintInt3int(i64 %4) - %5 = load i64, i64* %a1, align 4 - %6 = add i64 %5, 1 - store i64 %6, i64* %a1, align 4 - %7 = load i64, i64* %a1, align 4 - call void @_alolang_3rec3int(i64 %7) - br label %2 -} - -define void @main() { -entry: - call void @_alolang_3rec3int(i64 0) - ret void -} diff --git a/test/recursion.alo.s b/test/recursion.alo.s deleted file mode 100644 index 53fd5005d0414ae01fa0dd71f840a29880595555..0000000000000000000000000000000000000000 --- a/test/recursion.alo.s +++ /dev/null @@ -1,46 +0,0 @@ - .text - .file "test.ll" - .globl _alolang_3rec3int # -- Begin function _alolang_3rec3int - .p2align 4, 0x90 - .type _alolang_3rec3int,@function -_alolang_3rec3int: # @_alolang_3rec3int - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - movq %rdi, (%rsp) - cmpq $10, %rdi - jge .LBB0_2 -# %bb.1: - movq (%rsp), %rdi - callq _alolang_12testPrintInt3int@PLT - movq (%rsp), %rdi - incq %rdi - movq %rdi, (%rsp) - callq _alolang_3rec3int@PLT -.LBB0_2: - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end0: - .size _alolang_3rec3int, .Lfunc_end0-_alolang_3rec3int - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# %bb.0: # %entry - pushq %rax - .cfi_def_cfa_offset 16 - xorl %edi, %edi - callq _alolang_3rec3int@PLT - popq %rax - .cfi_def_cfa_offset 8 - retq -.Lfunc_end1: - .size main, .Lfunc_end1-main - .cfi_endproc - # -- End function - .section ".note.GNU-stack","",@progbits diff --git a/test/test03.alo.ac b/test/test03.alo.ac deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/test/wrongstr.alo.bc b/test/wrongstr.alo.bc deleted file mode 100644 index bd350e341430fe6471df36b079fafc8b616f428b..0000000000000000000000000000000000000000 Binary files a/test/wrongstr.alo.bc and /dev/null differ diff --git a/test/wrongstr.alo.ll b/test/wrongstr.alo.ll deleted file mode 100644 index 5dc1094f28a4ede9f212e0f4a564590742fa608a..0000000000000000000000000000000000000000 --- a/test/wrongstr.alo.ll +++ /dev/null @@ -1,2 +0,0 @@ -; ModuleID = './../test/wrongstr.alo.bc' -source_filename = "test.ll" diff --git a/test/wrongstr.alo.s b/test/wrongstr.alo.s deleted file mode 100644 index b86c029ff64b539e6b42e052c4644d33a01a2a54..0000000000000000000000000000000000000000 --- a/test/wrongstr.alo.s +++ /dev/null @@ -1,3 +0,0 @@ - .text - .file "test.ll" - .section ".note.GNU-stack","",@progbits diff --git a/tools/demangle b/tools/demangle index 7e73da6f7a34a10bedc2f780789d237db2ea0fc2..8a6a8ce9de531187bdfae7913f40c6b8754ed464 100755 Binary files a/tools/demangle and b/tools/demangle differ diff --git a/tools/demangle.cpp b/tools/demangle.cpp index 7120a3606168623d2023aa1acdffb07b700773bc..7e463e1f81eaed3bb11e56c95b95029d23deea3a 100644 --- a/tools/demangle.cpp +++ b/tools/demangle.cpp @@ -72,7 +72,7 @@ std::string demangle(const std::string &line) CompileError e("some error happened"); // todo:错误信息 throw e; } - skipSpace(words, i); + if (words[i] != ")") { //有参数 while (true) { @@ -85,7 +85,8 @@ std::string demangle(const std::string &line) } if (words[i] != ",") { // TODO:异常处理(逗号) - CompileError e("some error happened (comma)"); // todo:错误信息 + CompileError e("Expected comma got " + + words[i]); // todo:错误信息 throw e; } } @@ -103,4 +104,4 @@ int main(int argc, char *argv[]) catch (const std::exception &e) { std::cerr << e.what() << '\n'; } -} \ No newline at end of file +}