From 6d57696f6ab0f1c984f0b47c076f31c788abbacf Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 20 Feb 2021 08:49:44 +0800 Subject: [PATCH 01/98] Implement WhileExprAST --- src/ast/ExprAST.cpp | 7 +++++++ src/ast/WhileExprAST.cpp | 27 ++++++++++++++++++++++++++- src/ast/WhileExprAST.h | 10 ++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index c9e0524..e59797f 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -9,6 +9,7 @@ #include "IfExprAST.h" #include "IntExprAST.h" #include "VariableExprAST.h" +#include "WhileExprAST.h" #include int GetTokPrecedence(Token tok) @@ -63,6 +64,9 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) case tok_key_if: { return IfExprAST::ParseIfExpr(unit, codeblock); } + case tok_key_while: { + return WhileExprAST::ParseWhileExpr(unit, codeblock); + } case tok_syntax: { if (token.tokenValue == "(") { ExprAST *result = ParseExpression(unit, codeblock, false); @@ -178,6 +182,9 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } + if (WhileExprAST *v = dynamic_cast(result)) { + return result; //跳过分号 + } if (root) { Token token = unit->next_tok(); if (token.type != tok_syntax || token.tokenValue != ";") { diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index bad61c2..6bdf84f 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -6,10 +6,15 @@ */ #include "WhileExprAST.h" +#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() @@ -19,5 +24,25 @@ WhileExprAST::~WhileExprAST() llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) { + llvm::Function *function = builder->GetInsertBlock()->getParent(); + + llvm::BasicBlock *MergeBB = + llvm::BasicBlock::Create(*unit->context, "", function); + llvm::BasicBlock *bodyBB = body->Codegen(function); + builder->CreateBr(bodyBB); + builder->SetInsertPoint(body->endBB); + llvm::Value *conditionValue = condition->Codegen(builder); + builder->CreateCondBr(conditionValue, bodyBB, MergeBB); + builder->SetInsertPoint(MergeBB); + parent->endBB = MergeBB; return nullptr; } + +WhileExprAST *WhileExprAST::ParseWhileExpr(CompileUnit * unit, + CodeBlockAST *parent) +{ + ExprAST *condition = ExprAST::ParseExpression(unit, parent, false); + unit->next_tok(); + 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 a6a4e2a..8bc7046 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); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + ExprAST * condition; + CodeBlockAST * body; + CodeBlockAST * parent; }; #endif /* SRC_AST_WHILEEXPRAST_H_ */ -- Gitee From 70688579b0fd8d704efec445a87def190411bdde Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 08:55:46 +0800 Subject: [PATCH 02/98] tested while loop --- test/loop.alo | 9 +++++++++ test/loop.alo.bc | Bin 0 -> 1188 bytes test/loop.alo.ll | 25 +++++++++++++++++++++++++ test/loop.alo.s | 29 +++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 test/loop.alo create mode 100644 test/loop.alo.bc create mode 100644 test/loop.alo.ll create mode 100644 test/loop.alo.s diff --git a/test/loop.alo b/test/loop.alo new file mode 100644 index 0000000..8dd4128 --- /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/loop.alo.bc b/test/loop.alo.bc new file mode 100644 index 0000000000000000000000000000000000000000..275661b2e0194605aa110af11c928dc17f4840f5 GIT binary patch literal 1188 zcmXw3K}_3L7=DgJ>_Pf$AnKChL=F@wLWm}zTN9E@B;G36axhvCRBAl~#1gGReAJrF6HJKk*(GqiU>b)!Vy z)3My;H2VW)_X+wgOIOzRdH&j6wpc=S@2~(selvE0hx-hlGU~N)0rkg z@YCHLU`oBrtI35H@VI}S!SuWzlbh9O-8r*%)-PQA=STah>TQffnb#wL-@el3{XbIt zM53rke%*?Q-P41wP@7sGh%xs&D8$naZddKx3<=Wz$Yq@Z6T&l z8c^Apgg8QqlX@|l6K8YD?xPw!+Jk?s!$T`RT3TVMD~w#XJ3(gC%oLNx&7kJzEaxn7 z&RpHzmmG_nBaOQjr3+}&SM#o?xGOJdzaJMP!(ud&ij5KRfEd$@v1QTl=tJrVP=E5U znuV2qs?5Se#DcXLcM7Hrujz@I*-4sq_Lyqf_y=YR>4zM7u5T&jlKJzmi3G%%I1$ec z`H!=dqJZfW(`Jx)ZZ_@~j9*|T1+dvz3u><1N;zc7mFGN2kXIY-D(6b0P|AGQh?t5q z2oFijS%_#Zd96aj!*#gN!ur^5&2-PGKa9A|__7ENhs26*h8cXe4seP9En}=ZVa0r-qZ(o$7LVCoqUkMoHnF>9%JJ}x5E3h&{_ zlH^#!T&pS1B98WWOaq`no{-(EDc2HeDDGKKxlwbol5&58>?xL3HP?-%0%eV^19bAb zSSNY~z0HN8>_#4I*5Uo$%vF_lFl`&<0ZVFpEn9SD9>0Ai-L3~+quNVq@|V@k9{;1 eThis Inner Loop Header: Depth=1 + movq (%rsp), %rdi + callq _alolang_12testPrintInt3int@PLT + movq (%rsp), %rax + incq %rax + movq %rax, (%rsp) + cmpq $10, %rax + jl .LBB0_1 +# %bb.2: + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits -- Gitee From 78bbde3dec5a7bd3c26da73e53b18a0fda38c287 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 09:12:41 +0800 Subject: [PATCH 03/98] Added document for blank identifier --- docs/_sidebar.md | 1 + docs/language/keyword/blank/index.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 docs/language/keyword/blank/index.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 5a680f3..956b461 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -29,6 +29,7 @@ * [alolang关键字:array](language/keyword/type/array/index) * [alolang关键字:int32_t](language/keyword/type/int32_t/index) * [alolang关键词: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) diff --git a/docs/language/keyword/blank/index.md b/docs/language/keyword/blank/index.md new file mode 100644 index 0000000..fe0071b --- /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 -- Gitee From 9216ff94c26729e5a5c1fff0e5eefd29ce1e4f25 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 09:51:34 +0800 Subject: [PATCH 04/98] Added CF Web Analytics --- docs/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 30e018f..38f223c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -30,6 +30,8 @@ - + + + -- Gitee From 9843f6cbabd7df05b340db0bdf556225851631ca Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 20 Feb 2021 15:37:17 +0800 Subject: [PATCH 05/98] Rebuild Codeblock --- src/CompileUnit.cpp | 22 ++++++++++-------- src/CompileUnit.h | 4 ++++ src/ast/CodeBlockAST.cpp | 38 ++++++++++++++++++------------- src/ast/ExternAST.cpp | 26 +++++++++++++++++++++- src/ast/IfExprAST.cpp | 4 +--- src/ast/PrototypeAST.cpp | 48 +++++++++++++++++++++++----------------- src/ast/PrototypeAST.h | 5 ++++- src/ast/WhileExprAST.cpp | 5 ++--- 8 files changed, 100 insertions(+), 52 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 2b25b39..f4213be 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -65,7 +65,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - std::cout << token.dump() << std::endl; + // std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); @@ -80,7 +80,7 @@ CompileUnit::CompileUnit(std::string name, std::string source) this->sis = std::istringstream(source); this->lexer = new yyFlexLexer(sis, std::cerr); context = new llvm::LLVMContext(); - module = new llvm::Module("test.ll", *context); + module = new llvm::Module(name, *context); } CompileUnit::~CompileUnit() {} @@ -101,8 +101,9 @@ void CompileUnit::compile() do { 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.push_back(func_ast); + // llvm::Function *func = func_ast->Codegen(); /*llvm::Type* type=llvm::FunctionType::get(llvm::Type::getVoidTy(*context), false); @@ -121,17 +122,20 @@ void CompileUnit::compile() std::to_string(token.lineno)); throw e; } - if (token.type == tok_fun) { - ExternAST::ParseExtern(this)->Codegen(); - } - // todo:对导出非函数符号的处理 + externs.push_back(ExternAST::ParseExtern(this)); break; } default: - std::cerr << "unexpected token:" << icurTok->dump() << std::endl; } } while (next_tok().type != tok_eof); + std::cout << "Start codegen:" << name << std::endl; + for (ExternAST *externast : externs) { + externast->Codegen(); + } + for (FunctionAST *functionast : functions) { + functionast->Codegen(); + } build(); } diff --git a/src/CompileUnit.h b/src/CompileUnit.h index af1c1dc..870a352 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -16,6 +16,8 @@ #include class TypeAST; +class FunctionAST; +class ExternAST; class CompileUnit { public: @@ -34,6 +36,8 @@ class CompileUnit std::vector tokenList; std::vector::iterator icurTok; std::map types; + std::vector functions; + std::vector externs; }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 44374a4..d9763e5 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -29,24 +29,32 @@ CodeBlockAST *CodeBlockAST::ParseCodeBlock( CompileUnit *unit, std::string name, CodeBlockAST *parent, std::map namedValues) { - CodeBlockAST *codeblock = - new CodeBlockAST(unit, std::vector(), name, parent); - codeblock->namedValues = namedValues; - std::vector &body = codeblock->body; + Token token = *(unit->icurTok + 1); + if (token.type == tok_syntax && token.tokenValue == "{") { + unit->next_tok(); + 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; + while (true) { + Token inBlockToken = *(unit->icurTok + 1); + 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)); } - if (inBlockToken.type == tok_syntax && inBlockToken.tokenValue == "}") { - unit->next_tok(); - break; - } - body.push_back(ExprAST::ParseExpression(unit, codeblock, true)); + return codeblock; + } else { + CompileError e("Expected codeblock"); + throw e; } - return codeblock; } llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 63823fd..363831c 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -21,8 +21,32 @@ 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); + throw e; + } + } 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->next_tok(); + if (token.type != tok_syntax || token.tokenValue != ";") { + CompileError e("丟失分号: \"" + token.dump() + "\" 前"); + throw e; + } + return new ExternAST(unit, proto); } diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index f319956..e092ce1 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -27,13 +27,11 @@ 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); } diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 44829db..c3559e7 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -14,11 +14,14 @@ 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; } PrototypeAST::~PrototypeAST() @@ -75,28 +78,33 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) if (FnName != "main") { FnName = demangle(FnName, argStr); } - token = unit->next_tok(); // -> or ; or { - + token = *(unit->icurTok + 1); // -> or ; or { + std::vector returnTypes; if (token.type == tok_return_type) { + unit->next_tok(); + int bc = 0; while (true) { - // todo:解析返回类型 - token = unit->next_tok(); // identifier. + // todo:大量异常处理 + token = *(unit->icurTok + 1); // identifier. 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; } } + if (token.type == tok_identifier) { + returnTypes.push_back(token.tokenValue); + } } } else { if (token.tokenValue == "{") { @@ -112,7 +120,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } } } - return new PrototypeAST(unit, FnName, args); + return new PrototypeAST(unit, FnName, args, returnTypes); } llvm::Function *PrototypeAST::Codegen() diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index d7a2a96..bd7f30a 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -14,12 +14,15 @@ 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::vector returnTypes; std::string name; + bool returnDirectly; //直接返回 }; #endif /* COMPILER_AST_PROTOTYPEAST_H_ */ diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 6bdf84f..648fb9f 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -41,8 +41,7 @@ llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) WhileExprAST *WhileExprAST::ParseWhileExpr(CompileUnit * unit, CodeBlockAST *parent) { - ExprAST *condition = ExprAST::ParseExpression(unit, parent, false); - unit->next_tok(); - CodeBlockAST *body = CodeBlockAST::ParseCodeBlock(unit, "", parent); + ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); + CodeBlockAST *body = CodeBlockAST::ParseCodeBlock(unit, "", parent); return new WhileExprAST(unit, parent, condition, body); } -- Gitee From fa68e494575df2adb5fb234f95df403a0c68ccc4 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 20 Feb 2021 16:27:54 +0800 Subject: [PATCH 06/98] Implement extern "S" --- src/CompileUnit.cpp | 48 ++++++++++++++++++---------------------- src/CompileUnit.h | 22 +++++++++--------- src/ast/CallExprAST.cpp | 24 +++++++++++--------- src/ast/ExternAST.cpp | 3 +++ src/ast/ExternAST.h | 1 + src/ast/FunctionAST.cpp | 1 + src/ast/FunctionAST.h | 1 + src/ast/PrototypeAST.cpp | 45 ++++++++++++++++++++++++++++--------- src/ast/PrototypeAST.h | 9 +++++--- 9 files changed, 92 insertions(+), 62 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index f4213be..ff557e5 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -34,19 +34,10 @@ void scanToken(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(); - } + int tokenid = unit->lexer->yylex(); + token.type = TokenType(tokenid); + token.lineno = unit->lexer->lineno(); + token.tokenValue = unit->lexer->YYText(); // Deal with numbers if (token.type == tok_number) { int numTypeFlag = 10; //进制数 @@ -62,10 +53,13 @@ void scanToken(CompileUnit *unit) 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; + std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); @@ -102,7 +96,8 @@ void CompileUnit::compile() switch (icurTok->type) { case tok_fun: { FunctionAST *func_ast = FunctionAST::ParseFunction(this); - functions.push_back(func_ast); + 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), @@ -116,13 +111,9 @@ void CompileUnit::compile() break; } case tok_extern: { - Token token = next_tok(); - if (token.type == tok_eof) { - CompileError e("Unexpected EOF in funtion body, line " + - std::to_string(token.lineno)); - throw e; - } - externs.push_back(ExternAST::ParseExtern(this)); + ExternAST *externast = ExternAST::ParseExtern(this); + externs.insert(std::pair( + externast->getDemangledName(), externast)); break; } default: @@ -130,12 +121,17 @@ void CompileUnit::compile() } } while (next_tok().type != tok_eof); std::cout << "Start codegen:" << name << std::endl; - for (ExternAST *externast : externs) { - externast->Codegen(); + std::map::reverse_iterator extern_iter; + for (extern_iter = externs.rbegin(); extern_iter != externs.rend(); + extern_iter++) { + extern_iter->second->Codegen(); } - for (FunctionAST *functionast : functions) { - functionast->Codegen(); + std::map::reverse_iterator function_iter; + for (function_iter = functions.rbegin(); function_iter != functions.rend(); + function_iter++) { + function_iter->second->Codegen(); } + build(); } diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 870a352..624bc36 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -27,17 +27,17 @@ class CompileUnit 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::vector functions; - std::vector externs; + 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::map functions; + std::map externs; }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index c82dc4d..e6d8e1f 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -16,15 +16,8 @@ CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, std::vector &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; } @@ -36,9 +29,18 @@ CallExprAST::~CallExprAST() llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Function *CalleeF = unit->module->getFunction(callee); + std::vector argStr; + for (ExprAST *ast : args) { + argStr.push_back(ast->type); + } + std::string dname = demangle(callee, argStr); + if (callee == "main") { + dname = "main"; + } + + llvm::Function *CalleeF = unit->module->getFunction(dname); if (CalleeF == 0) { - CompileError e("Function " + callee + " not found"); + CompileError e("Function " + dname + " not found"); throw e; } std::vector argsV; diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 363831c..7d33e12 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -34,6 +34,7 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) throw e; } } + unit->next_tok(); PrototypeAST *proto = PrototypeAST::ParsePrototype(unit, false); if (S) { proto->returnDirectly = true; @@ -50,6 +51,8 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) 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 aa47819..6549d76 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 932dabf..e842966 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -52,3 +52,4 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) CodeBlockAST::ParseCodeBlock(unit, "entry", nullptr, namedValues); 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 7e68aaf..ea78823 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/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index c3559e7..6024b6d 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -22,6 +22,15 @@ PrototypeAST::PrototypeAST( 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() @@ -32,8 +41,7 @@ PrototypeAST::~PrototypeAST() PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) { std::vector> args; - std::vector argStr; - Token token = unit->next_tok(); // identifier. + Token token = unit->next_tok(); if (token.type != tok_identifier) { std::cerr << "error1" << std::endl; // TODO:异常处理 @@ -72,12 +80,7 @@ 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->icurTok + 1); // -> or ; or { std::vector returnTypes; if (token.type == tok_return_type) { @@ -103,6 +106,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } } if (token.type == tok_identifier) { + unit->next_tok(); returnTypes.push_back(token.tokenValue); } } @@ -140,11 +144,30 @@ llvm::Function *PrototypeAST::Codegen() } llvmArgs.push_back(typeAST->second->Codegen()); } - llvm::FunctionType *FT = llvm::FunctionType::get( - llvm::Type::getVoidTy(*unit->context), llvmArgs, false); + 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 { + auto typeAST = unit->types.find(returnTypes[0]); + if (typeAST == unit->types.end()) { + CompileError e("can't find type:" + returnTypes[0]); + throw e; + } + returnType = typeAST->second->Codegen(); + } + + } else { + returnType = llvm::Type::getVoidTy(*unit->context); + } + 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. diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index bd7f30a..fa5e2d4 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -20,9 +20,12 @@ class PrototypeAST : public BaseAST llvm::Function * Codegen(); static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody); std::vector> args; - std::vector returnTypes; - std::string name; - bool returnDirectly; //直接返回 + + std::string demangledName; + + std::vector returnTypes; + std::string name; + bool returnDirectly; //直接返回 }; #endif /* COMPILER_AST_PROTOTYPEAST_H_ */ -- Gitee From 3cc29472268db586ce3578653a8ef231f66fa662 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 21:03:26 +0800 Subject: [PATCH 07/98] test --- test/demoa+b.alo.bc | Bin 1236 -> 1260 bytes test/demoa+b.alo.ll | 2 +- test/demoa+b.alo.s | 2 +- test/loop.alo.bc | Bin 1188 -> 1212 bytes test/loop.alo.ll | 2 +- test/loop.alo.s | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/demoa+b.alo.bc b/test/demoa+b.alo.bc index 6c8af1b2dbe4bfa2c9c82bf5b6ac876b72dd0172..9fb8baeb678dbd831119122818694ac369efec5e 100644 GIT binary patch delta 96 zcmcb@`G#|X3ZukC)ukdneCpF*yXv2Rsb947FW>qj>kNL|PP}Bv_;fQ5V;ZyAe?|r< qh~;5m5C^h_n5V3r+`(cerKhJ~l3HA%pOTuJpQxRrmza|eRSE!0LL9LG delta 72 zcmaFEd4+R=3Zv*m)ukLfl|C&dKTjJ?yl2UHcC!Ry8nf6RMg}N|Due2UXwyXv2RssHUaZ+Yv@_llw$I2{-eK-yr*Ee<9GpCN%+ z#f(E_D+dEZ$5Ej0W@g54X0hLlFcq;p3=D!mju7*d(#ZuZn&NtT`X#BwCHgt}`2~83 IIr&h90L@7qc>n+a delta 109 zcmdnPxrB3q3M2nS)s?0^l|C&dKTjJiVKQUnV1R=J=C%-NM>rSA$Z0sj*0@NRk%3{O o#AbfRaAvU|KsE%#@-Q&)0hvO~Q*tKPuxN6Zq!yRx<>Y{50rF%OLjV8( diff --git a/test/loop.alo.ll b/test/loop.alo.ll index 604d369..2e0042b 100644 --- a/test/loop.alo.ll +++ b/test/loop.alo.ll @@ -1,5 +1,5 @@ ; ModuleID = './../test/loop.alo.bc' -source_filename = "test.ll" +source_filename = "../test/loop.alo" declare void @_alolang_12testPrintInt3int(i64) diff --git a/test/loop.alo.s b/test/loop.alo.s index f86a01c..5b00b9c 100644 --- a/test/loop.alo.s +++ b/test/loop.alo.s @@ -1,5 +1,5 @@ .text - .file "test.ll" + .file "loop.alo" .globl main # -- Begin function main .p2align 4, 0x90 .type main,@function -- Gitee From 54d276bae3ef9ef8559f54d003f63b05eb57c679 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 20 Feb 2021 21:08:19 +0800 Subject: [PATCH 08/98] Fix a bug and delete junk file --- .gitignore | 6 +++- src/CompileUnit.cpp | 8 +++--- src/ast/BinaryExprAST.cpp | 3 +- test/demo.alo.bc | Bin 1320 -> 0 bytes test/demo.alo.ll | 26 ----------------- test/demo.alo.s | 51 --------------------------------- test/demoa+b.alo.bc | Bin 1260 -> 0 bytes test/demoa+b.alo.ll | 25 ---------------- test/demoa+b.alo.s | 23 --------------- test/loop.alo.bc | Bin 1212 -> 0 bytes test/loop.alo.ll | 25 ---------------- test/loop.alo.s | 29 ------------------- test/module | Bin 1316 -> 0 bytes test/module.ll | 24 ---------------- test/module.s | 58 -------------------------------------- test/recursion.alo.bc | Bin 1288 -> 0 bytes test/recursion.alo.ll | 32 --------------------- test/recursion.alo.s | 46 ------------------------------ test/test03.alo.ac | 0 test/wrongstr.alo.bc | Bin 988 -> 0 bytes test/wrongstr.alo.ll | 2 -- test/wrongstr.alo.s | 3 -- 22 files changed, 11 insertions(+), 350 deletions(-) delete mode 100644 test/demo.alo.bc delete mode 100644 test/demo.alo.ll delete mode 100644 test/demo.alo.s delete mode 100644 test/demoa+b.alo.bc delete mode 100644 test/demoa+b.alo.ll delete mode 100644 test/demoa+b.alo.s delete mode 100644 test/loop.alo.bc delete mode 100644 test/loop.alo.ll delete mode 100644 test/loop.alo.s delete mode 100644 test/module delete mode 100644 test/module.ll delete mode 100644 test/module.s delete mode 100644 test/recursion.alo.bc delete mode 100644 test/recursion.alo.ll delete mode 100644 test/recursion.alo.s delete mode 100644 test/test03.alo.ac delete mode 100644 test/wrongstr.alo.bc delete mode 100644 test/wrongstr.alo.ll delete mode 100644 test/wrongstr.alo.s diff --git a/.gitignore b/.gitignore index af9520e..1114709 100644 --- a/.gitignore +++ b/.gitignore @@ -128,4 +128,8 @@ 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 \ No newline at end of file diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index ff557e5..d603db1 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -121,13 +121,13 @@ void CompileUnit::compile() } } while (next_tok().type != tok_eof); std::cout << "Start codegen:" << name << std::endl; - std::map::reverse_iterator extern_iter; - for (extern_iter = externs.rbegin(); extern_iter != externs.rend(); + std::map::iterator extern_iter; + for (extern_iter = externs.begin(); extern_iter != externs.end(); extern_iter++) { extern_iter->second->Codegen(); } - std::map::reverse_iterator function_iter; - for (function_iter = functions.rbegin(); function_iter != functions.rend(); + std::map::iterator function_iter; + for (function_iter = functions.begin(); function_iter != functions.end(); function_iter++) { function_iter->second->Codegen(); } diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index b686345..02b5b07 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -15,7 +15,8 @@ BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, this->binOP = binOP; this->LHS = LHS; this->RHS = RHS; - this->type = LHS->type; + // todo:类型检查 + this->type = LHS->type; } BinaryExprAST::~BinaryExprAST() diff --git a/test/demo.alo.bc b/test/demo.alo.bc deleted file mode 100644 index ffd4e6f941f3c13189aea70f4c68225e07b58813..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1320 zcmZ8hUrbt87(e`xOO&2_tE2;aFS%E2LX5G1E(3uDxSO#n5194ACT#?#P8UlNnW8QW z2=&s9EY$kIgAbDU(q#{H;h_)BB3{=q#~Npv#cjq&K-(?Wkku_+)@(bMX|wDk_xsNG zo!|Y=_xrwcj+0&4c~uEO4FI5Dp>KZc@)tu_|IGH)^@Lp_7=+LB2%m6X6&!7*B zXm2_4(hD-eXr33v6z6K>YK`>c{;=Xrv2(u8IY1bdCb{Zjt zImjSnVFe!U!rxZlfnL&|Pm|>|S*XfwFS*W; zYY}SQEBijln)9qVRh9R6(*kRXODqfgd9>+^S<54dCBrMe8sYrCT)-a<4r3t?7gTY< zB~JbDZTt}6zq(;L2}^doNW%lfg4R*nInAm=v&oR#5zY24SuRq)h%`g09#e+xT#Q-@ z?&f169&R#(g;G7Pqa-d=K=Ynv-Ag`UsGS`3p-3Yn%up4t?9z>>slZz@tPK_9#j3T; zTH?s$6JORMrradTM~+SFus|wur9{Ak6}aby&-B{drbAOMzOq%Mc2EM{YD*?+%SO+} zcvFHk7kKNvoH@@Uj@CkVc1(_;tj16QdpY$_58#0Zf4VEH(Dv4y~*PX}dljcZkBYiYOTR z-GG+Mr0*nDN+6#V<&-CowPT3OcnoPcfiyQl;lc@T3FaogReI3`4KEFi;INl z(%Cr)O7#D@F@zKN86nXW6aOVL(JjaV;3|5jgtw_)vhbN;_jyOJk9vLY_L+i%<3acP s!SR0)XBFJ^H9rGC+y+gJ|KA z`m3#3)oBf7b4)8@+9PVhU{Zb36Q5p2DCaoW(&s{ZVvMBBqGXMvWwAB$WnR_p*YU&nZh!tY>?tBC1paOcDlt@%D_jyY$fCUohuN#{MxnU=KQ4v0dR z7!abtemvwAgL*MICmL?QOYQ;kcODj#uyBIRo8c}(VYV1ImQ5?Irn?Ni5ixCS(Z#&+ zSB1&1@3g16mf5H?$2YtH;uXh2cqrA`v7aR63Yb1Lt@`K(jB#_>__4wyC(Ia2KF!(7 zQF~5ura3n%$g>q!k#ok8DkW}KAf)0L%7?%wEO;OlIai?I?h@SQ;bXRb`EIMJm_M|h zH*TT?+6~Th)V&z3jY;+d=g3K}>&uR;gfO~t?Tf<%jhFrer3! zS#sM<{>j533Km$1)W=(zhg-17!zV14|CurF%+n=BIdk8sdp}8b)U34Bw9d8UxRyBA zf>5tNF}c+e_8r5(ojyaoqfFL>d7 z9+j3X$^|Cx^Kd^Mj^N{#a_2)L%38+VCCp0pMTK)A>Yl;S9d{@IG)Uq(*Fw}eiyDf# z=b|pu+@vJWfX@s-Es`~=)?;XEdA@aRe0A^$dh=DwoynDslY(x6t*N5buWD(qg`(g5mul2wHmKuUuioassEb%2H%D%D?{`#q;Pta|qe1v6;`20NuX9i-W$Q54x?kVBbiP4-5Hz>wA2$TnIV8=GWvQ*Ymei@w)-8c`rQAfkT&@7bKh diff --git a/test/demoa+b.alo.ll b/test/demoa+b.alo.ll deleted file mode 100644 index 3007a60..0000000 --- a/test/demoa+b.alo.ll +++ /dev/null @@ -1,25 +0,0 @@ -; ModuleID = './../test/demoa+b.alo.bc' -source_filename = "../test/demoa+b.alo" - -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 ff5b24f..0000000 --- a/test/demoa+b.alo.s +++ /dev/null @@ -1,23 +0,0 @@ - .text - .file "demoa+b.alo" - .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/loop.alo.bc b/test/loop.alo.bc deleted file mode 100644 index 663d09974596a0636c40247e2419d4b777a4fc43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1212 zcmXw3O-vg{6dtq2y8$!15I42M+S=tuLI~j>+Q!Cqg}qG#tq+UZ1CbJ8qtu0p!U8TB zQdKrKT}So7p-ALsS7vQWtGg5=9kB5yG+|NlU2J&?pi)bk;Oa+BY+A zX5M_?_h#11t?az31E3NBFrc+GeR%Pw;N|1x{_5U{PlaNv7Jxd`sjgr_1sb10A0BPI z?#ZcpG?dLTuZnA%D+z;1{p~=6I$z@?K*AfT*=K5T}?cbL!I#OL621@k~lr=Sw83 z<8dF=)(9rlH+VHMUkC1Ytx1m~f1Nk~_RRe9xMphZ(ckP_*;8F; z>W$S~mL3xdk2mJWn%*OHKN0{W?kKVE(APmk==D4u)T!JF&K{SN-UvP&#wXHa+I>Ji zr{GZpc4)n(wN>N23>~yomY2oqWz3!9+)2zWhm#=zze?cK-J&4iGXgdl76nE$$hGhw z1@jhi#6lKIu*Aa-YTdZQ(p#)?Eno^-t~qbVoSU3u8FSr^x#E~pF6k!y_|-xD+@Ls) zd_)vdqTt6TTky$Ol_>30MC>QTF}*mR7N^tEw!;!U+=c(Hzyk|5kjv1;3@w-ac7Wbs z>Gh~_BcS;`#W`}EBVG2lB>MtqPhidk$&3ztJ?ngkIkS@X=OIz(6UT*EXb=zk#gJYM z-4G4;J|+(V`410^DOl(t^9(#dESMJK_Nr;kV|u{S+fmc@E?vwU|5TZR`d)jM>s*XE zWxnZuB7SiyjEB>`zM~YWC}8^Bv=N}6vc{cN>BWUJzp=Q(t9kr{yskN-CR)=+Yk{2sHJqhao4;Vt@t=psuv)DH^i3UAr z9nhXr6K7=`;h~`N?vy-13gA5Tt1h4;n#BGpjh^vm3This Inner Loop Header: Depth=1 - movq (%rsp), %rdi - callq _alolang_12testPrintInt3int@PLT - movq (%rsp), %rax - incq %rax - movq %rax, (%rsp) - cmpq $10, %rax - jl .LBB0_1 -# %bb.2: - popq %rax - .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/module b/test/module deleted file mode 100644 index 3652e2bb98e105ca5b954fdb3381dd4958d191c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 zcmaJ>Ur1Y57(ds<+^eSNUN!3ydT+S5cEgF-Yud5IB*Wx(HtQTq*&ZCUED;qu+U}~E zMmr=i(VK2zL?~PL^ z&UemtzCXY3e8(-_+%dZ2K-?d zWVmk9mC?SfV=T5QBC3C-oHCiUUv!3;x60g8RqiNbF<2?%JCzo9%p)%gb*E~SIOCcs z>&j5`23~55@jnn2chuNW-;ikjEOl;@U(SHut2{!7V745kD)_E(ZSB!(Q6M|fxrCvn zJr=KuM%$Uj0j;ME-J)76CVIa_dg^oEX)A-!8Jen|YMqE1Du|PAFA2oYyJp3ALE&Kv&WpohPU=n7 z?TL8BtEX4AQswyiV;k2s`lBoV?cykY4b2-7`U>PuP$70X$MzTqXH2q2)wnxE4hPAB zWS@Q)(GM7W5W*+)Zu3%_yFJJDh~*`*$dRnZnUS1vjWZjJ2W0XJMGkuuStdth&0tWG zdBv2i#(N2z6Y0w$y;HyiFFwI6b6WztA#h86bB}n{ej{RElWYqb$Bl?1stegW@q$GHzY3$SLaWML9%)YL%r&Rs-7ZkZe>6asc zUNY!Y0!Ae;tC()TPwyl8p%>>9c&C-l@puoS;On`~w0X&8z9X=kVe{rTo6m8766PM` zS!+sanTgo5-edm+;!}o#WH5QQ{UAXX5ioyjUiGv01#TpmEdShK1< zB{>0*XG@N}WRC%>#&1rIg+7V|ulfMM4#o8Q3f}Y454Lp$p1v#6cX|4W z7hh)Zj);MMw5|JN8|S_FsVL=s6S&)QgQ<1Dap2`j_tB5bBFG`ice`*;GSb}_~ecc-}3^rbiN2M zeb0*zQlT(8Twlt3Pyw%tad*fws&#>|UyC@WHDKdsC;%PIWY%#lVxNJ8YMiqX2P8M4 zLS-R8|GaK%wXViutrYKc)uDjIg^_W>kLq;gXv`Nfh9@*c@ed)r%ufbCETH-M=QUKT zO~(i##2cA$kV2)u=Ktj)|0&l8`m~_ef|;XHVzSJN8baD{idGRi4}TeSRHKA@n!sTbBF) diff --git a/test/module.ll b/test/module.ll deleted file mode 100644 index 8eb4214..0000000 --- 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 2ec427b..0000000 --- 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/recursion.alo.bc b/test/recursion.alo.bc deleted file mode 100644 index 28a1a316d9bdb5f60fcabcb8dbbbe50153a247e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1288 zcmX|BK};J*6rE*_cN3i11+3IGYik!1$&CNJAx~CKfm0r|MAd~n z{k55wPNewn2xmaC9C94Ww0@F1cavYrL*5%aLKv*Gk>0~!xNfL#oK-+=Dl-{#T~{hy zqbOZ$vmISFOa~40L>;={G0zc}V4>D<8kV8g1=DDka^$b?owHTP2wD&AN{Adk^Ip>{ zPq%~fna}spI-pk)BAbrUX5Su!QgdLg_fdc8vOTIMeE5y>#Fm;WlMmyDTn7SG!M`CK2R~rho zcsqlOA~Pg1n`K-M;x=~4x-M|5f^|{0^@}$=x09X~$vsDUZzsJ9=_!=WBO&VACF;#f zY6Ns#4QJGFh#GNFBQL5U?UlINORK{cHIh|Fvx(-NGTzz1f6U`;k?hOQaHScpP|<5L zcURz+64tx2@yCqh&P(oWMc>j~laeb%dM35Qu<6S&&qLCa(@ftEsNo(p5>7@hQL&I3 zwW!f)wc*}rW(P692XQHbH#?XjkGBB@@35{d*cSb^2LiX2u&r%yrK0sW!q#u;cIBk@ zsidb6Z2AvKNWBuHV%hGl=NU$4!1kf-uFO3Vtm_Nb&j_1duwX6A#xvKGu7c*tNj@Ot z<)XJFc~anN={tJ?sd@$Kp{c75Dw0i{+hp)yJtegR>J{lN^pypn z1~^kSdm|3$6?L^IoRxe)c}{Y#Xk%O4^31*`e*GwI3D#W>_8-{{;m1LsmMQ53GmnG# zc`lxyMje&T$5g0V$K4a2(p+&HEJ8-GRKYu&^h`lRN#AtR3(d`F`kj_} zgbskMH%QGewQ{e`$GfYd2jR@uF36e198qf~JN)V5_;g3|tWlsR$1QeaH5v=?%|vZ$ ziz~Dm7sm+RzMS$Cao$3|E1qH%5|SGr-!T?ZLG}l;Ji?=+;OipufE{eT!C%=^ufuGI zw`Di0DKSnG`gPo02p=HBJVH7iCuSQJ;vd2>{e~V!=iyDN2U|x@eyaPu^5DmV^3Vsp ut diff --git a/test/recursion.alo.ll b/test/recursion.alo.ll deleted file mode 100644 index 60cd691..0000000 --- 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 53fd500..0000000 --- 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 e69de29..0000000 diff --git a/test/wrongstr.alo.bc b/test/wrongstr.alo.bc deleted file mode 100644 index bd350e341430fe6471df36b079fafc8b616f428b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 988 zcmXX_Uuara7(eD3uZ#9vC(`M9@8#Yk11TlFF&$H{j_Tct+k7x=4;i#nLnqlNs)pzSt%piLQphmH*AnK8y)Mzj&29;_wk)` z?m53d-w8?^`)}F+7zO~$nuYQAKmI0u>7UwV({whh!*jeDfCHROLp&J5`6T|x+}Q0v zL;s$^;_@u(^5!>&jSg1-q6dbp>Y;L3dgAtdt5R$j}v3IPfXbCJ2U1=Ea z+BoS#f%{(PvgYllou^BapI0y5=IRZ6?kx_0S8#TXhK$^moBBK4dLD;%zEZMT!%Ia| zemrc^6Mb0Vb>5r_=g+E-ox&Yv;d!ShqbEWOpD<2IeYAi48uF_6R36%_9Ae~vc>H4^e)eA#@M)UOT4d$JCdhH`0gvdJRxd5+kBL~F-N{N zhmtsEkz7J@l$>{x^Dl<+u?tyr*@zN$lq{o6Id|r$2alTY&kfiWh}lMk?o?=P5cgvA zHcxNmnC+P1r;_ApNS^W_-c#KxlDj~NE9zN%>B}YYF(Fn}^LL*jc?KnAB{fH;qbOxZ zsWs$y_#t%!s6QgGQ-baDREvXM%z|?=dv$g*z&_&Xy&SvOq&qFwX*yOLLvyamaNS?@@1gRkuXIB-vyMv_kK z6}dPgmnA=zyefHi)TKlELFL5LK);m^dFDS2PM&K=;gblKmg@8crk+ILaW$JGGtPnY zX@pVtdC$nJs=KBW*A@Q?f$#Xy0)PQ$QuD1V;wm Date: Sat, 20 Feb 2021 21:17:17 +0800 Subject: [PATCH 09/98] Add VariableDefExprAST --- src/Makefile.am | 2 +- src/ast/VariableDefExprAST.cpp | 87 ++++++++++++++++++++++++++++++++++ src/ast/VariableDefExprAST.h | 29 ++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/ast/VariableDefExprAST.cpp create mode 100644 src/ast/VariableDefExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index 4193a27..ff83e9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ 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/TypeAST.cpp ast/VariableDefExprAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp yacc_stuff/tokenizer.lpp AM_LFLAGS = -o lex.yy.c diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp new file mode 100644 index 0000000..d5e0684 --- /dev/null +++ b/src/ast/VariableDefExprAST.cpp @@ -0,0 +1,87 @@ +/* + * 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 + +VariableDefExprAST::VariableDefExprAST(CompileUnit * unit, + const std::string &idName, + const std::string &type, + ExprAST *initValue, int argID) + : ExprAST(unit) +{ + this->idName = idName; + this->type = type; + this->alloca = nullptr; + this->initValue = initValue; + this->argID = argID; +} + +VariableDefExprAST::~VariableDefExprAST() +{ + // TODO Auto-generated destructor stub +} + +static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, + llvm::Function * function, + const std::string &VarName, + const std::string &type) +{ + 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; + } + + return builder.CreateAlloca(typeAST->second->Codegen(), 0, VarName.c_str()); +} + +llvm::Value *VariableDefExprAST::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); + } + } + return builder->CreateLoad(alloca); +} + +VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, + CodeBlockAST *codeblock, + std::string idName, + std::string type) +{ + 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 VariableDefExprAST(unit, idName, type, initValue); +} diff --git a/src/ast/VariableDefExprAST.h b/src/ast/VariableDefExprAST.h new file mode 100644 index 0000000..3c8f0b6 --- /dev/null +++ b/src/ast/VariableDefExprAST.h @@ -0,0 +1,29 @@ +/* + * 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, const std::string &idName, + const std::string &type, ExprAST *initValue, + int argID = -1); + virtual ~VariableDefExprAST(); + static VariableDefExprAST *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 +}; + +#endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ -- Gitee From 5b8a3105459ce8b83d733992f1e421245f177195 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 21:23:08 +0800 Subject: [PATCH 10/98] Update VSC Ext --- .../vscode/alolang/CHANGELOG.md | 24 ++++++++++++++++-- .../vscode/alolang/README.md | 4 +++ .../vscode/alolang/alolang-0.0.4.vsix | Bin 0 -> 5253 bytes .../vscode/alolang/package.json | 2 +- .../alolang/syntaxes/alolang.tmLanguage.json | 7 +++-- test/demoa+b.alo | 7 ++++- 6 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 syntax_highlight_plugin/vscode/alolang/alolang-0.0.4.vsix diff --git a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md index 351a4da..2b0ebab 100644 --- a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md +++ b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md @@ -4,9 +4,29 @@ 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.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 d8cad16..181dce0 100644 --- a/syntax_highlight_plugin/vscode/alolang/README.md +++ b/syntax_highlight_plugin/vscode/alolang/README.md @@ -31,6 +31,10 @@ Waiting to be reported. ## Release Notes +### 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 GIT binary patch literal 5253 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 literal 0 HcmV?d00001 diff --git a/syntax_highlight_plugin/vscode/alolang/package.json b/syntax_highlight_plugin/vscode/alolang/package.json index 586e2c7..573ad7d 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.4", "publisher": "AloLangDevTeam", "license": "GPLv3", "repository": { diff --git a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json index c6bf749..44f41a9 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" } } diff --git a/test/demoa+b.alo b/test/demoa+b.alo index c99fc12..3ceb74e 100644 --- a/test/demoa+b.alo +++ b/test/demoa+b.alo @@ -1,5 +1,5 @@ extern func testPrintInt(int i); -extern func testGetInt(); +extern "S" func testGetInt() -> int; func main() { @@ -11,4 +11,9 @@ func main() c = a + b; testPrintInt(c); + + a = testGetInt(); + b = testGetInt(); + c = a + b; + testPrintInt(c); } \ No newline at end of file -- Gitee From e23139e48acec2c9aa6a5b7379874f68410404d1 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 20 Feb 2021 22:01:51 +0800 Subject: [PATCH 11/98] Tested function override --- test/override.alo | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/override.alo diff --git a/test/override.alo b/test/override.alo new file mode 100644 index 0000000..1516221 --- /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 -- Gitee From 42afa08b24092032f4577aa0a5d937d1681e034a Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 20 Feb 2021 22:14:57 +0800 Subject: [PATCH 12/98] Rebuild Variable System --- src/ast/AssignmentAST.cpp | 18 ++------- src/ast/CallExprAST.cpp | 17 +++------ src/ast/CodeBlockAST.cpp | 14 ++++--- src/ast/CodeBlockAST.h | 21 +++++----- src/ast/ExprAST.cpp | 27 ++++++------- src/ast/FunctionAST.cpp | 10 ++--- src/ast/VariableDefExprAST.cpp | 28 ++++++++------ src/ast/VariableDefExprAST.h | 9 +++-- src/ast/VariableExprAST.cpp | 70 +++++++++------------------------- src/ast/VariableExprAST.h | 19 +++++---- 10 files changed, 95 insertions(+), 138 deletions(-) diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index bb278ee..0c1cbbe 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -29,24 +29,14 @@ AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, { 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; + return new AssignmentAST(unit, new VariableExprAST(unit, codeblock, LHS), + ExprAST::ParseExpression(unit, codeblock, false)); } llvm::Value *AssignmentAST::Codegen(llvm::IRBuilder<> *builder) { llvm::Value *value = RHS->Codegen(builder); - builder->CreateStore(value, LHS->alloca); // todo:对函数参数赋值 + + builder->CreateStore(value, LHS->getAlloca()); // todo:对函数参数赋值 return value; } diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index e6d8e1f..5d9f1cb 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -29,6 +29,12 @@ CallExprAST::~CallExprAST() llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) { + std::vector argsV; + + for (unsigned i = 0, e = args.size(); i != e; ++i) { + argsV.push_back(args[i]->Codegen(builder)); + } + std::vector argStr; for (ExprAST *ast : args) { argStr.push_back(ast->type); @@ -43,17 +49,6 @@ llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Function " + dname + " not found"); throw e; } - std::vector argsV; - - // If argument mismatch error. - if (CalleeF->arg_size() != args.size()) { - CompileError e("Incorrect arguments passed"); - throw e; - } - - for (unsigned i = 0, e = args.size(); i != e; ++i) { - argsV.push_back(args[i]->Codegen(builder)); - } return builder->CreateCall(CalleeF, argsV); } diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index d9763e5..2fdc341 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,18 +26,21 @@ 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 + 1); if (token.type == tok_syntax && token.tokenValue == "{") { unit->next_tok(); CodeBlockAST *codeblock = new CodeBlockAST(unit, std::vector(), name, parent); - codeblock->namedValues = namedValues; std::vector &body = codeblock->body; - + for (VariableDefExprAST *argDef : args) { + argDef->codeblock = codeblock; + body.push_back(argDef); + } while (true) { Token inBlockToken = *(unit->icurTok + 1); if (inBlockToken.type == tok_eof) { diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 0d976ef..51260b8 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/ExprAST.cpp b/src/ast/ExprAST.cpp index e59797f..5a9c546 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -8,6 +8,7 @@ #include "CodeBlockAST.h" #include "IfExprAST.h" #include "IntExprAST.h" +#include "VariableDefExprAST.h" #include "VariableExprAST.h" #include "WhileExprAST.h" #include @@ -48,12 +49,14 @@ ExprAST::~ExprAST() ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) { // todo:除了函数调用之外的语句解析 - Token token = unit->next_tok(); + Token token = *(unit->icurTok + 1); switch (token.type) { case tok_number: { + token = unit->next_tok(); return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); } case tok_key_literal: { + token = unit->next_tok(); if (token.tokenValue == "true") { return new BoolExprAST(unit, true); } else { @@ -62,12 +65,15 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) break; } case tok_key_if: { + token = unit->next_tok(); return IfExprAST::ParseIfExpr(unit, codeblock); } case tok_key_while: { + token = unit->next_tok(); return WhileExprAST::ParseWhileExpr(unit, codeblock); } case tok_syntax: { + token = unit->next_tok(); if (token.tokenValue == "(") { ExprAST *result = ParseExpression(unit, codeblock, false); token = unit->next_tok(); @@ -82,6 +88,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) break; } case tok_identifier: { + token = unit->next_tok(); //函数调用或定义 std::string idName = token.tokenValue; token = *(unit->icurTok + 1); @@ -89,10 +96,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) //定义 std::string valName = token.tokenValue; unit->next_tok(); - VariableExprAST *varAST = - VariableExprAST::ParseVar(unit, codeblock, valName, idName); - codeblock->namedValues.insert( - std::pair(valName, varAST)); + VariableDefExprAST *varAST = + VariableDefExprAST::ParseVar(unit, codeblock, valName, idName); return varAST; } else if (token.tokenValue == "=") { //赋值 @@ -123,17 +128,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) 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; - } - } - CompileError e("can't find variable:" + idName); - throw e; + return new VariableExprAST(unit, codeblock, idName); } break; } diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index e842966..d3c0e86 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,15 +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))); + 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/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index d5e0684..7311d54 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -12,13 +12,16 @@ #include "IntExprAST.h" #include "TypeAST.h" #include +#include VariableDefExprAST::VariableDefExprAST(CompileUnit * unit, + CodeBlockAST * codeblock, const std::string &idName, const std::string &type, ExprAST *initValue, int argID) : ExprAST(unit) { + this->codeblock = codeblock; this->idName = idName; this->type = type; this->alloca = nullptr; @@ -49,18 +52,19 @@ static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, llvm::Value *VariableDefExprAST::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); - } + 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); } - return builder->CreateLoad(alloca); + codeblock->namedValues.insert( + std::pair>( + idName, std::pair(type, alloca))); + return nullptr; } VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, @@ -83,5 +87,5 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, throw e; } } - return new VariableDefExprAST(unit, idName, type, initValue); + return new VariableDefExprAST(unit, codeblock, idName, type, initValue); } diff --git a/src/ast/VariableDefExprAST.h b/src/ast/VariableDefExprAST.h index 3c8f0b6..e1b0e2e 100644 --- a/src/ast/VariableDefExprAST.h +++ b/src/ast/VariableDefExprAST.h @@ -12,16 +12,17 @@ class VariableDefExprAST : public ExprAST { public: - VariableDefExprAST(CompileUnit *unit, const std::string &idName, - const std::string &type, ExprAST *initValue, - int argID = -1); + VariableDefExprAST(CompileUnit *unit, CodeBlockAST *codeblock, + const std::string &idName, const std::string &type, + ExprAST *initValue, int argID = -1); virtual ~VariableDefExprAST(); static VariableDefExprAST *ParseVar(CompileUnit * unit, CodeBlockAST *codeblock, std::string idName, std::string type); llvm::Value * Codegen(llvm::IRBuilder<> *builder); + CodeBlockAST * codeblock; std::string idName; - llvm::Value * alloca; + llvm::AllocaInst * alloca; ExprAST * initValue; int argID; //函数的参数号,函数内变量为-1 }; diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index c94c511..945906c 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,27 @@ 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::AllocaInst *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 = varAST->second.first; + return alloca; } } - return builder->CreateLoad(alloca); + CompileError e("can't find variable:" + idName); + throw e; } -VariableExprAST *VariableExprAST::ParseVar(CompileUnit * unit, - CodeBlockAST *codeblock, - std::string idName, std::string type) +llvm::Value *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); + return builder->CreateLoad(getAlloca()); } diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index 0356ad8..273df80 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::AllocaInst *getAlloca(); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + std::string idName; + CodeBlockAST * codeblock; + + private: + llvm::AllocaInst *alloca; }; #endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ -- Gitee From 45789b5264c5ec19aa72fe235115c184c69a66c7 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 08:30:51 +0800 Subject: [PATCH 13/98] Rebuild typeAST --- src/CompileUnit.cpp | 10 +++++---- src/CompileUnit.h | 2 +- src/ast/PrototypeAST.cpp | 16 ++++---------- src/ast/TypeAST.cpp | 39 ++++++++++++++++++++++------------ src/ast/TypeAST.h | 1 + src/ast/VariableDefExprAST.cpp | 9 ++------ 6 files changed, 39 insertions(+), 38 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index d603db1..fd497f4 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -24,10 +24,12 @@ 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) diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 624bc36..9c3b679 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -35,9 +35,9 @@ class CompileUnit llvm::Module * module; std::vector tokenList; std::vector::iterator icurTok; - std::map types; std::map functions; std::map externs; + std::map types; // Codgen用 }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 6024b6d..af379d4 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -137,12 +137,8 @@ llvm::Function *PrototypeAST::Codegen() */ 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); - throw e; - } - llvmArgs.push_back(typeAST->second->Codegen()); + TypeAST *typeAST = new TypeAST(unit, args[i].first); + llvmArgs.push_back(typeAST->Codegen()); } llvm::Type *returnType; if (returnDirectly) { @@ -152,12 +148,8 @@ llvm::Function *PrototypeAST::Codegen() } else if (returnTypes.size() == 0) { returnType = llvm::Type::getVoidTy(*unit->context); } else { - auto typeAST = unit->types.find(returnTypes[0]); - if (typeAST == unit->types.end()) { - CompileError e("can't find type:" + returnTypes[0]); - throw e; - } - returnType = typeAST->second->Codegen(); + TypeAST *typeAST = new TypeAST(unit, returnTypes[0]); + returnType = typeAST->Codegen(); } } else { diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index ab55cee..697cbab 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -6,6 +6,7 @@ */ #include "TypeAST.h" +#include "../CompileError.hpp" #include "CompileUnit.h" TypeAST::TypeAST(CompileUnit *unit, std::string name) : BaseAST(unit) @@ -19,19 +20,29 @@ 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); - } 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_S; + auto typeAST = unit->types.find(name); + if (typeAST == unit->types.end()) { + CompileError e("can't find type:" + name); + throw e; } + return typeAST->second; + /* + //用户定义的类型 + llvm::StructType *llvm_S = + llvm::StructType::create(*unit->context, name); + std::vector members; + for (TypeAST *member : innerType) { + members.push_back(member->Codegen()); + } + return llvm_S;*/ +} + +TypeAST *TypeAST::ParseType(CompileUnit *unit) +{ + Token token = unit->next_tok(); + if (token.type != tok_identifier) { + CompileError e("Expected type but got " + token.dump()); + throw e; + } + return nullptr; } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 111f128..f578728 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -15,6 +15,7 @@ class TypeAST : public BaseAST public: TypeAST(CompileUnit *unit, std::string name); virtual ~TypeAST(); + TypeAST * ParseType(CompileUnit *unit); llvm::Type * Codegen(); std::string name; std::vector innerType; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index 7311d54..4b4bb99 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -41,13 +41,8 @@ static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, { 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; - } - - return builder.CreateAlloca(typeAST->second->Codegen(), 0, VarName.c_str()); + TypeAST * typeAST = new TypeAST(unit, type); + return builder.CreateAlloca(typeAST->Codegen(), 0, VarName.c_str()); } llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) -- Gitee From 86fa40e0d70f51a6a1cc2a1a84ebf7c6ecb91ea5 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 09:04:35 +0800 Subject: [PATCH 14/98] Rebuild type system --- src/ast/BoolExprAST.cpp | 3 ++- src/ast/CallExprAST.cpp | 28 +++++++++++++++++++++++-- src/ast/CodeBlockAST.h | 2 +- src/ast/ExprAST.cpp | 10 ++++----- src/ast/ExprAST.h | 2 +- src/ast/FunctionAST.cpp | 2 +- src/ast/IntExprAST.cpp | 3 ++- src/ast/PrototypeAST.cpp | 37 ++++++++++++++++------------------ src/ast/PrototypeAST.h | 12 +++++------ src/ast/TypeAST.cpp | 2 +- src/ast/TypeAST.h | 2 +- src/ast/VariableDefExprAST.cpp | 31 ++++++++++++++-------------- src/ast/VariableDefExprAST.h | 5 ++--- src/utils.cpp | 15 +++++--------- src/utils.h | 5 +++-- 15 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/ast/BoolExprAST.cpp b/src/ast/BoolExprAST.cpp index e0037e5..480ad56 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 = new TypeAST(unit, "bool"); } BoolExprAST::~BoolExprAST() diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 5d9f1cb..058d395 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -7,6 +7,8 @@ #include "CallExprAST.h" #include "../CompileError.hpp" +#include "ExternAST.h" +#include "FunctionAST.h" #include @@ -35,18 +37,40 @@ llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) argsV.push_back(args[i]->Codegen(builder)); } - std::vector argStr; + std::vector argStr; for (ExprAST *ast : args) { + if (ast->type == nullptr) { + CompileError e("Void type found."); + throw e; + } argStr.push_back(ast->type); } std::string dname = demangle(callee, argStr); if (callee == "main") { dname = "main"; } + PrototypeAST *proto = nullptr; + 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; + } + if (proto->returnDirectly) { + type = proto->returnTypes[0]; + } llvm::Function *CalleeF = unit->module->getFunction(dname); if (CalleeF == 0) { - CompileError e("Function " + dname + " not found"); + CompileError e("Function " + dname + " not found in LLVM IR"); throw e; } diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 51260b8..0b06686 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -29,7 +29,7 @@ class CodeBlockAST : public BaseAST llvm::IRBuilder<> * builder; std::vector body; - std::map> + std::map> namedValues; // Codegen阶段用 std::string name; CodeBlockAST * parent; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 5a9c546..68d949e 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -88,21 +88,20 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) break; } case tok_identifier: { - token = unit->next_tok(); //函数调用或定义 std::string idName = token.tokenValue; - token = *(unit->icurTok + 1); + token = *(unit->icurTok + 2); if (token.type == tok_identifier) { //定义 - std::string valName = token.tokenValue; - unit->next_tok(); VariableDefExprAST *varAST = - VariableDefExprAST::ParseVar(unit, codeblock, valName, idName); + VariableDefExprAST::ParseVar(unit, codeblock); return varAST; } else if (token.tokenValue == "=") { + token = unit->next_tok(); //赋值 return AssignmentAST::ParseAssignment(unit, codeblock, idName); } else if (token.tokenValue == "(") { + token = unit->next_tok(); //函数调用 unit->next_tok(); std::vector args; @@ -127,6 +126,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return new CallExprAST(unit, idName, args); } else { + token = unit->next_tok(); //变量 return new VariableExprAST(unit, codeblock, idName); } diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index 3bf5b6d..4d54643 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -13,7 +13,7 @@ class ExprAST : public BaseAST static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock); - std::string type; + TypeAST * type; }; #endif /* COMPILER_AST_ASTEXPR_H_ */ diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index d3c0e86..8d70a59 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -44,7 +44,7 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) << "Function definition found:" << protoType->name << std::endl; std::vector args; for (unsigned int i = 0; i < protoType->args.size(); i++) { - std::pair arg = protoType->args[i]; + std::pair arg = protoType->args[i]; args.push_back(new VariableDefExprAST(unit, nullptr, arg.second, arg.first, nullptr, i)); } diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 2f14ef5..3e1b3b0 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -6,13 +6,14 @@ */ #include "IntExprAST.h" +#include "TypeAST.h" #include #include IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) { this->val = val; - this->type = "int"; + this->type = new TypeAST(unit, "int"); } IntExprAST::~IntExprAST() diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index af379d4..9d2324d 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -14,16 +14,16 @@ PrototypeAST::PrototypeAST( CompileUnit *unit, const std::string &name, - const std::vector> &args, - const std::vector & returnTypes) + const std::vector> &args, + const std::vector & returnTypes) : BaseAST(unit) { this->name = name; this->args = args; this->returnDirectly = false; this->returnTypes = returnTypes; - std::vector argStr; - for (std::pair pair : args) { + std::vector argStr; + for (std::pair pair : args) { argStr.push_back(pair.first); } if (name != "main") { @@ -40,8 +40,8 @@ PrototypeAST::~PrototypeAST() PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) { - std::vector> args; - Token token = unit->next_tok(); + std::vector> args; + Token token = unit->next_tok(); if (token.type != tok_identifier) { std::cerr << "error1" << std::endl; // TODO:异常处理 @@ -60,18 +60,20 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) token = unit->next_tok(); // ). break; } - token = unit->next_tok(); + token = *(unit->icurTok + 1); if (token.type == tok_syntax && token.tokenValue == ",") { + token = unit->next_tok(); 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->next_tok(); + std::string name = token.tokenValue; + std::pair pair; pair.first = type; pair.second = name; args.push_back(pair); @@ -82,7 +84,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } token = *(unit->icurTok + 1); // -> or ; or { - std::vector returnTypes; + std::vector returnTypes; if (token.type == tok_return_type) { unit->next_tok(); int bc = 0; @@ -105,10 +107,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) break; } } - if (token.type == tok_identifier) { - unit->next_tok(); - returnTypes.push_back(token.tokenValue); - } + returnTypes.push_back(TypeAST::ParseType(unit)); } } else { if (token.tokenValue == "{") { @@ -137,8 +136,7 @@ llvm::Function *PrototypeAST::Codegen() */ std::vector llvmArgs; for (int i = 0; i < args.size(); i++) { - TypeAST *typeAST = new TypeAST(unit, args[i].first); - llvmArgs.push_back(typeAST->Codegen()); + llvmArgs.push_back(args[i].first->Codegen()); } llvm::Type *returnType; if (returnDirectly) { @@ -148,8 +146,7 @@ llvm::Function *PrototypeAST::Codegen() } else if (returnTypes.size() == 0) { returnType = llvm::Type::getVoidTy(*unit->context); } else { - TypeAST *typeAST = new TypeAST(unit, returnTypes[0]); - returnType = typeAST->Codegen(); + returnType = returnTypes[0]->Codegen(); } } else { diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index fa5e2d4..886d3f7 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -14,18 +14,18 @@ class PrototypeAST : public BaseAST { public: PrototypeAST(CompileUnit *unit, const std::string &name, - const std::vector> &args, - const std::vector &returnTypes); + const std::vector> &args, + const std::vector &returnTypes); virtual ~PrototypeAST(); llvm::Function * Codegen(); static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody); - std::vector> args; + std::vector> args; std::string demangledName; - std::vector returnTypes; - std::string name; - bool returnDirectly; //直接返回 + std::vector returnTypes; + std::string name; + bool returnDirectly; //直接返回 }; #endif /* COMPILER_AST_PROTOTYPEAST_H_ */ diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 697cbab..ff6796d 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -44,5 +44,5 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) CompileError e("Expected type but got " + token.dump()); throw e; } - return nullptr; + return new TypeAST(unit, token.tokenValue); } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index f578728..389869c 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -15,7 +15,7 @@ class TypeAST : public BaseAST public: TypeAST(CompileUnit *unit, std::string name); virtual ~TypeAST(); - TypeAST * ParseType(CompileUnit *unit); + static TypeAST * ParseType(CompileUnit *unit); llvm::Type * Codegen(); std::string name; std::vector innerType; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index 4b4bb99..d750f33 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -16,8 +16,7 @@ VariableDefExprAST::VariableDefExprAST(CompileUnit * unit, CodeBlockAST * codeblock, - const std::string &idName, - const std::string &type, + const std::string &idName, TypeAST *type, ExprAST *initValue, int argID) : ExprAST(unit) { @@ -37,11 +36,10 @@ VariableDefExprAST::~VariableDefExprAST() static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, llvm::Function * function, const std::string &VarName, - const std::string &type) + TypeAST * typeAST) { llvm::IRBuilder<> builder(&function->getEntryBlock(), function->getEntryBlock().begin()); - TypeAST * typeAST = new TypeAST(unit, type); return builder.CreateAlloca(typeAST->Codegen(), 0, VarName.c_str()); } @@ -57,21 +55,20 @@ llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) builder->CreateStore(initValue->Codegen(builder), alloca); } codeblock->namedValues.insert( - std::pair>( - idName, std::pair(type, alloca))); + std::pair>( + idName, std::pair(type, alloca))); return nullptr; } VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, - CodeBlockAST *codeblock, - std::string idName, - std::string type) + CodeBlockAST *codeblock) { - std::cout << std::left << std::setw(35) - << "Variable definition found:" << idName << " with type:" << type - << std::endl; - Token nexToken = *(unit->icurTok + 1); - ExprAST *initValue = nullptr; + TypeAST *typeAST = TypeAST::ParseType(unit); + + Token nexToken = unit->next_tok(); + std::string idName = nexToken.tokenValue; + nexToken = *(unit->icurTok + 1); + ExprAST *initValue = nullptr; if (nexToken.type != tok_syntax || nexToken.tokenValue != ";") { if (nexToken.type == tok_syntax && nexToken.tokenValue == "=") { @@ -82,5 +79,9 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, throw e; } } - return new VariableDefExprAST(unit, codeblock, idName, type, initValue); + + 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 index e1b0e2e..650092c 100644 --- a/src/ast/VariableDefExprAST.h +++ b/src/ast/VariableDefExprAST.h @@ -13,12 +13,11 @@ class VariableDefExprAST : public ExprAST { public: VariableDefExprAST(CompileUnit *unit, CodeBlockAST *codeblock, - const std::string &idName, const std::string &type, + const std::string &idName, TypeAST *type, ExprAST *initValue, int argID = -1); virtual ~VariableDefExprAST(); static VariableDefExprAST *ParseVar(CompileUnit * unit, - CodeBlockAST *codeblock, - std::string idName, std::string type); + CodeBlockAST *codeblock); llvm::Value * Codegen(llvm::IRBuilder<> *builder); CodeBlockAST * codeblock; std::string idName; diff --git a/src/utils.cpp b/src/utils.cpp index 9a25a2d..65a81c7 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 354081e..2532903 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); -- Gitee From 4c3df840948a4b7d5763f00c5ff3ad1da0136e7a Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 09:10:32 +0800 Subject: [PATCH 15/98] Add testPrintDouble --- src/lib/testPuts.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 93f6192..3bf21f2 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_12testPrintDouble6double(double a) { printf("%lf\n", a); } extern void _alolang_13testPrintBool4bool(int a) { if (a) { -- Gitee From ecb2d679e2da210aa2fed35b1d892b58ede8a23b Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 09:18:27 +0800 Subject: [PATCH 16/98] Fix a bug in BinaryExprAST --- src/ast/BinaryExprAST.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 02b5b07..fb0f0f8 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -7,6 +7,7 @@ #include "BinaryExprAST.h" #include "../CompileError.hpp" +#include "TypeAST.h" BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, ExprAST *RHS) @@ -17,6 +18,20 @@ BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, this->RHS = RHS; // todo:类型检查 this->type = LHS->type; + //整理此段代码,将操作抽象 + if (binOP == "==") { + this->type = new TypeAST(unit, "bool"); + } else if (binOP == "!=") { + this->type = new TypeAST(unit, "bool"); + } else if (binOP == ">") { + this->type = new TypeAST(unit, "bool"); + } else if (binOP == "<") { + this->type = new TypeAST(unit, "bool"); + } else if (binOP == ">=") { + this->type = new TypeAST(unit, "bool"); + } else if (binOP == "<=") { + this->type = new TypeAST(unit, "bool"); + } } BinaryExprAST::~BinaryExprAST() -- Gitee From 1b7d32b17a53a0c74c393d80b7315606ee1ce2d7 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 09:39:52 +0800 Subject: [PATCH 17/98] Fix a bug in the Codegen of WhileExprAST --- src/ast/WhileExprAST.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 648fb9f..6cc25a8 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -24,15 +24,23 @@ WhileExprAST::~WhileExprAST() llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Function *function = builder->GetInsertBlock()->getParent(); - + 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(bodyBB); - builder->SetInsertPoint(body->endBB); + builder->CreateBr(condBB); + + // builder->SetInsertPoint(body->endBB); + builder->SetInsertPoint(condBB); llvm::Value *conditionValue = condition->Codegen(builder); builder->CreateCondBr(conditionValue, bodyBB, MergeBB); + + builder->SetInsertPoint(body->endBB); + builder->CreateBr(condBB); + builder->SetInsertPoint(MergeBB); parent->endBB = MergeBB; return nullptr; -- Gitee From a296a287587e187f2da47a013b2f952c0e9b63cb Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 21:51:22 +0800 Subject: [PATCH 18/98] Add UnarExprAST --- src/Makefile.am | 2 +- src/ast/ExprAST.cpp | 7 ++++++- src/ast/UnaryExprAST.cpp | 26 ++++++++++++++++++++++++++ src/ast/UnaryExprAST.h | 23 +++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/ast/UnaryExprAST.cpp create mode 100644 src/ast/UnaryExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index ff83e9a..ef5a572 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ 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/VariableDefExprAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp yacc_stuff/tokenizer.lpp + 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 diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 68d949e..09eb364 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -8,6 +8,7 @@ #include "CodeBlockAST.h" #include "IfExprAST.h" #include "IntExprAST.h" +#include "UnaryExprAST.h" #include "VariableDefExprAST.h" #include "VariableExprAST.h" #include "WhileExprAST.h" @@ -38,6 +39,7 @@ int GetTokPrecedence(Token tok) ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) { + this->type = nullptr; // TODO Auto-generated constructor stub } @@ -73,8 +75,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return WhileExprAST::ParseWhileExpr(unit, codeblock); } case tok_syntax: { - token = unit->next_tok(); if (token.tokenValue == "(") { + token = unit->next_tok(); ExprAST *result = ParseExpression(unit, codeblock, false); token = unit->next_tok(); if (token.type != tok_syntax || token.tokenValue != ")") { @@ -83,6 +85,9 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) } return result; } else { + token = unit->next_tok(); + return new UnaryExprAST(unit, token.tokenValue, + ParseExpression(unit, codeblock, false)); std::cerr << "error3:" << token.dump() << std::endl; } break; diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp new file mode 100644 index 0000000..76c91f5 --- /dev/null +++ b/src/ast/UnaryExprAST.cpp @@ -0,0 +1,26 @@ +/* + * UnaryExprAST.cpp + * + * Created on: Feb 21, 2021 + * Author: zbc + */ + +#include "UnaryExprAST.h" + +UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, + ExprAST *operand) + : ExprAST(unit) +{ + this->op = op; + this->operand = operand; +} + +UnaryExprAST::~UnaryExprAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Value *UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + return nullptr; +} diff --git a/src/ast/UnaryExprAST.h b/src/ast/UnaryExprAST.h new file mode 100644 index 0000000..79ec11b --- /dev/null +++ b/src/ast/UnaryExprAST.h @@ -0,0 +1,23 @@ +/* + * 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); + virtual ~UnaryExprAST(); + llvm::Value *Codegen(llvm::IRBuilder<> *builder); + std::string op; + ExprAST * operand; +}; + +#endif /* SRC_AST_UNARYEXPRAST_H_ */ -- Gitee From ec3f9a59a65cf6040729d37b62d7d775ad73c411 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 21 Feb 2021 23:05:48 +0800 Subject: [PATCH 19/98] Add GlobalVariable --- src/CompileUnit.cpp | 17 +++++++++++++++- src/CompileUnit.h | 26 ++++++++++++++---------- src/ast/PrototypeAST.cpp | 7 +------ src/ast/UnaryExprAST.cpp | 3 +++ src/ast/VariableDefExprAST.cpp | 37 ++++++++++++++++++++++++---------- 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index fd497f4..5f75dc4 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -18,6 +18,7 @@ #include "ast/ExternAST.h" #include "ast/FunctionAST.h" #include "ast/TypeAST.h" +#include "ast/VariableDefExprAST.h" #include "utils.h" #include #include @@ -61,7 +62,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - std::cout << token.dump() << std::endl; + // std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); @@ -118,11 +119,25 @@ void CompileUnit::compile() externast->getDemangledName(), externast)); break; } + case tok_identifier: { + //全局变量 + VariableDefExprAST *var = + VariableDefExprAST::ParseVar(this, nullptr); + Token token = next_tok(); + globalVariables.insert( + std::pair(var->idName, var)); + break; + } default: std::cerr << "unexpected token:" << icurTok->dump() << std::endl; } } while (next_tok().type != tok_eof); std::cout << "Start codegen:" << name << std::endl; + 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++) { diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 9c3b679..e047091 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -18,6 +18,7 @@ class TypeAST; class FunctionAST; class ExternAST; +class VariableDefExprAST; class CompileUnit { public: @@ -27,17 +28,20 @@ class CompileUnit 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 functions; - std::map externs; - std::map types; // Codgen用 + 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 globalVariables; + std::map functions; + std::map externs; + std::map types; // Codgen用 + std::map globalVariablesCodegen; // Codgen用 + // std::map }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 9d2324d..203547a 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -128,12 +128,6 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) 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++) { llvmArgs.push_back(args[i].first->Codegen()); @@ -180,6 +174,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/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 76c91f5..7f6f353 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -6,6 +6,7 @@ */ #include "UnaryExprAST.h" +#include "../CompileError.hpp" UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand) @@ -13,6 +14,8 @@ UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, { this->op = op; this->operand = operand; + CompileError e("一元运算符未实现"); + throw e; } UnaryExprAST::~UnaryExprAST() diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index d750f33..ad9f492 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -45,18 +45,29 @@ static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) { - 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); + if (codeblock == nullptr) { + llvm::GlobalVariable *gVar = new llvm::GlobalVariable( + *unit->module, type->Codegen(), false, + llvm::GlobalValue::ExternalLinkage, nullptr); + unit->globalVariablesCodegen.insert( + std::pair(idName, gVar)); + //全局变量 + } else { + //局部变量 + 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); + } + codeblock->namedValues.insert( + std::pair>( + idName, + std::pair(type, alloca))); } - codeblock->namedValues.insert( - std::pair>( - idName, std::pair(type, alloca))); return nullptr; } @@ -72,6 +83,10 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, 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 { -- Gitee From a8ed0ed4155967273be9c5ab7db68fa8c256259e Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 22 Feb 2021 10:18:25 +0800 Subject: [PATCH 20/98] Rebuild Paser --- src/CompileUnit.cpp | 4 ++-- src/ast/CodeBlockAST.cpp | 7 ++++--- src/ast/ExprAST.cpp | 38 ++++++++++++++-------------------- src/ast/ExternAST.cpp | 3 ++- src/ast/IfExprAST.cpp | 1 + src/ast/PrototypeAST.cpp | 12 ++++------- src/ast/TypeAST.cpp | 6 ++++-- src/ast/VariableDefExprAST.cpp | 4 ++-- src/ast/WhileExprAST.cpp | 1 + 9 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 5f75dc4..af796e5 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -95,7 +95,7 @@ void CompileUnit::compile() std::cout << "Start compiling:" << name << std::endl; initInnerType(this); scanToken(this); - do { + while (icurTok->type != tok_eof) { switch (icurTok->type) { case tok_fun: { FunctionAST *func_ast = FunctionAST::ParseFunction(this); @@ -131,7 +131,7 @@ void CompileUnit::compile() default: std::cerr << "unexpected token:" << icurTok->dump() << std::endl; } - } while (next_tok().type != tok_eof); + } std::cout << "Start codegen:" << name << std::endl; std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 2fdc341..fcd9e53 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -31,9 +31,8 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, CodeBlockAST * parent, const std::vector args) { - Token token = *(unit->icurTok + 1); + Token token = *unit->icurTok; if (token.type == tok_syntax && token.tokenValue == "{") { - unit->next_tok(); CodeBlockAST *codeblock = new CodeBlockAST(unit, std::vector(), name, parent); std::vector &body = codeblock->body; @@ -41,8 +40,10 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, argDef->codeblock = codeblock; body.push_back(argDef); } + //解析块内语句 + Token inBlockToken = unit->next_tok(); while (true) { - Token inBlockToken = *(unit->icurTok + 1); + inBlockToken = *(unit->icurTok); if (inBlockToken.type == tok_eof) { CompileError e("Unexpexted EOF in function body"); throw e; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 09eb364..5a4f7ba 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -51,14 +51,13 @@ ExprAST::~ExprAST() ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) { // todo:除了函数调用之外的语句解析 - Token token = *(unit->icurTok + 1); + Token token = *unit->icurTok; switch (token.type) { case tok_number: { - token = unit->next_tok(); + unit->next_tok(); return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); } case tok_key_literal: { - token = unit->next_tok(); if (token.tokenValue == "true") { return new BoolExprAST(unit, true); } else { @@ -67,25 +66,23 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) break; } case tok_key_if: { - token = unit->next_tok(); return IfExprAST::ParseIfExpr(unit, codeblock); } case tok_key_while: { - token = unit->next_tok(); return WhileExprAST::ParseWhileExpr(unit, codeblock); } case tok_syntax: { if (token.tokenValue == "(") { - token = unit->next_tok(); + unit->next_tok(); ExprAST *result = ParseExpression(unit, codeblock, false); - token = unit->next_tok(); + token = *unit->icurTok; if (token.type != tok_syntax || token.tokenValue != ")") { CompileError e("missing ')'"); throw e; } + token = unit->next_tok(); return result; } else { - token = unit->next_tok(); return new UnaryExprAST(unit, token.tokenValue, ParseExpression(unit, codeblock, false)); std::cerr << "error3:" << token.dump() << std::endl; @@ -95,7 +92,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) case tok_identifier: { //函数调用或定义 std::string idName = token.tokenValue; - token = *(unit->icurTok + 2); + token = *(unit->icurTok + 1); if (token.type == tok_identifier) { //定义 VariableDefExprAST *varAST = @@ -106,21 +103,17 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) //赋值 return AssignmentAST::ParseAssignment(unit, codeblock, idName); } else if (token.tokenValue == "(") { - token = unit->next_tok(); //函数调用 - unit->next_tok(); + token = unit->next_tok(); + token = unit->next_tok(); std::vector args; while (true) { - Token nextToken = *(unit->icurTok + 1); - - if (nextToken.type == tok_syntax && - nextToken.tokenValue == ")") { + token = *unit->icurTok; + if (token.type == tok_syntax && token.tokenValue == ")") { unit->next_tok(); break; } - if (nextToken.type == tok_syntax && - nextToken.tokenValue == ",") { - unit->next_tok(); + if (token.type == tok_syntax && token.tokenValue == ",") { continue; } @@ -131,8 +124,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return new CallExprAST(unit, idName, args); } else { - token = unit->next_tok(); //变量 + unit->next_tok(); return new VariableExprAST(unit, codeblock, idName); } break; @@ -149,7 +142,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, int ExprPrec, ExprAST *LHS) { while (1) { - Token token = *(unit->icurTok + 1); + Token token = *unit->icurTok; int TokPrec = GetTokPrecedence(token); if (TokPrec < ExprPrec) { return LHS; @@ -160,7 +153,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, if (!RHS) return nullptr; - int NextPrec = GetTokPrecedence(*(unit->icurTok + 1)); + int NextPrec = GetTokPrecedence(*(unit->icurTok)); if (TokPrec < NextPrec) { RHS = ParseBinOpRHS(unit, codeblock, TokPrec + 1, RHS); if (RHS == nullptr) { @@ -186,11 +179,12 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, return result; //跳过分号 } if (root) { - Token token = unit->next_tok(); + Token token = *(unit->icurTok); if (token.type != tok_syntax || token.tokenValue != ";") { CompileError e("丟失分号: \"" + token.dump() + "\" 前"); throw e; } + unit->next_tok(); } return result; } diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 7d33e12..3c64a14 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -42,11 +42,12 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) // todo:对externC的处理 std::cout << std::left << std::setw(35) << "Function extern found:" << proto->name << std::endl; - Token token = unit->next_tok(); + Token token = *(unit->icurTok); if (token.type != tok_syntax || token.tokenValue != ";") { CompileError e("丟失分号: \"" + token.dump() + "\" 前"); throw e; } + token = unit->next_tok(); return new ExternAST(unit, proto); } diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index e092ce1..4bfbd50 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -27,6 +27,7 @@ IfExprAST::~IfExprAST() IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) { + unit->next_tok(); ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); CodeBlockAST *thenBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); CodeBlockAST *elseBlock = nullptr; diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 203547a..ae05a17 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -56,11 +56,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } while (true) { - if (FnName == "main") { - token = unit->next_tok(); // ). - break; - } - token = *(unit->icurTok + 1); + token = unit->next_tok(); if (token.type == tok_syntax && token.tokenValue == ",") { token = unit->next_tok(); continue; @@ -71,7 +67,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } TypeAST *type = TypeAST::ParseType(unit); // todo:错误处理 - token = unit->next_tok(); + token = *unit->icurTok; std::string name = token.tokenValue; std::pair pair; pair.first = type; @@ -83,14 +79,14 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) // TODO:异常处理 } - token = *(unit->icurTok + 1); // -> or ; or { + token = *(unit->icurTok); // -> or ; or { std::vector returnTypes; if (token.type == tok_return_type) { unit->next_tok(); int bc = 0; while (true) { // todo:大量异常处理 - token = *(unit->icurTok + 1); // identifier. + token = *unit->icurTok; if (token.type == tok_syntax) { if (token.tokenValue == "(") { bc++; diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index ff6796d..ec51564 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -39,10 +39,12 @@ llvm::Type *TypeAST::Codegen() TypeAST *TypeAST::ParseType(CompileUnit *unit) { - Token token = unit->next_tok(); + Token token = *unit->icurTok; if (token.type != tok_identifier) { CompileError e("Expected type but got " + token.dump()); throw e; } - return new TypeAST(unit, token.tokenValue); + TypeAST *result = new TypeAST(unit, token.tokenValue); + token = unit->next_tok(); + return result; } diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index ad9f492..dc0f034 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -76,9 +76,9 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, { TypeAST *typeAST = TypeAST::ParseType(unit); - Token nexToken = unit->next_tok(); + Token nexToken = *(unit->icurTok); std::string idName = nexToken.tokenValue; - nexToken = *(unit->icurTok + 1); + nexToken = unit->next_tok(); ExprAST *initValue = nullptr; if (nexToken.type != tok_syntax || nexToken.tokenValue != ";") { diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 6cc25a8..418f8a9 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -49,6 +49,7 @@ llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) 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); -- Gitee From cbc8e59aaa6d1964d097e401bde0445847eb96cf Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 22 Feb 2021 12:53:27 +0800 Subject: [PATCH 21/98] Implement global variable --- src/CompileUnit.cpp | 7 ++++++- src/CompileUnit.h | 5 +++-- src/ast/CodeBlockAST.h | 2 +- src/ast/VariableDefExprAST.cpp | 23 ++++++++++++++++++++--- src/ast/VariableExprAST.cpp | 15 ++++++++++++--- src/ast/VariableExprAST.h | 10 +++++----- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index af796e5..2dee039 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -136,7 +136,12 @@ void CompileUnit::compile() std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); gVar_iter != globalVariables.end(); gVar_iter++) { - gVar_iter->second->Codegen(nullptr); + llvm::Value *gVarValue = gVar_iter->second->Codegen(nullptr); + globalVariablesValue.insert( + std::pair>( + gVar_iter->second->idName, + std::pair(gVar_iter->second->type, + gVarValue))); } std::map::iterator extern_iter; for (extern_iter = externs.begin(); extern_iter != externs.end(); diff --git a/src/CompileUnit.h b/src/CompileUnit.h index e047091..f4fd777 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -39,8 +39,9 @@ class CompileUnit std::map globalVariables; std::map functions; std::map externs; - std::map types; // Codgen用 - std::map globalVariablesCodegen; // Codgen用 + std::map types; // Codgen用 + std::map> + globalVariablesValue; // Codgen用 // std::map }; diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 0b06686..6ec37d0 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -29,7 +29,7 @@ class CodeBlockAST : public BaseAST llvm::IRBuilder<> * builder; std::vector body; - std::map> + std::map> namedValues; // Codegen阶段用 std::string name; CodeBlockAST * parent; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index dc0f034..f024640 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -48,9 +48,26 @@ llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) if (codeblock == nullptr) { llvm::GlobalVariable *gVar = new llvm::GlobalVariable( *unit->module, type->Codegen(), false, - llvm::GlobalValue::ExternalLinkage, nullptr); - unit->globalVariablesCodegen.insert( - std::pair(idName, gVar)); + llvm::GlobalValue::ExternalLinkage, nullptr, idName); + // todo:初始填0 + if (type->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 (type->name == "double") { + llvm::Type * ftype = llvm::Type::getDoubleTy(*unit->context); + llvm::Constant *res = llvm::ConstantFP::get(ftype, 0); + gVar->setInitializer(res); + } else if (type->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(type, gVar))); //全局变量 } else { //局部变量 diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 945906c..a4dca0f 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -27,11 +27,12 @@ VariableExprAST::~VariableExprAST() // TODO Auto-generated destructor stub } -llvm::AllocaInst *VariableExprAST::getAlloca() +llvm::Value *VariableExprAST::getAlloca() { if (alloca != nullptr) { return alloca; } + //找局部变量 CodeBlockAST *curCodeBlock = codeblock; while (curCodeBlock != nullptr) { auto varAST = curCodeBlock->namedValues.find(idName); @@ -43,8 +44,16 @@ llvm::AllocaInst *VariableExprAST::getAlloca() return alloca; } } - CompileError e("can't find variable:" + idName); - throw e; + //找全局变量 + auto gVar = unit->globalVariablesValue.find(idName); + if (gVar == unit->globalVariablesValue.end()) { + CompileError e("can't find variable:" + idName); + throw e; + } else { + type = gVar->second.first; + alloca = gVar->second.second; + return alloca; + } } llvm::Value *VariableExprAST::Codegen(llvm::IRBuilder<> *builder) diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index 273df80..aaf605b 100644 --- a/src/ast/VariableExprAST.h +++ b/src/ast/VariableExprAST.h @@ -15,13 +15,13 @@ class VariableExprAST : public ExprAST VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, const std::string &idName); virtual ~VariableExprAST(); - llvm::AllocaInst *getAlloca(); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - std::string idName; - CodeBlockAST * codeblock; + llvm::Value * getAlloca(); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + std::string idName; + CodeBlockAST *codeblock; private: - llvm::AllocaInst *alloca; + llvm::Value *alloca; }; #endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ -- Gitee From 233eff19655ef1ab211647a9e685e36e689f650b Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 22 Feb 2021 13:28:38 +0800 Subject: [PATCH 22/98] Test global var --- test/globalvar.alo | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/globalvar.alo diff --git a/test/globalvar.alo b/test/globalvar.alo new file mode 100644 index 0000000..bafc3e9 --- /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 -- Gitee From 0e2ea5944696a2fadb974b46bca06b7e28f48be6 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 22 Feb 2021 15:46:10 +0800 Subject: [PATCH 23/98] Add ClassAST --- src/Makefile.am | 8 +++++--- src/ast/ClassAST.cpp | 18 ++++++++++++++++++ src/ast/ClassAST.h | 20 ++++++++++++++++++++ src/ast/ExprAST.cpp | 1 + src/ast/UnaryExprAST.cpp | 12 ++++++++++-- 5 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/ast/ClassAST.cpp create mode 100644 src/ast/ClassAST.h diff --git a/src/Makefile.am b/src/Makefile.am index ef5a572..2d33769 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,11 @@ 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/VariableDefExprAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp ast/UnaryExprAST.cpp yacc_stuff/tokenizer.lpp + ast/AssignmentAST.cpp ast/BaseAST.cpp ast/BinaryExprAST.cpp ast/BoolExprAST.cpp\ + ast/CallExprAST.cpp ast/ClassAST.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/VariableDefExprAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp\ + ast/UnaryExprAST.cpp yacc_stuff/tokenizer.lpp AM_LFLAGS = -o lex.yy.c diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp new file mode 100644 index 0000000..2ed8fdb --- /dev/null +++ b/src/ast/ClassAST.cpp @@ -0,0 +1,18 @@ +/* + * ClassAST.cpp + * + * Created on: Feb 22, 2021 + * Author: zbc + */ + +#include "ClassAST.h" + +ClassAST::ClassAST(CompileUnit *unit) : BaseAST(unit) +{ + // TODO Auto-generated constructor stub +} + +ClassAST::~ClassAST() +{ + // TODO Auto-generated destructor stub +} diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h new file mode 100644 index 0000000..13219f6 --- /dev/null +++ b/src/ast/ClassAST.h @@ -0,0 +1,20 @@ +/* + * ClassAST.h + * + * Created on: Feb 22, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_CLASSAST_H_ +#define SRC_AST_CLASSAST_H_ + +#include "BaseAST.h" + +class ClassAST : public BaseAST +{ + public: + ClassAST(CompileUnit *unit); + virtual ~ClassAST(); +}; + +#endif /* SRC_AST_CLASSAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 5a4f7ba..93151c3 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -83,6 +83,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) token = unit->next_tok(); return result; } else { + unit->next_tok(); return new UnaryExprAST(unit, token.tokenValue, ParseExpression(unit, codeblock, false)); std::cerr << "error3:" << token.dump() << std::endl; diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 7f6f353..89eda3d 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -7,6 +7,7 @@ #include "UnaryExprAST.h" #include "../CompileError.hpp" +#include "TypeAST.h" UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand) @@ -14,8 +15,12 @@ UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, { this->op = op; this->operand = operand; - CompileError e("一元运算符未实现"); - throw e; + if (op == "!") { + this->type = new TypeAST(unit, "bool"); + } else { + CompileError e("一元运算符:" + op + "未实现"); + throw e; + } } UnaryExprAST::~UnaryExprAST() @@ -25,5 +30,8 @@ UnaryExprAST::~UnaryExprAST() llvm::Value *UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) { + if (op == "!") { + return builder->CreateXor(operand->Codegen(builder), 1); + } return nullptr; } -- Gitee From b550eb3379c2b7cee79091cb3c8cfeb01899a101 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 22 Feb 2021 17:35:57 +0800 Subject: [PATCH 24/98] something, have bug ,definately --- src/ast/CodeBlockAST.cpp | 8 +- src/yacc_stuff/tokenizer.cpp | 2028 ++++++++++++++++++++++++++++++++++ 2 files changed, 2034 insertions(+), 2 deletions(-) create mode 100644 src/yacc_stuff/tokenizer.cpp diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index fcd9e53..e303595 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -72,9 +72,13 @@ llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) for (ExprAST *expr : body) { expr->Codegen(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") + builder->CreateRetVoid(); + else + builder->CreateRet(0); } return bb; diff --git a/src/yacc_stuff/tokenizer.cpp b/src/yacc_stuff/tokenizer.cpp new file mode 100644 index 0000000..570d702 --- /dev/null +++ b/src/yacc_stuff/tokenizer.cpp @@ -0,0 +1,2028 @@ +#line 1 "../../src/yacc_stuff/tokenizer.cpp" + +#line 3 "../../src/yacc_stuff/tokenizer.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer yyFlexLexer + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ +#include +#include +#include +#include +#include +/* end standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + + std::streambuf* yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +#define yytext_ptr yytext +#define YY_INTERACTIVE + +#include + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 62 +#define YY_END_OF_BUFFER 63 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[144] = + { 0, + 0, 0, 63, 61, 1, 33, 53, 60, 34, 36, + 51, 38, 39, 37, 40, 54, 41, 58, 59, 28, + 27, 52, 50, 55, 42, 56, 57, 21, 47, 49, + 48, 35, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 43, 45, 44, + 46, 1, 30, 0, 0, 2, 0, 16, 26, 0, + 0, 0, 0, 27, 32, 29, 31, 21, 21, 21, + 21, 21, 8, 21, 21, 21, 21, 21, 21, 13, + 21, 4, 21, 21, 21, 21, 21, 3, 0, 3, + 2, 0, 3, 0, 26, 24, 25, 22, 23, 21, + + 21, 21, 21, 21, 21, 10, 17, 21, 21, 21, + 21, 21, 3, 25, 23, 21, 15, 21, 9, 21, + 21, 21, 18, 12, 21, 21, 5, 21, 6, 21, + 21, 21, 21, 21, 14, 21, 19, 21, 20, 21, + 11, 7, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 1, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 20, 20, 20, 20, 20, 21, 21, 22, 23, 24, + 25, 26, 27, 1, 28, 29, 28, 28, 28, 28, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 31, 30, 30, + 32, 33, 34, 35, 30, 1, 36, 37, 38, 39, + + 40, 41, 42, 43, 44, 30, 45, 46, 30, 47, + 48, 30, 30, 49, 50, 51, 52, 30, 53, 54, + 30, 30, 55, 56, 57, 58, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[59] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 4, 4, 5, + 5, 1, 1, 1, 1, 4, 4, 4, 4, 4, + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 1, 1, 1, 1 + } ; + +static const flex_int16_t yy_base[152] = + { 0, + 0, 0, 211, 212, 57, 185, 58, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 183, 212, 212, 45, + 50, 212, 212, 183, 182, 181, 212, 0, 212, 212, + 212, 212, 158, 155, 31, 155, 26, 37, 154, 160, + 152, 150, 158, 144, 147, 152, 146, 212, 212, 212, + 212, 75, 212, 78, 81, 188, 59, 212, 75, 69, + 0, 78, 0, 82, 212, 212, 212, 0, 153, 151, + 140, 142, 0, 138, 136, 140, 136, 137, 132, 0, + 131, 0, 130, 136, 127, 134, 128, 101, 173, 172, + 212, 102, 105, 141, 94, 97, 0, 99, 0, 137, + + 132, 120, 130, 129, 118, 127, 128, 89, 84, 83, + 93, 86, 212, 0, 0, 86, 0, 86, 0, 80, + 88, 91, 0, 0, 77, 87, 0, 84, 0, 76, + 75, 83, 73, 76, 0, 57, 0, 47, 0, 35, + 0, 0, 212, 138, 140, 145, 150, 153, 155, 158, + 161 + } ; + +static const flex_int16_t yy_def[152] = + { 0, + 143, 1, 143, 143, 143, 143, 144, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 145, 143, 143, + 143, 143, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 143, 143, 143, + 143, 143, 143, 144, 146, 146, 147, 143, 143, 143, + 148, 143, 149, 143, 143, 143, 143, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 146, 143, 143, + 143, 144, 144, 147, 143, 143, 150, 143, 151, 145, + + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 143, 150, 151, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 0, 143, 143, 143, 143, 143, 143, 143, + 143 + } ; + +static const flex_int16_t yy_nxt[271] = + { 0, + 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, + 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 28, 40, 28, 28, 41, 42, 43, 44, + 45, 28, 46, 47, 48, 49, 50, 51, 52, 52, + 55, 93, 56, 59, 59, 64, 71, 64, 64, 64, + 64, 74, 76, 60, 142, 61, 52, 52, 72, 75, + 88, 62, 56, 90, 77, 91, 96, 96, 78, 141, + 57, 94, 95, 95, 95, 98, 98, 64, 63, 64, + + 64, 64, 64, 90, 55, 91, 56, 55, 140, 56, + 57, 95, 95, 95, 96, 96, 98, 98, 117, 139, + 138, 137, 136, 135, 134, 133, 132, 127, 131, 130, + 129, 128, 127, 126, 57, 125, 124, 57, 54, 54, + 54, 54, 54, 68, 68, 89, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 97, 97, 99, 99, 114, + 114, 114, 115, 115, 115, 123, 122, 121, 120, 119, + 118, 117, 116, 94, 113, 113, 82, 112, 111, 110, + 109, 82, 108, 107, 106, 105, 104, 103, 102, 101, + 100, 82, 91, 87, 86, 85, 84, 83, 82, 81, + + 80, 79, 73, 70, 69, 67, 66, 65, 58, 53, + 143, 3, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 + } ; + +static const flex_int16_t yy_chk[271] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, + 7, 57, 7, 20, 20, 21, 35, 21, 21, 21, + 21, 37, 38, 20, 140, 20, 52, 52, 35, 37, + 54, 20, 54, 55, 38, 55, 60, 60, 38, 138, + 7, 57, 59, 59, 59, 62, 62, 64, 20, 64, + + 64, 64, 64, 88, 92, 88, 92, 93, 136, 93, + 54, 95, 95, 95, 96, 96, 98, 98, 134, 133, + 132, 131, 130, 128, 126, 125, 122, 121, 120, 118, + 116, 112, 111, 110, 92, 109, 108, 93, 144, 144, + 144, 144, 144, 145, 145, 146, 146, 146, 146, 146, + 147, 147, 147, 147, 147, 148, 148, 149, 149, 150, + 150, 150, 151, 151, 151, 107, 106, 105, 104, 103, + 102, 101, 100, 94, 90, 89, 87, 86, 85, 84, + 83, 81, 79, 78, 77, 76, 75, 74, 72, 71, + 70, 69, 56, 47, 46, 45, 44, 43, 42, 41, + + 40, 39, 36, 34, 33, 26, 25, 24, 17, 6, + 3, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[63] = + { 0, +1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, }; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "../../src/yacc_stuff/tokenizer.lpp" +#line 2 "../../src/yacc_stuff/tokenizer.lpp" +#include +#include +#include +int token; + +#line 534 "../../src/yacc_stuff/tokenizer.cpp" +#line 535 "../../src/yacc_stuff/tokenizer.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +#define ECHO LexerOutput( yytext, yyleng ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +\ + if ( (int)(result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) LexerError( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +#define YY_DECL int yyFlexLexer::yylex() +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin.rdbuf(std::cin.rdbuf()); + + if ( ! yyout ) + yyout.rdbuf(std::cout.rdbuf()); + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 11 "../../src/yacc_stuff/tokenizer.lpp" + +#line 669 "../../src/yacc_stuff/tokenizer.cpp" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 144 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 212 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 12 "../../src/yacc_stuff/tokenizer.lpp" +{/*Skip spaces tabs, and line feeds*/}; + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 14 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_str; return token; + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 15 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_err; return token; + YY_BREAK +case 4: +YY_RULE_SETUP +#line 17 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_op; return token; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 19 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_literal; return token; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 21 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_break; return token; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 22 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_continue; return token; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 23 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_do; return token; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 24 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_else; return token; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 25 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_for; return token; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 26 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_foreach; return token; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 27 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_goto; return token; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 28 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_if; return token; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 29 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_while; return token; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 31 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_key_switch; return token; + YY_BREAK +case 16: +YY_RULE_SETUP +#line 33 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_return_type; return token; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 34 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_fun; return token; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 35 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_fun; return token; + YY_BREAK +case 19: +YY_RULE_SETUP +#line 36 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_extern; return token; + YY_BREAK +case 20: +YY_RULE_SETUP +#line 37 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_extern; return token; + YY_BREAK +case 21: +YY_RULE_SETUP +#line 38 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_identifier; return token; + YY_BREAK +case 22: +YY_RULE_SETUP +#line 39 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 23: +YY_RULE_SETUP +#line 40 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 41 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 42 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 26: +YY_RULE_SETUP +#line 43 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 27: +YY_RULE_SETUP +#line 44 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 28: +YY_RULE_SETUP +#line 45 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_number; return token; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 48 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 30: +YY_RULE_SETUP +#line 49 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 31: +YY_RULE_SETUP +#line 50 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 51 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 33: +YY_RULE_SETUP +#line 52 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 53 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 35: +YY_RULE_SETUP +#line 54 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 36: +YY_RULE_SETUP +#line 55 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 37: +YY_RULE_SETUP +#line 56 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 38: +YY_RULE_SETUP +#line 57 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 39: +YY_RULE_SETUP +#line 58 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 40: +YY_RULE_SETUP +#line 59 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 41: +YY_RULE_SETUP +#line 60 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 42: +YY_RULE_SETUP +#line 61 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 43: +YY_RULE_SETUP +#line 62 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 44: +YY_RULE_SETUP +#line 63 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 45: +YY_RULE_SETUP +#line 64 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 46: +YY_RULE_SETUP +#line 65 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 47: +YY_RULE_SETUP +#line 66 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 48: +YY_RULE_SETUP +#line 67 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 49: +YY_RULE_SETUP +#line 68 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 50: +YY_RULE_SETUP +#line 69 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 51: +YY_RULE_SETUP +#line 70 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 52: +YY_RULE_SETUP +#line 71 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 53: +YY_RULE_SETUP +#line 72 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 54: +YY_RULE_SETUP +#line 73 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 55: +YY_RULE_SETUP +#line 74 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 56: +YY_RULE_SETUP +#line 75 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 57: +YY_RULE_SETUP +#line 76 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 58: +YY_RULE_SETUP +#line 77 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 59: +YY_RULE_SETUP +#line 78 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case 60: +YY_RULE_SETUP +#line 79 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_syntax; return token; + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 80 "../../src/yacc_stuff/tokenizer.lpp" +{token = tok_eof; return token;} + YY_BREAK +case 61: +/* rule 61 can match eol */ +YY_RULE_SETUP +#line 81 "../../src/yacc_stuff/tokenizer.lpp" +token = tok_err; return token; + YY_BREAK +case 62: +YY_RULE_SETUP +#line 82 "../../src/yacc_stuff/tokenizer.lpp" +ECHO; + YY_BREAK +#line 1054 "../../src/yacc_stuff/tokenizer.cpp" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin.rdbuf(); + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* The contents of this function are C++ specific, so the () macro is not used. + * This constructor simply maintains backward compatibility. + * DEPRECATED + */ +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ): + yyin(arg_yyin ? arg_yyin->rdbuf() : std::cin.rdbuf()), + yyout(arg_yyout ? arg_yyout->rdbuf() : std::cout.rdbuf()) +{ + ctor_common(); +} + +/* The contents of this function are C++ specific, so the () macro is not used. + */ +yyFlexLexer::yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout ): + yyin(arg_yyin.rdbuf()), + yyout(arg_yyout.rdbuf()) +{ + ctor_common(); +} + +/* The contents of this function are C++ specific, so the () macro is not used. + */ +void yyFlexLexer::ctor_common() +{ + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + yy_buffer_stack = NULL; + yy_buffer_stack_top = 0; + yy_buffer_stack_max = 0; + + yy_state_buf = 0; + +} + +/* The contents of this function are C++ specific, so the () macro is not used. + */ +yyFlexLexer::~yyFlexLexer() +{ + delete [] yy_state_buf; + yyfree( yy_start_stack ); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyfree( yy_buffer_stack ); +} + +/* The contents of this function are C++ specific, so the () macro is not used. + */ +void yyFlexLexer::switch_streams( std::istream& new_in, std::ostream& new_out ) +{ + // was if( new_in ) + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + + // was if( new_out ) + yyout.rdbuf(new_out.rdbuf()); +} + +/* The contents of this function are C++ specific, so the () macro is not used. + */ +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if( ! new_in ) { + new_in = &yyin; + } + + if ( ! new_out ) { + new_out = &yyout; + } + + switch_streams(*new_in, *new_out); +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin.eof() || yyin.fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin.get( buf[0] ); + + if ( yyin.eof() ) + return 0; + + if ( yyin.bad() ) + return -1; + + return 1; + +#else + (void) yyin.read( buf, max_size ); + + if ( yyin.bad() ) + return -1; + else + return yyin.gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout.write( buf, size ); +} + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +int yyFlexLexer::yy_get_next_buffer() +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + yy_state_type yyFlexLexer::yy_get_previous_state() +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 144 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 144 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 143); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + void yyFlexLexer::yyunput( int c, char* yy_bp) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} +#endif + + int yyFlexLexer::yyinput() +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + if ( c == '\n' ) + + yylineno++; +; + + return c; +} + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyFlexLexer::yyrestart( std::istream& input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Delegate to the new version that takes an istream reference. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ +void yyFlexLexer::yyrestart( std::istream* input_file ) +{ + if( ! input_file ) { + input_file = &yyin; + } + yyrestart( *input_file ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + + void yyFlexLexer::yy_load_buffer_state() +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin.rdbuf(YY_CURRENT_BUFFER_LVALUE->yy_input_file); + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream& file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Delegate creation of buffers to the new version that takes an istream reference. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +{ + return yy_create_buffer( *file, size ); +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream& file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file.rdbuf(); + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yyFlexLexer::yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +void yyFlexLexer::yyensure_buffer_stack(void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + + void yyFlexLexer::yy_push_state( int _new_state ) +{ + if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) + { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_size_t) (yy_start_stack_depth) * sizeof( int ); + + if ( ! (yy_start_stack) ) + (yy_start_stack) = (int *) yyalloc( new_size ); + + else + (yy_start_stack) = (int *) yyrealloc( + (void *) (yy_start_stack), new_size ); + + if ( ! (yy_start_stack) ) + YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(_new_state); +} + + void yyFlexLexer::yy_pop_state() +{ + if ( --(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + + int yyFlexLexer::yy_top_state() +{ + return (yy_start_stack)[(yy_start_stack_ptr) - 1]; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +void yyFlexLexer::LexerError( const char* msg ) +{ + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 82 "../../src/yacc_stuff/tokenizer.lpp" + + +int yyFlexLexer::yywrap(){return 1;} + -- Gitee From 221537b37042336f2e081980eb2cf3632f35b193 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 22 Feb 2021 21:46:11 +0800 Subject: [PATCH 25/98] Added some document for type --- docs/language/keyword/type/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/language/keyword/type/index.md b/docs/language/keyword/type/index.md index 8dad771..f50c7ad 100644 --- a/docs/language/keyword/type/index.md +++ b/docs/language/keyword/type/index.md @@ -5,6 +5,7 @@ 包含下面这几种 ``` +type anytype array auto -- Gitee From 5a4242e41cc5a8001c362d6a76e9cbfa7d230c14 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 22 Feb 2021 21:47:01 +0800 Subject: [PATCH 26/98] Added some document for something --- docs/_sidebar.md | 1 + docs/language/keyword/type/index.md | 1 + docs/language/keyword/type/type/index.md | 17 +++++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 docs/language/keyword/type/type/index.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 956b461..0375d35 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -15,6 +15,7 @@ * [alolang关键字:anytype](language/keyword/type/anytype/index) * [alolang关键字:float](language/keyword/type/float/index) * [alolang关键字:enum](language/keyword/type/enum/index) + * [alolang关键字:type](language/keyword/type/type/index) * [alolang关键字:void](language/keyword/type/void/index) * [alolang关键字:char](language/keyword/type/char/index) * [alolang关键字:bool](language/keyword/type/bool/index) diff --git a/docs/language/keyword/type/index.md b/docs/language/keyword/type/index.md index 8dad771..f50c7ad 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/type/index.md b/docs/language/keyword/type/type/index.md new file mode 100644 index 0000000..547309c --- /dev/null +++ b/docs/language/keyword/type/type/index.md @@ -0,0 +1,17 @@ +# alolang关键字: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 -- Gitee From 3ba3e1f71471faddcbf8e4f44fdf2ec1e22ecb4a Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 22 Feb 2021 22:17:26 +0800 Subject: [PATCH 27/98] Remove tokenizer.cpp --- src/yacc_stuff/tokenizer.cpp | 2028 ---------------------------------- 1 file changed, 2028 deletions(-) delete mode 100644 src/yacc_stuff/tokenizer.cpp diff --git a/src/yacc_stuff/tokenizer.cpp b/src/yacc_stuff/tokenizer.cpp deleted file mode 100644 index 570d702..0000000 --- a/src/yacc_stuff/tokenizer.cpp +++ /dev/null @@ -1,2028 +0,0 @@ -#line 1 "../../src/yacc_stuff/tokenizer.cpp" - -#line 3 "../../src/yacc_stuff/tokenizer.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 4 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - - /* The c++ scanner is a mess. The FlexLexer.h header file relies on the - * following macro. This is required in order to pass the c++-multiple-scanners - * test in the regression suite. We get reports that it breaks inheritance. - * We will address this in a future release of flex, or omit the C++ scanner - * altogether. - */ - #define yyFlexLexer yyFlexLexer - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* begin standard C++ headers. */ -#include -#include -#include -#include -#include -/* end standard C++ headers. */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an - * integer in range [0..255] for use as an array index. - */ -#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern int yyleng; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires - * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE yylex. - * One obvious solution it to make yy_act a global. I tried that, and saw - * a 5% performance hit in a non-yylineno scanner, because yy_act is - * normally declared as a register variable-- so it is not worth it. - */ - #define YY_LESS_LINENO(n) \ - do { \ - int yyl;\ - for ( yyl = n; yyl < yyleng; ++yyl )\ - if ( yytext[yyl] == '\n' )\ - --yylineno;\ - }while(0) - #define YY_LINENO_REWIND_TO(dst) \ - do {\ - const char *p;\ - for ( p = yy_cp-1; p >= (dst); --p)\ - if ( *p == '\n' )\ - --yylineno;\ - }while(0) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - - std::streambuf* yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -void *yyalloc ( yy_size_t ); -void *yyrealloc ( void *, yy_size_t ); -void yyfree ( void * ); - -#define yy_new_buffer yy_create_buffer -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ -typedef flex_uint8_t YY_CHAR; - -#define yytext_ptr yytext -#define YY_INTERACTIVE - -#include - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 62 -#define YY_END_OF_BUFFER 63 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static const flex_int16_t yy_accept[144] = - { 0, - 0, 0, 63, 61, 1, 33, 53, 60, 34, 36, - 51, 38, 39, 37, 40, 54, 41, 58, 59, 28, - 27, 52, 50, 55, 42, 56, 57, 21, 47, 49, - 48, 35, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 43, 45, 44, - 46, 1, 30, 0, 0, 2, 0, 16, 26, 0, - 0, 0, 0, 27, 32, 29, 31, 21, 21, 21, - 21, 21, 8, 21, 21, 21, 21, 21, 21, 13, - 21, 4, 21, 21, 21, 21, 21, 3, 0, 3, - 2, 0, 3, 0, 26, 24, 25, 22, 23, 21, - - 21, 21, 21, 21, 21, 10, 17, 21, 21, 21, - 21, 21, 3, 25, 23, 21, 15, 21, 9, 21, - 21, 21, 18, 12, 21, 21, 5, 21, 6, 21, - 21, 21, 21, 21, 14, 21, 19, 21, 20, 21, - 11, 7, 0 - } ; - -static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 20, 20, 20, 20, 20, 21, 21, 22, 23, 24, - 25, 26, 27, 1, 28, 29, 28, 28, 28, 28, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 31, 30, 30, - 32, 33, 34, 35, 30, 1, 36, 37, 38, 39, - - 40, 41, 42, 43, 44, 30, 45, 46, 30, 47, - 48, 30, 30, 49, 50, 51, 52, 30, 53, 54, - 30, 30, 55, 56, 57, 58, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static const YY_CHAR yy_meta[59] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 4, 4, 5, - 5, 1, 1, 1, 1, 4, 4, 4, 4, 4, - 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 1, 1, 1, 1 - } ; - -static const flex_int16_t yy_base[152] = - { 0, - 0, 0, 211, 212, 57, 185, 58, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 183, 212, 212, 45, - 50, 212, 212, 183, 182, 181, 212, 0, 212, 212, - 212, 212, 158, 155, 31, 155, 26, 37, 154, 160, - 152, 150, 158, 144, 147, 152, 146, 212, 212, 212, - 212, 75, 212, 78, 81, 188, 59, 212, 75, 69, - 0, 78, 0, 82, 212, 212, 212, 0, 153, 151, - 140, 142, 0, 138, 136, 140, 136, 137, 132, 0, - 131, 0, 130, 136, 127, 134, 128, 101, 173, 172, - 212, 102, 105, 141, 94, 97, 0, 99, 0, 137, - - 132, 120, 130, 129, 118, 127, 128, 89, 84, 83, - 93, 86, 212, 0, 0, 86, 0, 86, 0, 80, - 88, 91, 0, 0, 77, 87, 0, 84, 0, 76, - 75, 83, 73, 76, 0, 57, 0, 47, 0, 35, - 0, 0, 212, 138, 140, 145, 150, 153, 155, 158, - 161 - } ; - -static const flex_int16_t yy_def[152] = - { 0, - 143, 1, 143, 143, 143, 143, 144, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 145, 143, 143, - 143, 143, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 143, 143, 143, - 143, 143, 143, 144, 146, 146, 147, 143, 143, 143, - 148, 143, 149, 143, 143, 143, 143, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 146, 143, 143, - 143, 144, 144, 147, 143, 143, 150, 143, 151, 145, - - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 143, 150, 151, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 0, 143, 143, 143, 143, 143, 143, 143, - 143 - } ; - -static const flex_int16_t yy_nxt[271] = - { 0, - 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, - 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 28, 40, 28, 28, 41, 42, 43, 44, - 45, 28, 46, 47, 48, 49, 50, 51, 52, 52, - 55, 93, 56, 59, 59, 64, 71, 64, 64, 64, - 64, 74, 76, 60, 142, 61, 52, 52, 72, 75, - 88, 62, 56, 90, 77, 91, 96, 96, 78, 141, - 57, 94, 95, 95, 95, 98, 98, 64, 63, 64, - - 64, 64, 64, 90, 55, 91, 56, 55, 140, 56, - 57, 95, 95, 95, 96, 96, 98, 98, 117, 139, - 138, 137, 136, 135, 134, 133, 132, 127, 131, 130, - 129, 128, 127, 126, 57, 125, 124, 57, 54, 54, - 54, 54, 54, 68, 68, 89, 89, 89, 89, 89, - 92, 92, 92, 92, 92, 97, 97, 99, 99, 114, - 114, 114, 115, 115, 115, 123, 122, 121, 120, 119, - 118, 117, 116, 94, 113, 113, 82, 112, 111, 110, - 109, 82, 108, 107, 106, 105, 104, 103, 102, 101, - 100, 82, 91, 87, 86, 85, 84, 83, 82, 81, - - 80, 79, 73, 70, 69, 67, 66, 65, 58, 53, - 143, 3, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 - } ; - -static const flex_int16_t yy_chk[271] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, - 7, 57, 7, 20, 20, 21, 35, 21, 21, 21, - 21, 37, 38, 20, 140, 20, 52, 52, 35, 37, - 54, 20, 54, 55, 38, 55, 60, 60, 38, 138, - 7, 57, 59, 59, 59, 62, 62, 64, 20, 64, - - 64, 64, 64, 88, 92, 88, 92, 93, 136, 93, - 54, 95, 95, 95, 96, 96, 98, 98, 134, 133, - 132, 131, 130, 128, 126, 125, 122, 121, 120, 118, - 116, 112, 111, 110, 92, 109, 108, 93, 144, 144, - 144, 144, 144, 145, 145, 146, 146, 146, 146, 146, - 147, 147, 147, 147, 147, 148, 148, 149, 149, 150, - 150, 150, 151, 151, 151, 107, 106, 105, 104, 103, - 102, 101, 100, 94, 90, 89, 87, 86, 85, 84, - 83, 81, 79, 78, 77, 76, 75, 74, 72, 71, - 70, 69, 56, 47, 46, 45, 44, 43, 42, 41, - - 40, 39, 36, 34, 33, 26, 25, 24, 17, 6, - 3, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 - } ; - -/* Table of booleans, true if rule could match eol. */ -static const flex_int32_t yy_rule_can_match_eol[63] = - { 0, -1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, }; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "../../src/yacc_stuff/tokenizer.lpp" -#line 2 "../../src/yacc_stuff/tokenizer.lpp" -#include -#include -#include -int token; - -#line 534 "../../src/yacc_stuff/tokenizer.cpp" -#line 535 "../../src/yacc_stuff/tokenizer.cpp" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy ( char *, const char *, int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen ( const char * ); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -#define ECHO LexerOutput( yytext, yyleng ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ -\ - if ( (int)(result = LexerInput( (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) LexerError( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 -#define YY_DECL int yyFlexLexer::yylex() -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK /*LINTED*/break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin.rdbuf(std::cin.rdbuf()); - - if ( ! yyout ) - yyout.rdbuf(std::cout.rdbuf()); - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - { -#line 11 "../../src/yacc_stuff/tokenizer.lpp" - -#line 669 "../../src/yacc_stuff/tokenizer.cpp" - - while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 144 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 212 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { - int yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - - yylineno++; -; - } - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -/* rule 1 can match eol */ -YY_RULE_SETUP -#line 12 "../../src/yacc_stuff/tokenizer.lpp" -{/*Skip spaces tabs, and line feeds*/}; - YY_BREAK -case 2: -/* rule 2 can match eol */ -YY_RULE_SETUP -#line 14 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_str; return token; - YY_BREAK -case 3: -/* rule 3 can match eol */ -YY_RULE_SETUP -#line 15 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_err; return token; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 17 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_op; return token; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 19 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_literal; return token; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 21 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_break; return token; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 22 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_continue; return token; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 23 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_do; return token; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 24 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_else; return token; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 25 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_for; return token; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 26 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_foreach; return token; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 27 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_goto; return token; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 28 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_if; return token; - YY_BREAK -case 14: -YY_RULE_SETUP -#line 29 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_while; return token; - YY_BREAK -case 15: -YY_RULE_SETUP -#line 31 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_key_switch; return token; - YY_BREAK -case 16: -YY_RULE_SETUP -#line 33 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_return_type; return token; - YY_BREAK -case 17: -YY_RULE_SETUP -#line 34 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_fun; return token; - YY_BREAK -case 18: -YY_RULE_SETUP -#line 35 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_fun; return token; - YY_BREAK -case 19: -YY_RULE_SETUP -#line 36 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_extern; return token; - YY_BREAK -case 20: -YY_RULE_SETUP -#line 37 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_extern; return token; - YY_BREAK -case 21: -YY_RULE_SETUP -#line 38 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_identifier; return token; - YY_BREAK -case 22: -YY_RULE_SETUP -#line 39 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 23: -YY_RULE_SETUP -#line 40 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 24: -YY_RULE_SETUP -#line 41 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 25: -YY_RULE_SETUP -#line 42 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 26: -YY_RULE_SETUP -#line 43 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 27: -YY_RULE_SETUP -#line 44 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 28: -YY_RULE_SETUP -#line 45 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_number; return token; - YY_BREAK -case 29: -YY_RULE_SETUP -#line 48 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 30: -YY_RULE_SETUP -#line 49 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 31: -YY_RULE_SETUP -#line 50 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 32: -YY_RULE_SETUP -#line 51 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 33: -YY_RULE_SETUP -#line 52 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 34: -YY_RULE_SETUP -#line 53 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 35: -YY_RULE_SETUP -#line 54 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 36: -YY_RULE_SETUP -#line 55 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 37: -YY_RULE_SETUP -#line 56 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 38: -YY_RULE_SETUP -#line 57 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 39: -YY_RULE_SETUP -#line 58 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 40: -YY_RULE_SETUP -#line 59 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 41: -YY_RULE_SETUP -#line 60 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 42: -YY_RULE_SETUP -#line 61 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 43: -YY_RULE_SETUP -#line 62 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 44: -YY_RULE_SETUP -#line 63 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 45: -YY_RULE_SETUP -#line 64 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 46: -YY_RULE_SETUP -#line 65 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 47: -YY_RULE_SETUP -#line 66 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 48: -YY_RULE_SETUP -#line 67 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 49: -YY_RULE_SETUP -#line 68 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 50: -YY_RULE_SETUP -#line 69 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 51: -YY_RULE_SETUP -#line 70 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 52: -YY_RULE_SETUP -#line 71 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 53: -YY_RULE_SETUP -#line 72 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 54: -YY_RULE_SETUP -#line 73 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 55: -YY_RULE_SETUP -#line 74 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 56: -YY_RULE_SETUP -#line 75 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 57: -YY_RULE_SETUP -#line 76 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 58: -YY_RULE_SETUP -#line 77 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 59: -YY_RULE_SETUP -#line 78 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case 60: -YY_RULE_SETUP -#line 79 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_syntax; return token; - YY_BREAK -case YY_STATE_EOF(INITIAL): -#line 80 "../../src/yacc_stuff/tokenizer.lpp" -{token = tok_eof; return token;} - YY_BREAK -case 61: -/* rule 61 can match eol */ -YY_RULE_SETUP -#line 81 "../../src/yacc_stuff/tokenizer.lpp" -token = tok_err; return token; - YY_BREAK -case 62: -YY_RULE_SETUP -#line 82 "../../src/yacc_stuff/tokenizer.lpp" -ECHO; - YY_BREAK -#line 1054 "../../src/yacc_stuff/tokenizer.cpp" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin.rdbuf(); - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of user's declarations */ -} /* end of yylex */ - -/* The contents of this function are C++ specific, so the () macro is not used. - * This constructor simply maintains backward compatibility. - * DEPRECATED - */ -yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ): - yyin(arg_yyin ? arg_yyin->rdbuf() : std::cin.rdbuf()), - yyout(arg_yyout ? arg_yyout->rdbuf() : std::cout.rdbuf()) -{ - ctor_common(); -} - -/* The contents of this function are C++ specific, so the () macro is not used. - */ -yyFlexLexer::yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout ): - yyin(arg_yyin.rdbuf()), - yyout(arg_yyout.rdbuf()) -{ - ctor_common(); -} - -/* The contents of this function are C++ specific, so the () macro is not used. - */ -void yyFlexLexer::ctor_common() -{ - yy_c_buf_p = 0; - yy_init = 0; - yy_start = 0; - yy_flex_debug = 0; - yylineno = 1; // this will only get updated if %option yylineno - - yy_did_buffer_switch_on_eof = 0; - - yy_looking_for_trail_begin = 0; - yy_more_flag = 0; - yy_more_len = 0; - yy_more_offset = yy_prev_more_offset = 0; - - yy_start_stack_ptr = yy_start_stack_depth = 0; - yy_start_stack = NULL; - - yy_buffer_stack = NULL; - yy_buffer_stack_top = 0; - yy_buffer_stack_max = 0; - - yy_state_buf = 0; - -} - -/* The contents of this function are C++ specific, so the () macro is not used. - */ -yyFlexLexer::~yyFlexLexer() -{ - delete [] yy_state_buf; - yyfree( yy_start_stack ); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yyfree( yy_buffer_stack ); -} - -/* The contents of this function are C++ specific, so the () macro is not used. - */ -void yyFlexLexer::switch_streams( std::istream& new_in, std::ostream& new_out ) -{ - // was if( new_in ) - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); - - // was if( new_out ) - yyout.rdbuf(new_out.rdbuf()); -} - -/* The contents of this function are C++ specific, so the () macro is not used. - */ -void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) -{ - if( ! new_in ) { - new_in = &yyin; - } - - if ( ! new_out ) { - new_out = &yyout; - } - - switch_streams(*new_in, *new_out); -} - -#ifdef YY_INTERACTIVE -int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) -#else -int yyFlexLexer::LexerInput( char* buf, int max_size ) -#endif -{ - if ( yyin.eof() || yyin.fail() ) - return 0; - -#ifdef YY_INTERACTIVE - yyin.get( buf[0] ); - - if ( yyin.eof() ) - return 0; - - if ( yyin.bad() ) - return -1; - - return 1; - -#else - (void) yyin.read( buf, max_size ); - - if ( yyin.bad() ) - return -1; - else - return yyin.gcount(); -#endif -} - -void yyFlexLexer::LexerOutput( const char* buf, int size ) -{ - (void) yyout.write( buf, size ); -} - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -int yyFlexLexer::yy_get_next_buffer() -{ - char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - char *source = (yytext_ptr); - int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc( (void *) b->yy_ch_buf, - (yy_size_t) (b->yy_buf_size + 2) ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( - (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - /* "- 2" to take care of EOB's */ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - yy_state_type yyFlexLexer::yy_get_previous_state() -{ - yy_state_type yy_current_state; - char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 144 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) -{ - int yy_is_jam; - char *yy_cp = (yy_c_buf_p); - - YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 144 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 143); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_UNPUT - void yyFlexLexer::yyunput( int c, char* yy_bp) -{ - char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - int number_to_move = (yy_n_chars) + 2; - char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - if ( c == '\n' ){ - --yylineno; - } - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} -#endif - - int yyFlexLexer::yyinput() -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - if ( c == '\n' ) - - yylineno++; -; - - return c; -} - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyFlexLexer::yyrestart( std::istream& input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_init_buffer( YY_CURRENT_BUFFER, input_file ); - yy_load_buffer_state( ); -} - -/** Delegate to the new version that takes an istream reference. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ -void yyFlexLexer::yyrestart( std::istream* input_file ) -{ - if( ! input_file ) { - input_file = &yyin; - } - yyrestart( *input_file ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - - void yyFlexLexer::yy_load_buffer_state() -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin.rdbuf(YY_CURRENT_BUFFER_LVALUE->yy_input_file); - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream& file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; -} - -/** Delegate creation of buffers to the new version that takes an istream reference. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) -{ - return yy_create_buffer( *file, size ); -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree( (void *) b->yy_ch_buf ); - - yyfree( (void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream& file ) - -{ - int oerrno = errno; - - yy_flush_buffer( b ); - - b->yy_input_file = file.rdbuf(); - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yyFlexLexer::yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -void yyFlexLexer::yyensure_buffer_stack(void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - - void yyFlexLexer::yy_push_state( int _new_state ) -{ - if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) - { - yy_size_t new_size; - - (yy_start_stack_depth) += YY_START_STACK_INCR; - new_size = (yy_size_t) (yy_start_stack_depth) * sizeof( int ); - - if ( ! (yy_start_stack) ) - (yy_start_stack) = (int *) yyalloc( new_size ); - - else - (yy_start_stack) = (int *) yyrealloc( - (void *) (yy_start_stack), new_size ); - - if ( ! (yy_start_stack) ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; - - BEGIN(_new_state); -} - - void yyFlexLexer::yy_pop_state() -{ - if ( --(yy_start_stack_ptr) < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); -} - - int yyFlexLexer::yy_top_state() -{ - return (yy_start_stack)[(yy_start_stack_ptr) - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -void yyFlexLexer::LexerError( const char* msg ) -{ - std::cerr << msg << std::endl; - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, const char * s2, int n ) -{ - - int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (const char * s ) -{ - int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return malloc(size); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return realloc(ptr, size); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 82 "../../src/yacc_stuff/tokenizer.lpp" - - -int yyFlexLexer::yywrap(){return 1;} - -- Gitee From bb76671218fb16294cfa6acf00f99e5256e746ea Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 09:09:35 +0800 Subject: [PATCH 28/98] Fix the return value of main --- src/CompileUnit.cpp | 2 ++ src/CompileUnit.h | 2 ++ src/ast/CodeBlockAST.cpp | 11 ++++++++--- src/ast/PrototypeAST.cpp | 6 +++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 2dee039..fde3d58 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -14,6 +14,7 @@ #include #include +#include "ast/ClassAST.h" #include "ast/ExprAST.h" #include "ast/ExternAST.h" #include "ast/FunctionAST.h" @@ -133,6 +134,7 @@ void CompileUnit::compile() } } std::cout << "Start codegen:" << name << std::endl; + // todo:Class的Codegen std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); gVar_iter != globalVariables.end(); gVar_iter++) { diff --git a/src/CompileUnit.h b/src/CompileUnit.h index f4fd777..cde7dfe 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -19,6 +19,7 @@ class TypeAST; class FunctionAST; class ExternAST; class VariableDefExprAST; +class ClassAST; class CompileUnit { public: @@ -36,6 +37,7 @@ class CompileUnit llvm::Module * module; std::vector tokenList; std::vector::iterator icurTok; + std::map classes; std::map globalVariables; std::map functions; std::map externs; diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index e303595..ba5ca3e 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -75,10 +75,15 @@ llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) // builder->CreateRetVoid(); // todo:待处理,main特判 // std::cout << name << std::string(function->getName()) << std::endl; if (parent == nullptr) { - if (std::string(function->getName()) != "main") + if (std::string(function->getName()) != "main") { builder->CreateRetVoid(); - else - builder->CreateRet(0); + } else { + 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/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index ae05a17..fc13a94 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -140,7 +140,11 @@ llvm::Function *PrototypeAST::Codegen() } } else { - returnType = llvm::Type::getVoidTy(*unit->context); + if (name != "main") { + returnType = llvm::Type::getVoidTy(*unit->context); + } else { + returnType = llvm::IntegerType::get(*unit->context, 32); + } } llvm::FunctionType *FT = -- Gitee From 5ce33c77e13be31ca89202a58556897c38f63995 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 10:21:27 +0800 Subject: [PATCH 29/98] Add Codegen for class --- src/ast/ClassAST.cpp | 2 ++ src/ast/ClassAST.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 2ed8fdb..83db3da 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -16,3 +16,5 @@ ClassAST::~ClassAST() { // TODO Auto-generated destructor stub } + +llvm::Type *ClassAST::Codegen() { return nullptr; } diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 13219f6..d8376ae 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -15,6 +15,7 @@ class ClassAST : public BaseAST public: ClassAST(CompileUnit *unit); virtual ~ClassAST(); + llvm::Type *Codegen(); }; #endif /* SRC_AST_CLASSAST_H_ */ -- Gitee From 9aa21c0b414d924e704bfbaf955a7f70c5cbaf44 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 24 Feb 2021 13:07:05 +0800 Subject: [PATCH 30/98] changed AC_PREREQ to 2.69 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1a82905..435e077 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], -- Gitee From 1fc8469289d89c40eaccece30c4cf0c881d9259d Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 13:08:18 +0800 Subject: [PATCH 31/98] Implement Multi-value expression --- src/CompileUnit.cpp | 7 +----- src/ast/AssignmentAST.cpp | 40 +++++++++++++++++++++-------- src/ast/AssignmentAST.h | 14 +++++------ src/ast/BinaryExprAST.cpp | 46 ++++++++++++++++++---------------- src/ast/BinaryExprAST.h | 2 +- src/ast/BoolExprAST.cpp | 12 +++++---- src/ast/BoolExprAST.h | 4 +-- src/ast/CallExprAST.cpp | 28 +++++++++++++-------- src/ast/CallExprAST.h | 2 +- src/ast/ExprAST.cpp | 35 ++++++++++++++++---------- src/ast/ExprAST.h | 5 ++-- src/ast/IfExprAST.cpp | 15 +++++++---- src/ast/IfExprAST.h | 10 ++++---- src/ast/IntExprAST.cpp | 10 +++++--- src/ast/IntExprAST.h | 2 +- src/ast/UnaryExprAST.cpp | 15 ++++++++--- src/ast/UnaryExprAST.h | 6 ++--- src/ast/VariableDefExprAST.cpp | 41 +++++++++++++++++------------- src/ast/VariableDefExprAST.h | 3 ++- src/ast/VariableExprAST.cpp | 14 ++++++++--- src/ast/VariableExprAST.h | 8 +++--- src/ast/WhileExprAST.cpp | 13 +++++++--- src/ast/WhileExprAST.h | 12 ++++----- 23 files changed, 207 insertions(+), 137 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index fde3d58..29c8a45 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -138,12 +138,7 @@ void CompileUnit::compile() std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); gVar_iter != globalVariables.end(); gVar_iter++) { - llvm::Value *gVarValue = gVar_iter->second->Codegen(nullptr); - globalVariablesValue.insert( - std::pair>( - gVar_iter->second->idName, - std::pair(gVar_iter->second->type, - gVarValue))); + gVar_iter->second->Codegen(nullptr); } std::map::iterator extern_iter; for (extern_iter = externs.begin(); extern_iter != externs.end(); diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index 0c1cbbe..68317aa 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -10,8 +10,8 @@ #include "CodeBlockAST.h" #include "VariableExprAST.h" -AssignmentAST::AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, - ExprAST *RHS) +AssignmentAST::AssignmentAST(CompileUnit * unit, + std::vector LHS, ExprAST *RHS) : ExprAST(unit) { this->LHS = LHS; @@ -23,20 +23,38 @@ AssignmentAST::~AssignmentAST() // TODO Auto-generated destructor stub } -AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, - CodeBlockAST * codeblock, - const std::string &LHS) +AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, + CodeBlockAST *codeblock) { + std::vector LHS; //左侧变量 + Token token = *unit->icurTok; + while (true) { + if (token.type == tok_identifier) { + LHS.push_back( + new VariableExprAST(unit, codeblock, token.tokenValue)); + } else if (token.type == tok_syntax) { + if (token.tokenValue == "=") { + break; + } + } + token = unit->next_tok(); + } unit->next_tok(); - return new AssignmentAST(unit, new VariableExprAST(unit, codeblock, LHS), + return new AssignmentAST(unit, LHS, ExprAST::ParseExpression(unit, codeblock, false)); } -llvm::Value *AssignmentAST::Codegen(llvm::IRBuilder<> *builder) +std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Value *value = RHS->Codegen(builder); - - builder->CreateStore(value, LHS->getAlloca()); // todo:对函数参数赋值 - return value; + std::vector RHSV = RHS->Codegen(builder); + 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++) { + builder->CreateStore(RHSV[i], + LHS[i]->getAlloca()); // todo:对函数参数赋值 + } + return std::vector(); } diff --git a/src/ast/AssignmentAST.h b/src/ast/AssignmentAST.h index b4aac75..c3b12a9 100644 --- a/src/ast/AssignmentAST.h +++ b/src/ast/AssignmentAST.h @@ -14,14 +14,14 @@ class VariableExprAST; class AssignmentAST : public ExprAST { public: - AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, ExprAST *RHS); + AssignmentAST(CompileUnit *unit, std::vector 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; + std::vector Codegen(llvm::IRBuilder<> *builder); + static AssignmentAST * ParseAssignment(CompileUnit * unit, + CodeBlockAST *codeblock); + std::vector LHS; //左侧变量 + ExprAST * RHS; }; #endif /* SRC_AST_ASSIGNMENTAST_H_ */ diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index fb0f0f8..457fdd9 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -20,17 +20,17 @@ BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, this->type = LHS->type; //整理此段代码,将操作抽象 if (binOP == "==") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else if (binOP == "!=") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else if (binOP == ">") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else if (binOP == "<") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else if (binOP == ">=") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else if (binOP == "<=") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } } @@ -39,34 +39,38 @@ BinaryExprAST::~BinaryExprAST() // TODO Auto-generated destructor stub } -llvm::Value *BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) { - llvm::Value *L = LHS->Codegen(builder); - llvm::Value *R = RHS->Codegen(builder); - if (L == nullptr || R == 0) - return 0; + std::vector L = LHS->Codegen(builder); + std::vector R = RHS->Codegen(builder); + std::vector result; + if (L.size() != 1 || R.size() != 1) { + CompileError e("Bin Expr length != 1"); + throw e; + } if (binOP == "+") { - return builder->CreateAdd(L, R); + result.push_back(builder->CreateAdd(L[0], R[0])); } else if (binOP == "-") { - return builder->CreateSub(L, R); + result.push_back(builder->CreateSub(L[0], R[0])); } else if (binOP == "*") { - return builder->CreateMul(L, R); + result.push_back(builder->CreateMul(L[0], R[0])); } else if (binOP == "/") { - return builder->CreateFDiv(L, R); + result.push_back(builder->CreateFDiv(L[0], R[0])); } else if (binOP == "==") { - return builder->CreateICmpEQ(L, R); + result.push_back(builder->CreateICmpEQ(L[0], R[0])); } else if (binOP == "!=") { - return builder->CreateICmpNE(L, R); + result.push_back(builder->CreateICmpNE(L[0], R[0])); } else if (binOP == ">") { - return builder->CreateICmpSGT(L, R); + result.push_back(builder->CreateICmpSGT(L[0], R[0])); } else if (binOP == "<") { - return builder->CreateICmpSLT(L, R); + result.push_back(builder->CreateICmpSLT(L[0], R[0])); } else if (binOP == ">=") { - return builder->CreateICmpSGE(L, R); + result.push_back(builder->CreateICmpSGE(L[0], R[0])); } else if (binOP == "<=") { - return builder->CreateICmpSLE(L, R); + result.push_back(builder->CreateICmpSLE(L[0], R[0])); } else { CompileError e("Unknown operator:" + binOP); throw e; } + return result; } diff --git a/src/ast/BinaryExprAST.h b/src/ast/BinaryExprAST.h index 7f6113d..786ce3a 100644 --- a/src/ast/BinaryExprAST.h +++ b/src/ast/BinaryExprAST.h @@ -16,7 +16,7 @@ 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; diff --git a/src/ast/BoolExprAST.cpp b/src/ast/BoolExprAST.cpp index 480ad56..5b9f7d4 100644 --- a/src/ast/BoolExprAST.cpp +++ b/src/ast/BoolExprAST.cpp @@ -11,7 +11,7 @@ BoolExprAST::BoolExprAST(CompileUnit *unit, bool val) : ExprAST(unit) { this->val = val; - type = new TypeAST(unit, "bool"); + type.push_back(new TypeAST(unit, "bool")); } BoolExprAST::~BoolExprAST() @@ -19,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 09ee1a2..ada577d 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 058d395..5c7f55b 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -29,21 +29,27 @@ CallExprAST::~CallExprAST() // TODO Auto-generated destructor stub } -llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { + std::vector result; std::vector argsV; for (unsigned i = 0, e = args.size(); i != e; ++i) { - argsV.push_back(args[i]->Codegen(builder)); + std::vector r = args[i]->Codegen(builder); + if (r.size() != 1) { + CompileError e("Multi/Void type in args found."); + throw e; + } + argsV.push_back(r[0]); } std::vector argStr; for (ExprAST *ast : args) { - if (ast->type == nullptr) { - CompileError e("Void type found."); + if (ast->type.size() != 1) { + CompileError e("Multi/Void type found."); throw e; } - argStr.push_back(ast->type); + argStr.push_back(ast->type[0]); } std::string dname = demangle(callee, argStr); if (callee == "main") { @@ -65,14 +71,16 @@ llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Function " + dname + " not found."); throw e; } - if (proto->returnDirectly) { - type = proto->returnTypes[0]; - } + type = proto->returnTypes; + llvm::Function *CalleeF = unit->module->getFunction(dname); if (CalleeF == 0) { CompileError e("Function " + dname + " not found in LLVM IR"); throw e; } - - return builder->CreateCall(CalleeF, argsV); + llvm::Value *retD = builder->CreateCall(CalleeF, argsV); + if (proto->returnDirectly) { + result.push_back(retD); + } + return result; } diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index 3cfdd5b..3f1eae0 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -16,7 +16,7 @@ class CallExprAST : public ExprAST CallExprAST(CompileUnit *unit, const std::string &callee, std::vector &args); virtual ~CallExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); std::string callee; std::vector args; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 93151c3..4ea77f5 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -37,11 +37,7 @@ int GetTokPrecedence(Token tok) return TokPrec; } -ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) -{ - this->type = nullptr; - // TODO Auto-generated constructor stub -} +ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) { subExpr = nullptr; } ExprAST::~ExprAST() { @@ -99,10 +95,6 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) VariableDefExprAST *varAST = VariableDefExprAST::ParseVar(unit, codeblock); return varAST; - } else if (token.tokenValue == "=") { - token = unit->next_tok(); - //赋值 - return AssignmentAST::ParseAssignment(unit, codeblock, idName); } else if (token.tokenValue == "(") { //函数调用 token = unit->next_tok(); @@ -125,9 +117,22 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return new CallExprAST(unit, idName, args); } else { - //变量 - unit->next_tok(); - return new VariableExprAST(unit, codeblock, idName); + //变量或赋值 + int i = 0; + while (true) { + token = *(unit->icurTok + i); + if (token.type == tok_syntax) { + if (token.tokenValue == "=") { + return AssignmentAST::ParseAssignment(unit, codeblock); + break; + } else if (token.tokenValue != ",") { + //变量 + unit->next_tok(); + return new VariableExprAST(unit, codeblock, idName); + } + } + i++; + } } break; } @@ -179,8 +184,12 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (WhileExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } + Token token = *(unit->icurTok); + if (token.type == tok_syntax && token.tokenValue == ",") { + unit->next_tok(); + result->subExpr = ExprAST::ParseExpression(unit, codeblock, false); + } if (root) { - Token token = *(unit->icurTok); if (token.type != tok_syntax || token.tokenValue != ";") { CompileError e("丟失分号: \"" + token.dump() + "\" 前"); throw e; diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index 4d54643..935b974 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -9,11 +9,12 @@ 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; static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock); - TypeAST * type; + std::vector type; + ExprAST * subExpr; }; #endif /* COMPILER_AST_ASTEXPR_H_ */ diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index 4bfbd50..92de882 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -38,16 +38,21 @@ IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *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->Codegen(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 { @@ -57,5 +62,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 1919a20..b34dfed 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 3e1b3b0..80fb6e3 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -12,8 +12,8 @@ IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) { - this->val = val; - this->type = new TypeAST(unit, "int"); + this->val = val; + this->type.push_back(new TypeAST(unit, "int")); } IntExprAST::~IntExprAST() @@ -21,9 +21,11 @@ IntExprAST::~IntExprAST() // TODO Auto-generated destructor stub } -llvm::Value *IntExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector IntExprAST::Codegen(llvm::IRBuilder<> *builder) { + std::vector result; llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 64); llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); - return res; + result.push_back(res); + return result; } diff --git a/src/ast/IntExprAST.h b/src/ast/IntExprAST.h index 5f3d289..33c7578 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/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 89eda3d..392ca96 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -16,7 +16,7 @@ UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, this->op = op; this->operand = operand; if (op == "!") { - this->type = new TypeAST(unit, "bool"); + this->type.push_back(new TypeAST(unit, "bool")); } else { CompileError e("一元运算符:" + op + "未实现"); throw e; @@ -28,10 +28,17 @@ UnaryExprAST::~UnaryExprAST() // TODO Auto-generated destructor stub } -llvm::Value *UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) { + std::vector result; if (op == "!") { - return builder->CreateXor(operand->Codegen(builder), 1); + + std::vector Rs = operand->Codegen(builder); + if (Rs.size() != 1) { + CompileError e("Unary Expr length != 1"); + throw e; + } + result.push_back(builder->CreateXor(Rs[0], 1)); } - return nullptr; + return result; } diff --git a/src/ast/UnaryExprAST.h b/src/ast/UnaryExprAST.h index 79ec11b..2b080e0 100644 --- a/src/ast/UnaryExprAST.h +++ b/src/ast/UnaryExprAST.h @@ -15,9 +15,9 @@ class UnaryExprAST : public ExprAST public: UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand); virtual ~UnaryExprAST(); - llvm::Value *Codegen(llvm::IRBuilder<> *builder); - std::string op; - ExprAST * operand; + std::vector Codegen(llvm::IRBuilder<> *builder); + std::string op; + ExprAST * operand; }; #endif /* SRC_AST_UNARYEXPRAST_H_ */ diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index f024640..b5f5867 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -20,12 +20,12 @@ VariableDefExprAST::VariableDefExprAST(CompileUnit * unit, ExprAST *initValue, int argID) : ExprAST(unit) { - this->codeblock = codeblock; - this->idName = idName; - this->type = type; - this->alloca = nullptr; - this->initValue = initValue; - this->argID = argID; + this->codeblock = codeblock; + this->idName = idName; + this->alloca = nullptr; + this->initValue = initValue; + this->argID = argID; + this->variableType = type; } VariableDefExprAST::~VariableDefExprAST() @@ -43,23 +43,24 @@ static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, return builder.CreateAlloca(typeAST->Codegen(), 0, VarName.c_str()); } -llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector +VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) { if (codeblock == nullptr) { llvm::GlobalVariable *gVar = new llvm::GlobalVariable( - *unit->module, type->Codegen(), false, + *unit->module, variableType->Codegen(), false, llvm::GlobalValue::ExternalLinkage, nullptr, idName); // todo:初始填0 - if (type->name == "int") { + 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 (type->name == "double") { + } 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 (type->name == "bool") { + } else if (variableType->name == "bool") { llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 1); llvm::ConstantInt *res = llvm::ConstantInt::get(itype, 0, true); @@ -67,25 +68,31 @@ llvm::Value *VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) } unit->globalVariablesValue.insert( std::pair>( - idName, std::pair(type, gVar))); + idName, + std::pair(variableType, gVar))); //全局变量 } else { //局部变量 llvm::BasicBlock *insertBlock = builder->GetInsertBlock(); llvm::Function * function = insertBlock->getParent(); - alloca = CreateEntryBlockAlloca(unit, function, idName, type); + alloca = CreateEntryBlockAlloca(unit, function, idName, variableType); if (argID != -1) { builder->CreateStore(function->getArg(argID), alloca); } if (initValue != nullptr) { - builder->CreateStore(initValue->Codegen(builder), alloca); + std::vector ivalues = initValue->Codegen(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(type, alloca))); + idName, std::pair(variableType, + alloca))); } - return nullptr; + return std::vector(); } VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, diff --git a/src/ast/VariableDefExprAST.h b/src/ast/VariableDefExprAST.h index 650092c..ba8dfa0 100644 --- a/src/ast/VariableDefExprAST.h +++ b/src/ast/VariableDefExprAST.h @@ -18,11 +18,12 @@ class VariableDefExprAST : public ExprAST virtual ~VariableDefExprAST(); static VariableDefExprAST *ParseVar(CompileUnit * unit, CodeBlockAST *codeblock); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); CodeBlockAST * codeblock; std::string idName; llvm::AllocaInst * alloca; ExprAST * initValue; + TypeAST * variableType; int argID; //函数的参数号,函数内变量为-1 }; diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index a4dca0f..9bd2cb6 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -40,7 +40,7 @@ llvm::Value *VariableExprAST::getAlloca() curCodeBlock = curCodeBlock->parent; } else { alloca = varAST->second.second; - type = varAST->second.first; + type.push_back(varAST->second.first); return alloca; } } @@ -50,13 +50,19 @@ llvm::Value *VariableExprAST::getAlloca() CompileError e("can't find variable:" + idName); throw e; } else { - type = gVar->second.first; + type.push_back(gVar->second.first); alloca = gVar->second.second; return alloca; } } -llvm::Value *VariableExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector VariableExprAST::Codegen(llvm::IRBuilder<> *builder) { - return builder->CreateLoad(getAlloca()); + std::vector result; + result.push_back(builder->CreateLoad(getAlloca())); + if (subExpr != nullptr) { + std::vector subResult = subExpr->Codegen(builder); + result.insert(result.end(), subResult.begin(), subResult.end()); + } + return result; } diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index aaf605b..5b4de5e 100644 --- a/src/ast/VariableExprAST.h +++ b/src/ast/VariableExprAST.h @@ -15,10 +15,10 @@ class VariableExprAST : public ExprAST VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, const std::string &idName); virtual ~VariableExprAST(); - llvm::Value * getAlloca(); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - std::string idName; - CodeBlockAST *codeblock; + llvm::Value * getAlloca(); + std::vector Codegen(llvm::IRBuilder<> *builder); + std::string idName; + CodeBlockAST * codeblock; private: llvm::Value *alloca; diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 418f8a9..c761fec 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -6,6 +6,7 @@ */ #include "WhileExprAST.h" +#include "../CompileError.hpp" #include "CodeBlockAST.h" WhileExprAST::WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock, @@ -22,7 +23,7 @@ WhileExprAST::~WhileExprAST() // TODO Auto-generated destructor stub } -llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) +std::vector WhileExprAST::Codegen(llvm::IRBuilder<> *builder) { llvm::Function * function = builder->GetInsertBlock()->getParent(); llvm::BasicBlock *MergeBB = @@ -35,15 +36,19 @@ llvm::Value *WhileExprAST::Codegen(llvm::IRBuilder<> *builder) // builder->SetInsertPoint(body->endBB); builder->SetInsertPoint(condBB); - llvm::Value *conditionValue = condition->Codegen(builder); - builder->CreateCondBr(conditionValue, bodyBB, MergeBB); + std::vector conditionValues = condition->Codegen(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 nullptr; + return std::vector(); } WhileExprAST *WhileExprAST::ParseWhileExpr(CompileUnit * unit, diff --git a/src/ast/WhileExprAST.h b/src/ast/WhileExprAST.h index 8bc7046..543da09 100644 --- a/src/ast/WhileExprAST.h +++ b/src/ast/WhileExprAST.h @@ -16,12 +16,12 @@ class WhileExprAST : public ExprAST WhileExprAST(CompileUnit *unit, CodeBlockAST *codeblock, ExprAST *condition, CodeBlockAST *body); virtual ~WhileExprAST(); - static WhileExprAST *ParseWhileExpr(CompileUnit * unit, - CodeBlockAST *parent); - llvm::Value * Codegen(llvm::IRBuilder<> *builder); - ExprAST * condition; - CodeBlockAST * body; - CodeBlockAST * parent; + static WhileExprAST * ParseWhileExpr(CompileUnit * unit, + CodeBlockAST *parent); + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * condition; + CodeBlockAST * body; + CodeBlockAST * parent; }; #endif /* SRC_AST_WHILEEXPRAST_H_ */ -- Gitee From 2d985bcb2e3e914fe37fadd03e985a08cfec4593 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 15:55:21 +0800 Subject: [PATCH 32/98] Fix a bug in proto paser --- src/ast/PrototypeAST.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index fc13a94..e75ab4a 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -58,7 +58,6 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) while (true) { token = unit->next_tok(); if (token.type == tok_syntax && token.tokenValue == ",") { - token = unit->next_tok(); continue; } if (token.type == tok_syntax && token.tokenValue == ")") { -- Gitee From 194686a40b04b020a1367e1bc98a6e51fc72c9c3 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 16:14:37 +0800 Subject: [PATCH 33/98] Fix a bug in CallExprAST --- src/Makefile.am | 2 +- src/ast/CallExprAST.cpp | 21 ++++----------------- src/ast/CallExprAST.h | 7 +++---- src/ast/EmptyExprAST.cpp | 23 +++++++++++++++++++++++ src/ast/EmptyExprAST.h | 21 +++++++++++++++++++++ src/ast/ExprAST.cpp | 25 ++++++------------------- src/ast/VariableExprAST.cpp | 2 ++ 7 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 src/ast/EmptyExprAST.cpp create mode 100644 src/ast/EmptyExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index 2d33769..d8c483c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ 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/ClassAST.cpp ast/CodeBlockAST.cpp ast/ExprAST.cpp ast/ExternAST.cpp\ + ast/CallExprAST.cpp ast/ClassAST.cpp ast/CodeBlockAST.cpp ast/EmptyExprAST.cpp ast/ExprAST.cpp ast/ExternAST.cpp\ ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.cpp ast/PrototypeAST.cpp\ ast/TypeAST.cpp ast/VariableDefExprAST.cpp ast/VariableExprAST.cpp ast/WhileExprAST.cpp\ ast/UnaryExprAST.cpp yacc_stuff/tokenizer.lpp diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 5c7f55b..0ed28ff 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -15,7 +15,7 @@ #include "../utils.h" CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, - std::vector &args) + ExprAST *args) : ExprAST(unit) { this->callee = callee; @@ -32,24 +32,11 @@ CallExprAST::~CallExprAST() std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; - std::vector argsV; - - for (unsigned i = 0, e = args.size(); i != e; ++i) { - std::vector r = args[i]->Codegen(builder); - if (r.size() != 1) { - CompileError e("Multi/Void type in args found."); - throw e; - } - argsV.push_back(r[0]); - } + std::vector argsV = args->Codegen(builder); std::vector argStr; - for (ExprAST *ast : args) { - if (ast->type.size() != 1) { - CompileError e("Multi/Void type found."); - throw e; - } - argStr.push_back(ast->type[0]); + for (TypeAST *ast : args->type) { + argStr.push_back(ast); } std::string dname = demangle(callee, argStr); if (callee == "main") { diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index 3f1eae0..2c5531b 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(); 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/EmptyExprAST.cpp b/src/ast/EmptyExprAST.cpp new file mode 100644 index 0000000..0191eab --- /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 0000000..b096ba5 --- /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 4ea77f5..9b5df3d 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -6,6 +6,7 @@ #include "BoolExprAST.h" #include "CallExprAST.h" #include "CodeBlockAST.h" +#include "EmptyExprAST.h" #include "IfExprAST.h" #include "IntExprAST.h" #include "UnaryExprAST.h" @@ -76,8 +77,10 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) CompileError e("missing ')'"); throw e; } - token = unit->next_tok(); + unit->next_tok(); return result; + } else if (token.tokenValue == ")") { + return new EmptyExprAST(unit); } else { unit->next_tok(); return new UnaryExprAST(unit, token.tokenValue, @@ -97,24 +100,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return varAST; } else if (token.tokenValue == "(") { //函数调用 - token = unit->next_tok(); - token = unit->next_tok(); - std::vector args; - while (true) { - token = *unit->icurTok; - if (token.type == tok_syntax && token.tokenValue == ")") { - unit->next_tok(); - break; - } - if (token.type == tok_syntax && token.tokenValue == ",") { - continue; - } - - ExprAST *arg = ExprAST::ParseExpression(unit, codeblock, false); - args.push_back(arg); - // todo:异常处理 - } - + token = unit->next_tok(); + ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); return new CallExprAST(unit, idName, args); } else { //变量或赋值 diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 9bd2cb6..9c3bdef 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -62,7 +62,9 @@ std::vector VariableExprAST::Codegen(llvm::IRBuilder<> *builder) result.push_back(builder->CreateLoad(getAlloca())); 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; } -- Gitee From fd2d90a99620a73f4be065725cdb8b9462c08117 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 24 Feb 2021 16:44:33 +0800 Subject: [PATCH 34/98] fixed makefile bug --- .gitignore | 3 ++- configure.ac | 4 +++- src/Makefile.am | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 1114709..69e119b 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,5 @@ Makefile *.ll *.bc -*.s \ No newline at end of file +*.s +src/yacc_stuff/tokenizer.cpp diff --git a/configure.ac b/configure.ac index 435e077..3b4eb5d 100644 --- a/configure.ac +++ b/configure.ac @@ -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/src/Makefile.am b/src/Makefile.am index 2d33769..4db7261 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,4 +15,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 -- Gitee From 499161328d950099815a6cf658e1938471ad2c20 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 24 Feb 2021 16:55:44 +0800 Subject: [PATCH 35/98] Added token for class --- src/Token.cpp | 3 +++ src/Token.h | 3 ++- src/yacc_stuff/tokenizer.lpp | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Token.cpp b/src/Token.cpp index 166410f..744f0e0 100644 --- a/src/Token.cpp +++ b/src/Token.cpp @@ -96,6 +96,9 @@ 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"; } diff --git a/src/Token.h b/src/Token.h index 5eb9546..3944c6d 100644 --- a/src/Token.h +++ b/src/Token.h @@ -33,7 +33,8 @@ enum TokenType { tok_key_goto, tok_key_if, tok_key_while, - tok_key_switch + tok_key_switch, + tok_key_class }; class Token diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 2157e17..79ed137 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -30,6 +30,8 @@ while token = tok_key_while; return token case|switch token = tok_key_switch; return token; +class token = tok_key_class; return token; + -> token = tok_return_type; return token; fun token = tok_fun; return token; func token = tok_fun; return token; -- Gitee From 1831b9e00c20e4e4c07a4547f55c6b5e762a7dbc Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 17:32:59 +0800 Subject: [PATCH 36/98] Temp commit --- src/Makefile.am | 2 +- src/ast/ExprAST.cpp | 4 ++++ src/ast/PrototypeAST.cpp | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index d8c483c..cd6de7c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ 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/ClassAST.cpp ast/CodeBlockAST.cpp ast/EmptyExprAST.cpp ast/ExprAST.cpp ast/ExternAST.cpp\ - ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.cpp ast/PrototypeAST.cpp\ + ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.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 diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 9b5df3d..d43814d 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -9,6 +9,7 @@ #include "EmptyExprAST.h" #include "IfExprAST.h" #include "IntExprAST.h" +#include "ReturnExprAST.h" #include "UnaryExprAST.h" #include "VariableDefExprAST.h" #include "VariableExprAST.h" @@ -123,6 +124,9 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) } break; } + case tok_return: { + return ReturnExprAST::ParseReturnExprAST(unit, codeblock); + } default: { CompileError e("不期待的token:" + token.dump()); throw e; diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index e75ab4a..aa09eca 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -140,7 +140,13 @@ llvm::Function *PrototypeAST::Codegen() } else { if (name != "main") { - returnType = llvm::Type::getVoidTy(*unit->context); + 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); } -- Gitee From c8c285c2a228c928dd3de295541b4e6d986ccd66 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 17:36:22 +0800 Subject: [PATCH 37/98] Add ReturnExprAST --- src/ast/ReturnExprAST.cpp | 56 +++++++++++++++++++++++++++++++++++++++ src/ast/ReturnExprAST.h | 24 +++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/ast/ReturnExprAST.cpp create mode 100644 src/ast/ReturnExprAST.h diff --git a/src/ast/ReturnExprAST.cpp b/src/ast/ReturnExprAST.cpp new file mode 100644 index 0000000..dc6da06 --- /dev/null +++ b/src/ast/ReturnExprAST.cpp @@ -0,0 +1,56 @@ +/* + * 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); + result->returnExpr = ExprAST::ParseExpression(unit, codeblock, false); + return result; +} + +llvm::Value *getGEP(llvm::IRBuilder<> &Builder, llvm::Value *Base, + llvm::ArrayRef Offset) +{ + return Builder.CreateGEP( + llvm::cast(Base->getType()->getScalarType()) + ->getElementType(), + Base, Offset, "a"); +} + +std::vector ReturnExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector returnValue = returnExpr->Codegen(builder); + llvm::Function *function = builder->GetInsertBlock()->getParent(); + + llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + + llvm::StructType *sType = (llvm::StructType *)function->getReturnType(); + llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); + std::vector processedValue; + for (llvm::Value *value : returnValue) { + builder->CreateStore(value, getGEP(*builder, alloca, processedValue)); + processedValue.push_back(value); + } + 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 0000000..bd6b9f1 --- /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_ */ -- Gitee From d8c6bffa5939f3a9c22095f48c4ff6b6472b5888 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 24 Feb 2021 17:38:25 +0800 Subject: [PATCH 38/98] fixed some bug --- src/yacc_stuff/tokenizer.lpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 79ed137..03c3936 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -36,7 +36,7 @@ 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; +return token = tok_return; return token; [a-zA-Z_][a-zA-Z_]* 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; -- Gitee From 19312648146aafec809fe4300f454a7c20e2a252 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 19:29:33 +0800 Subject: [PATCH 39/98] Implment Multi-value return --- src/ast/CallExprAST.cpp | 13 +++++++++++++ src/ast/CodeBlockAST.cpp | 5 ++--- src/ast/IntExprAST.cpp | 10 ++++++++-- src/ast/ReturnExprAST.cpp | 21 ++++++++------------- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 0ed28ff..829a3fc 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -68,6 +68,19 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) 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}); + + /*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/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index ba5ca3e..721ee0b 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -75,9 +75,8 @@ llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) // builder->CreateRetVoid(); // todo:待处理,main特判 // std::cout << name << std::string(function->getName()) << std::endl; if (parent == nullptr) { - if (std::string(function->getName()) != "main") { - builder->CreateRetVoid(); - } else { + if (std::string(function->getName()) == "main") { + llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 32); llvm::ConstantInt *res = llvm::ConstantInt::get(type, 0, true); diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 80fb6e3..7d1edea 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -24,8 +24,14 @@ IntExprAST::~IntExprAST() std::vector IntExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; - llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 64); - llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); + llvm::IntegerType *rtype = llvm::IntegerType::get(*unit->context, 64); + llvm::ConstantInt *res = llvm::ConstantInt::get(rtype, val, true); result.push_back(res); + 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/ReturnExprAST.cpp b/src/ast/ReturnExprAST.cpp index dc6da06..78608a2 100644 --- a/src/ast/ReturnExprAST.cpp +++ b/src/ast/ReturnExprAST.cpp @@ -27,15 +27,6 @@ ReturnExprAST *ReturnExprAST::ParseReturnExprAST(CompileUnit * unit, return result; } -llvm::Value *getGEP(llvm::IRBuilder<> &Builder, llvm::Value *Base, - llvm::ArrayRef Offset) -{ - return Builder.CreateGEP( - llvm::cast(Base->getType()->getScalarType()) - ->getElementType(), - Base, Offset, "a"); -} - std::vector ReturnExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector returnValue = returnExpr->Codegen(builder); @@ -46,10 +37,14 @@ std::vector ReturnExprAST::Codegen(llvm::IRBuilder<> *builder) llvm::StructType *sType = (llvm::StructType *)function->getReturnType(); llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); - std::vector processedValue; - for (llvm::Value *value : returnValue) { - builder->CreateStore(value, getGEP(*builder, alloca, processedValue)); - processedValue.push_back(value); + 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(); -- Gitee From d3ab75d32a80d1c1179058718ca3b6cf4c932255 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 24 Feb 2021 21:49:03 +0800 Subject: [PATCH 40/98] multi return value test and preprocessor dump --- src/aloc.cpp | 2 +- test/mulret.alo | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/mulret.alo diff --git a/src/aloc.cpp b/src/aloc.cpp index 1cacf19..7cb97c4 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) // buff = header + buff; try { preProcessed = preProcess(buff, 0); - // cout << preProcessed; + cout << preProcessed; // todo:这行代码写的极不规范,尽快修改 CompileUnit(input_file_name, preProcessed).compile(); system(("llc ./" + input_file_name + diff --git a/test/mulret.alo b/test/mulret.alo new file mode 100644 index 0000000..fb2e999 --- /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; +} + +func main() { + int a = testGetInt(); + int b = testGetInt(); + a, b= swap(a, b); + testPrintInt(a); + testPrintInt(b); +} \ No newline at end of file -- Gitee From 7b2abbf2938238ede404665b7b6f6ef0914f1825 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 22:19:52 +0800 Subject: [PATCH 41/98] Fix a bug in demangle --- tools/demangle | Bin 49968 -> 51416 bytes tools/demangle.cpp | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/demangle b/tools/demangle index 7e73da6f7a34a10bedc2f780789d237db2ea0fc2..8a6a8ce9de531187bdfae7913f40c6b8754ed464 100755 GIT binary patch delta 13747 zcmai53tUvy)<0*M83B1C3=hTefr29Mm-#{s9ZSp?Wu}56silaDW~PoNnj=!^wlc4& z`S~mJnxS-y+w}ojqE<%MH6Ns4mP44KWsyDR`>(zC!EvJR+x&+A+W)=Q+H0@;W~_ zW366PtJq5Qm#$G`M9mfTZi3glu`RkA9enrZ%+1&{C~HCL{@S`-iPOI{o=9X{-J;^t zpr+zw#LG`9SGp)26ynnH>Wf$89Iv54pPdeW>G!-DL7TmXvi-V_Y9E$hG^tH&u)(Cd zu?D?~ne`!R2HUSUse{-U{C|ndvq{6S!(CCj!YTt4BZ$m4N)wk2LB0~rD zC~*ewcACyVxphRVjf1zZ*4hoMwPhWfhe!_aKHucAHSqs8IA6~r`kAT5IKwlV4YL?S z48vP}J&L6I^T@jKQ9Z|Pym^!k^2M5sA?h{m^;sUrB+ZlR!!43|?@w~w`f5F!-L8XS zcB@Vf*Ljxt8$$H0UMB>#k@8TmyyQ)kbfn>V#+?)=O}T;uKbN$fMPWbf3eg@ySA)5%qGPDOqD z_f;0TCCN*pM?aW1hkfeRS5NJ%%a;2L5R!73pGOM&*!xGr#BoK1vstxA7*n@JQ(Jlt z`@}u1UGjoiOY+gxA)f@}f};7e^9$JbKIK+r_{b4MhEAA}lN6gAo0xzx>hR|#UwWVc ze{PB%FJi@?k@G^+O=&0F+_?tX&>taL==q-xo;|o8d80zDZdU97a;)O-0%pe#4Q9MX z_jtNJ8QcO#MTNRuw#TF1Vb&~fMR8Z|NN!=+EDr^N>hYh73b|UgQT^%9-iE(+iXYmk zk3}snBO;?RqLU;(fBQ*;f=FXzy(oGk%-xhUS)a!ZbjncFsiZFx2qj+X*=K&H(5GWX z&EnEp##H~fgt8%`b*4+}DajYQ@L#a0{-)3ndCaU`DXg^~*Rl=%fg`$rqybSWm-e)B zPGGe5jA9-3+mDDHxK8*xwo0E7tDpAgL0;a?PHY5Q26ib}MFvB=h->$zZ0F0c|F&6gu%K6$!x~84j3pbyi2@sVRywldg=7<$pLFj>w}_?@sj{y#7Ab zBdK1->j$V#iD+EG>wBo)lj?=MzLV;dipE@C-$HdtLE~s%-$->@Cyg0@IDF9IIwB|+ zjqz-9*U;?8&5B|v_5PtV!GKNJla8RHlN9BrGE`rIvZd5OPAq*}ih?X9hHYrGtgb5Z zaMb&DUI9PKF^SNh#r0FBv5&fT)GeIE8oPGtm7NQng-O|#RRg-hRcglOS1mL&PI0h>-Obh+TqMoqEQthN)9TFGiM zqdqFheP7<cd~1l2l`V*8|74rF67Q;yO@dwxbw6Pbw|SFYV8W@B~w1pDjFT+3ZBEtN6sL zjpu1jHRBrlJfX@hS5^68wKijQ(U9Nx)e6lTo@Hz*nnpRpV#V=kw20LIwV?o82+sCN zXK^?Tu+bhw&+&XMq->Tg6}ZtBd+n(fbV7SgsMwCP+9>_lt2igI-+JQ>0sJLrQ*f8< z9r=LU2&ht||E~dELIgCdoxifV(I%_y7tvWs8$Mp+s(iQ4rmODK2HYdkr)Y!9FbYAed`;TatbmmTdx zo@j4u#cpXc;^maGwjAvuN46TBeI_f24zWJ;^WSG?23O^oNv8z1l^OltO-<9^jl^G! zJWlp=97^q**DwKc;1q;I1=<0lrML0Vqn zj$Rb3Saw~+(LE1uJT!gG)%DvBhnTCKw^?;mpw$J z?$wJXJsFQSo)4Wm*3x06?20R6FcN1Uj6k%s@(Uz8+dEo!?KV?mI_5@GBfo%W?~oVX z6uxb7O~>(AI$$@pl6@$;p*2uqc#}^SKR1^XNv4SR=#N~63!J?|ewpMa*s_?|Vb6eR zGLEo)V6lA;3$8WeUXE)A!sAF=y~TFHvg(dnzyZ9T{{yi^uBPn-y-`=xt_m8@+XN>g^iYiQW!!7usD_YX(Y# zo}n&TOP|54W14$lNp`bbJTHpz|1^^Q9BbB3Lsu*&K7=L4edkla@0Tc}HTLB?Haad$ zS4LoBljEax6LoBDd=K4B9V?Fy*FCCZpTtLpt)}zXhIL0){F*roPRc0f^Ws9-xwxL~ zU-{nQSY742sp{l0wlA%xwTj&Thb}NS+BNn$B=h^z8hbT)D#@<5s1%%L`P&VLRnR3_Rf0cFmhW8W+LcbK zgV9M-GT-0`5juY4T_pWB7ilrTag9Bd`VuV{MF@8fx*~)97aj^!`QG-XyI(#}$k}8T z8y~E0WXlrf>iVecMnamQD>7P!wG+aIB!=M88Jh%Xr?N$fX6u*oT%$#ZetmiJs}TmO z7c4eDlwz{Kd!KDtb={2Kps=vs`R=*}ch_V`DH0QxNY@0!)OtoE^nN@qnRd)4!Zz}_ z%UD8E2)mZ(Z}fyk*-3Ue&a4a4Gjmd=4v+R`BqfD~30K&NS>(=(-_pa~{Y~thqq7Op$%^|O0)6G+#y5TBIt7nZ#N>YlJqfFoIJsLf^O3I zn;58L;(6ckd|-Tj&J(*>c&N0j%B(bVHz1$C*YY`Ti5y@#mMpBb*tq3DY1uSaGkfG7 zvvKy(ZT4tstH)0FnA(He?9oTh_N9b{)bTBX)tgm|p0UvQ^nURht54~o&SARLF}iWr zSaxcU$c=co)znoBFTB-`mUF$d3uHS|gL_os?#2EOJ5QMXbB^aIJuMLJ-Kb7$lxEc9 z&bL&{M6J4C2)mscs9ST5d8R$qdlUChiyyv^A2DN1+B@>IoNtqfu#@W#PoQE$*zUB! zx}cv~Q(D9W|N4ge#8_(VjdWe(2P&^#;ML4?nE5KqJfh;K$!4NU6pIQ1{mBjY)@?Q} zy}xeIw`@cDgSuPaR9s3Qry34@jhX@24*fU%+D*zpKi{ZJ7>;R^NhJg zW~Lt#Z>3KYa^Se-w8N1O`NU@qhZ$IX1{ubh?ew|BQ42JE;c!gA%}nt{hhqiM{VRv# zcOOL=1MKLlD31ekVP^%d0B!*80PY1=0Z#$({8Jf)0Yw4N0I{2_$`23 zz@@-uBi@<54#5w%&mUbuN5Bif3BaF$i-Fy-);0sUPsSk zzJU4{kek6iert3?y^Wcx+;mHzD0M~xBQ8k21?^eC?9d(~;bRFnJVd)|H$m8R1T`D& zPhDUGbHWVkAx5)Dv%`&hAx*o$mSl&;{sf)O(+<+7* z&Q{azTHTNK7#@GB87k}HBns+Tko8||V!;-ZV}&k141O%RJOvP%%(fmnEvO@#Ob#5Ka~Cx}HC89HX=6ZFOoIOmpMWbaRi zFw#-@<3+X{zUeqN*Kse4A-1pMzBfY*tz!{TsD#+Lj>mBhqIVse0=5NWk2>xl1n1z` zI<^gLI>hO9?C_&uedu@}UFUFILz?vMu@0Pv`IWA9m@8o7%ls#Y8+JenVF{DNtyPes z>BL4FTJ09xovnJb4?+8I=XRuT8B{2B^kKpiXm4vTn9*!T`%JVqk*-r*x(40{+dk1? zydOI8^(+>1IUVAJdUk4Jn6Vh*;(GQS#9a_e>iMugfViz5DGFv8kLit9QC(lp9(XLm z=#I(!Pd)M&Zh%xxI$V0Yp3mk?kbCOcX>6vo5ck$&vcinJA-*d-pMZEmL}7>6T+bJm zJ64UZffXROD2QqUdmf?%;;;rjQ8OVXH?Y%S*Ft=_f!&xC(PJ;fmvEhmb{_WhyJ`Ix z?b{o857!}U4h1xNA}fo%7rz zpgYtm(OC^l_CnVG#{Qg)MF)+MSEzsEIf%oquz?U;ATGN?8`>Cx({arezRlBxxDD(C zh)-Q%haoP8xaA7F1aULO16LR+R6^VZ4_K?`ARdO_9QcK(Kh37#Y@`SAeb};`&c^e~49V*rB4bS>0tGx^_`6%1H z3}DXs7}%oRUY+C3_z=gTYA?TR!{@59Q;qvxRqSeKrQ)Btue9%5-;J`2PmW^+mdU!P zDawvzk{=>a`w;gFHg8UvRr}CZ)5d|s3w%le_3`{iRD5Js`ArL!^7d&s|#f&Fu zR5ZRNkm=?Q>}m-Vw8P<;OOkZ1;0n*{X96mw%{{FSdAzI8TO@If#Fr$#F7aK7$0eSX z_$_^ZC0Jd{`p)}wgxO^hdcn62U(Oiq!Vi$V>!jfs7E&LsG_x`D+CrKtf~YkALO!WPsIjkU;U9b%77@g^QqOav2H%+;1?d) zya(Q&zWOj)IFPGYIWF}#x?~|5TZTquTH+r%3NrcpPUc=)`umyx5>u$Vk7#|VzwnGI zFU#0#OHAq(`fsq44*$}U8~bdDDIpj)t2FMtF+!K_x~PPM@1g{^o)#g3R$|FYT}c14 zUV#oplOtEiNU3v9@+BF9*em&I7&PfGiW5Y!u52hq~KI(tMxg_KP*?laB1}`crj)RCb0{~P$|bC4^Cw|c=C8lj#kDe#tM!%mnCs743AEv~ou3o8-J`ecHkEKCNju zY$;mTnR`g`V`WcTo_9>OPd`;_f%1u2ZWa9?^(_57DGf zkB|h5%FS0hKz?pXKmJm`NbteRH!g?HIy8v&^j}R%iNyM(%f0JG*ow=z9}fMNRnn`3L|V@@ zysT#+QTMJ#;YrD#lD%VN@M7u#OXxRZI8-JHP`VRO9{FeP?8Tf1Ml^?PV&3tei$e9-LQ_x&!2+?p^bH{ z; z$I5YQw=zFV-t}Ph!tE0L$0}YK!ofTN$~@7aEFU5WZ8d)go`-Cx)1<8EJ|f6knF1W{ zysVRavmBIcRw9sc8q`R+6WdGuh2YJUj?fKKBVFz#&0{lrZH>v$j;`)JZDvU1$#roT zkOufdxhxE_hvib=^*Zvo)>2$>0Z;4>T(l64{TH33){7ZIb+PnaWore@F8FMk1+b z2@J!m&P{9@4~pKV7u_r1fF{8P;vgblkM1ly^?fe zA7uMChqCrNA7nRPu(GHv@%Mgp|K|3Pio!Cho}F<|Y~z;zH@63}8=G3RujrqDkqzye zlQW}WVNTxS#RE{Cp zIZDpNQR9jd<5|MC4y^d4c^yV2Bo3WBr*PKn{LK0D=g#N9SYQdSCbKmj5zOypOXxkn zWXN#(aX>}(%TM6Fj(bw;F9~jL52~o%GQ^;F{>1_PEFqoczA=uKZwRc&-!ZFwpi7sD z2#t4nVq+Rx=HXG{xz}GuKXC}X`;!Uhj`6F6ijaMW+}MYElGwIA!7TR`1Esg3%YkPN z5g1-VLf*`&^R<-ZWv1e{4Ks>nX5yC;Y{z@G?6Lm|jm^uHxB%@ziiT?q?99Q~0PT5;hIqab za46RQOn_J`8ZKgE4#jzDk54RtY~7($&z3-;goi7q4y6WY&sb4(Yp2vFpFGmhJhX4Qo delta 11670 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 O^$+A_lEw$^>G1!a)@rZ- diff --git a/tools/demangle.cpp b/tools/demangle.cpp index 7120a36..7e463e1 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 +} -- Gitee From 1455384b1b12ed116e83982b8585ad37b13b0aca Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 22:39:35 +0800 Subject: [PATCH 42/98] Fix a bug in preprocessor --- src/preprocessor.cpp | 54 +++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 0cb64e1..9700d45 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -181,33 +181,41 @@ std::string preProcess(const std::string &code, int cnt) } else { std::string replaced = doReplace(temp); //处理块注释 - long unsigned int position = replaced.find("*/"); - if (position != replaced.npos) { - if (!isCommented) { - // TODO:错误处理 + std::string result = ""; + + if (!isCommented) { + //处理行注释 + 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; } - replaced = replaced.substr(position + 2, - replaced.length() - position - 2); - isCommented = false; - } - if (isCommented) { - replaced = ""; - } - position = replaced.find("/*"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); - isCommented = true; - } - //处理行注释 - position = replaced.find("//"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); + position = resulta.find("*/"); + if (position != resulta.npos) { + if (!isCommented) { + CompileError e("Haven't been commented"); + throw e; + } + result += resulta.substr(position + 2, + resulta.length() - position - 2); + isCommented = false; + flag = true; + } + if (!flag) { + result = resulta; + } } - - int plen = replaced.length(); + int plen = result.length(); if (plen > 0) { - preprocessoroutput << replaced << std::endl; + preprocessoroutput << result << std::endl; } } temp.erase(); -- Gitee From d703b20d4e56db506c80669499672927363f577e Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 24 Feb 2021 22:43:04 +0800 Subject: [PATCH 43/98] Fix a bug in preprocessor --- src/preprocessor.cpp | 55 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 9700d45..9f83202 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -183,35 +183,36 @@ std::string preProcess(const std::string &code, int cnt) //处理块注释 std::string result = ""; - if (!isCommented) { - //处理行注释 - 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; - } + //处理行注释 + 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) { - CompileError e("Haven't been commented"); - throw e; - } - result += resulta.substr(position + 2, - resulta.length() - position - 2); - isCommented = false; - flag = true; - } - if (!flag) { - result = resulta; + position = resulta.find("*/"); + if (position != resulta.npos) { + if (!isCommented) { + CompileError e("Haven't been commented"); + throw e; } + result += resulta.substr(position + 2, + resulta.length() - position - 2); + isCommented = false; + flag = true; + } + if (!flag) { + result = resulta; + } + if (isCommented) { + result = ""; } int plen = result.length(); if (plen > 0) { -- Gitee From 2a0000615f9aa97ec9ed72461a4ef63285f09a46 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 25 Feb 2021 07:50:11 +0800 Subject: [PATCH 44/98] rewrite CompileError class --- src/CompileError.hpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/CompileError.hpp b/src/CompileError.hpp index 89acd1b..ac3108c 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 -- Gitee From 5f825c4f6e978dbde1b3f1c425adde6cf39e2b74 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 09:06:53 +0800 Subject: [PATCH 45/98] Add Class Paser --- src/CompileUnit.cpp | 10 ++++++++-- src/ast/BaseAST.h | 2 +- src/ast/ClassAST.cpp | 28 ++++++++++++++++++++++++++++ src/ast/ClassAST.h | 3 ++- test/mulret.alo | 2 +- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 29c8a45..b710df4 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -129,8 +129,14 @@ void CompileUnit::compile() std::pair(var->idName, var)); break; } - default: - std::cerr << "unexpected token:" << icurTok->dump() << std::endl; + case tok_key_class: { + ClassAST *classAST = ClassAST::ParseClass(this); + break; + } + default: { + CompileError e("unexpected token:" + icurTok->dump()); + throw e; + } } } std::cout << "Start codegen:" << name << std::endl; diff --git a/src/ast/BaseAST.h b/src/ast/BaseAST.h index a4d2724..33d4f13 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/ClassAST.cpp b/src/ast/ClassAST.cpp index 83db3da..cc4971e 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -6,6 +6,7 @@ */ #include "ClassAST.h" +#include "../CompileError.hpp" ClassAST::ClassAST(CompileUnit *unit) : BaseAST(unit) { @@ -17,4 +18,31 @@ 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"); + throw e; + } + std::string className = token.tokenValue; + std::cout << std::left << std::setw(35) + << "Class definition found:" << className << std::endl; + token = unit->next_tok(); + if (token.type != tok_syntax || token.tokenValue != "{") { + CompileError e("Expected {"); + throw e; + } + while (true) { + token = unit->next_tok(); + //解析成员方法,成员变量 + if (token.type == tok_syntax && token.tokenValue == "}") { + break; + } + } + token = unit->next_tok(); + ClassAST *classAST = new ClassAST(unit); + return classAST; +} + llvm::Type *ClassAST::Codegen() { return nullptr; } diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index d8376ae..64da9b7 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -15,7 +15,8 @@ class ClassAST : public BaseAST public: ClassAST(CompileUnit *unit); virtual ~ClassAST(); - llvm::Type *Codegen(); + llvm::Type * Codegen(); + static ClassAST *ParseClass(CompileUnit *unit); }; #endif /* SRC_AST_CLASSAST_H_ */ diff --git a/test/mulret.alo b/test/mulret.alo index fb2e999..bafe5e7 100644 --- a/test/mulret.alo +++ b/test/mulret.alo @@ -2,7 +2,7 @@ extern func testPrintInt(int i); extern "S" func testGetInt() -> int; func swap(int a, int b) -> int, int { - return b; + return b/*,a*/; } func main() { -- Gitee From 4619a3932984bead140756ff1e6da67749b873ba Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 25 Feb 2021 10:08:33 +0800 Subject: [PATCH 46/98] Adding perf check --- test/perfcheck/demo.alo | 10 ++++++++++ test/perfcheck/demo.c | 10 ++++++++++ test/perfcheck/demo.py | 6 ++++++ 3 files changed, 26 insertions(+) create mode 100644 test/perfcheck/demo.alo create mode 100644 test/perfcheck/demo.c create mode 100755 test/perfcheck/demo.py diff --git a/test/perfcheck/demo.alo b/test/perfcheck/demo.alo new file mode 100644 index 0000000..52f684d --- /dev/null +++ b/test/perfcheck/demo.alo @@ -0,0 +1,10 @@ +extern func testPrintInt(int i); + +func main() { + int a = 1; + int b = 1; + while (a < 100000000){ + a,b = (a+b),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 0000000..c8c915f --- /dev/null +++ b/test/perfcheck/demo.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + int a = 0; + while (a < 100000000) + a++; + printf("a = %d\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 0000000..05a4589 --- /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 -- Gitee From 877d3346b26ed0e08c66ab02650c9e687f76d6bb Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 25 Feb 2021 10:45:34 +0800 Subject: [PATCH 47/98] edit demo.alo --- test/perfcheck/demo.alo | 6 ++++-- test/perfcheck/demo.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/test/perfcheck/demo.alo b/test/perfcheck/demo.alo index 52f684d..1011d7d 100644 --- a/test/perfcheck/demo.alo +++ b/test/perfcheck/demo.alo @@ -3,8 +3,10 @@ extern func testPrintInt(int i); func main() { int a = 1; int b = 1; - while (a < 100000000){ - a,b = (a+b),a; + 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 index c8c915f..bbfaf19 100644 --- a/test/perfcheck/demo.c +++ b/test/perfcheck/demo.c @@ -2,9 +2,14 @@ int main(void) { - int a = 0; - while (a < 100000000) - a++; - printf("a = %d\n", a); + 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 -- Gitee From db7f108dd1b8c375c5f543e98abe380489431716 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 11:50:48 +0800 Subject: [PATCH 48/98] Fix ChainCodegen --- src/ast/AssignmentAST.cpp | 2 +- src/ast/BinaryExprAST.cpp | 4 ++-- src/ast/CallExprAST.cpp | 2 +- src/ast/CodeBlockAST.cpp | 2 +- src/ast/ExprAST.cpp | 12 ++++++++++++ src/ast/ExprAST.h | 1 + src/ast/IfExprAST.cpp | 3 ++- src/ast/IntExprAST.cpp | 6 ------ src/ast/ReturnExprAST.cpp | 2 +- src/ast/UnaryExprAST.cpp | 2 +- src/ast/VariableDefExprAST.cpp | 3 ++- src/ast/VariableExprAST.cpp | 6 ------ src/ast/WhileExprAST.cpp | 3 ++- 13 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index 68317aa..a02d3ce 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -47,7 +47,7 @@ AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) { - std::vector RHSV = RHS->Codegen(builder); + std::vector RHSV = RHS->CodegenChain(builder); if (RHSV.size() != LHS.size()) { CompileError e("the length of expression isn't equal."); throw e; diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 457fdd9..671fa0b 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -41,8 +41,8 @@ BinaryExprAST::~BinaryExprAST() std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) { - std::vector L = LHS->Codegen(builder); - std::vector R = RHS->Codegen(builder); + std::vector L = LHS->CodegenChain(builder); + std::vector R = RHS->CodegenChain(builder); std::vector result; if (L.size() != 1 || R.size() != 1) { CompileError e("Bin Expr length != 1"); diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 829a3fc..5fe2ced 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -32,7 +32,7 @@ CallExprAST::~CallExprAST() std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; - std::vector argsV = args->Codegen(builder); + std::vector argsV = args->CodegenChain(builder); std::vector argStr; for (TypeAST *ast : args->type) { diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 721ee0b..2be5131 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -70,7 +70,7 @@ llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) builder->SetInsertPoint(bb); for (ExprAST *expr : body) { - expr->Codegen(builder); + expr->CodegenChain(builder); } // builder->CreateRetVoid(); // todo:待处理,main特判 // std::cout << name << std::string(function->getName()) << std::endl; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index d43814d..db73329 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -189,3 +189,15 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, } 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 935b974..ee4c87f 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -10,6 +10,7 @@ class ExprAST : public BaseAST ExprAST(CompileUnit *unit); virtual ~ExprAST(); 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); diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index 92de882..d799786 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -41,7 +41,8 @@ IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) std::vector IfExprAST::Codegen(llvm::IRBuilder<> *builder) { llvm::Function *function = builder->GetInsertBlock()->getParent(); - std::vector conditionValues = condition->Codegen(builder); + std::vector conditionValues = + condition->CodegenChain(builder); if (conditionValues.size() != 1) { CompileError e("Multi/Void type in condition found."); throw e; diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 7d1edea..75a0c05 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -27,11 +27,5 @@ std::vector IntExprAST::Codegen(llvm::IRBuilder<> *builder) llvm::IntegerType *rtype = llvm::IntegerType::get(*unit->context, 64); llvm::ConstantInt *res = llvm::ConstantInt::get(rtype, val, true); result.push_back(res); - 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/ReturnExprAST.cpp b/src/ast/ReturnExprAST.cpp index 78608a2..dadc298 100644 --- a/src/ast/ReturnExprAST.cpp +++ b/src/ast/ReturnExprAST.cpp @@ -29,7 +29,7 @@ ReturnExprAST *ReturnExprAST::ParseReturnExprAST(CompileUnit * unit, std::vector ReturnExprAST::Codegen(llvm::IRBuilder<> *builder) { - std::vector returnValue = returnExpr->Codegen(builder); + std::vector returnValue = returnExpr->CodegenChain(builder); llvm::Function *function = builder->GetInsertBlock()->getParent(); llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 392ca96..025720f 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -33,7 +33,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) std::vector result; if (op == "!") { - std::vector Rs = operand->Codegen(builder); + std::vector Rs = operand->CodegenChain(builder); if (Rs.size() != 1) { CompileError e("Unary Expr length != 1"); throw e; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index b5f5867..890e96e 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -80,7 +80,8 @@ VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) builder->CreateStore(function->getArg(argID), alloca); } if (initValue != nullptr) { - std::vector ivalues = initValue->Codegen(builder); + std::vector ivalues = + initValue->CodegenChain(builder); if (ivalues.size() != 1) { CompileError e("Multi/Void type in init found."); throw e; diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 9c3bdef..93b3973 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -60,11 +60,5 @@ std::vector VariableExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; result.push_back(builder->CreateLoad(getAlloca())); - 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/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index c761fec..585ade1 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -36,7 +36,8 @@ std::vector WhileExprAST::Codegen(llvm::IRBuilder<> *builder) // builder->SetInsertPoint(body->endBB); builder->SetInsertPoint(condBB); - std::vector conditionValues = condition->Codegen(builder); + std::vector conditionValues = + condition->CodegenChain(builder); if (conditionValues.size() != 1) { CompileError e("Multi/Void type in condition found."); throw e; -- Gitee From ab98a5efcac0c80620f8e7463c03dd41bdd96c76 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 12:04:38 +0800 Subject: [PATCH 49/98] Add support for operator % --- src/CompileUnit.cpp | 2 +- src/ast/BinaryExprAST.cpp | 2 ++ src/ast/ExprAST.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index b710df4..4740f3d 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -63,7 +63,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - // std::cout << token.dump() << std::endl; + std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 671fa0b..819dc3b 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -56,6 +56,8 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) result.push_back(builder->CreateMul(L[0], R[0])); } else if (binOP == "/") { result.push_back(builder->CreateFDiv(L[0], R[0])); + } else if (binOP == "%") { + result.push_back(builder->CreateSRem(L[0], R[0])); } else if (binOP == "==") { result.push_back(builder->CreateICmpEQ(L[0], R[0])); } else if (binOP == "!=") { diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index db73329..c570619 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -31,6 +31,7 @@ int GetTokPrecedence(Token tok) BinopPrecedence["-"] = 200; BinopPrecedence["*"] = 300; BinopPrecedence["/"] = 300; + BinopPrecedence["%"] = 300; int TokPrec = BinopPrecedence[tok.tokenValue]; if (TokPrec <= 0) { -- Gitee From 9c45056851c3115d99b0010f52b8da785bd8f512 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 12:29:27 +0800 Subject: [PATCH 50/98] Implement the Codegen of class --- src/CompileUnit.cpp | 13 +++++++++++-- src/ast/ClassAST.cpp | 26 ++++++++++++++++++++++---- src/ast/ClassAST.h | 10 +++++++--- src/ast/TypeAST.cpp | 9 --------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 4740f3d..1ed4bf7 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -63,7 +63,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - std::cout << token.dump() << std::endl; + // std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); @@ -131,6 +131,8 @@ void CompileUnit::compile() } case tok_key_class: { ClassAST *classAST = ClassAST::ParseClass(this); + classes.insert(std::pair( + classAST->className, classAST)); break; } default: { @@ -140,7 +142,14 @@ void CompileUnit::compile() } } std::cout << "Start codegen:" << name << std::endl; - // todo:Class的Codegen + std::map::iterator class_iter; + for (class_iter = classes.begin(); class_iter != classes.end(); + class_iter++) { + llvm::Type *classType = class_iter->second->Codegen(); + types.insert( + std::pair(class_iter->first, classType)); + } + std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); gVar_iter != globalVariables.end(); gVar_iter++) { diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index cc4971e..0db2aab 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -7,10 +7,14 @@ #include "ClassAST.h" #include "../CompileError.hpp" +#include "TypeAST.h" -ClassAST::ClassAST(CompileUnit *unit) : BaseAST(unit) +ClassAST::ClassAST(CompileUnit *unit, const std::string &className, + std::vector members) + : BaseAST(unit) { - // TODO Auto-generated constructor stub + this->className = className; + this->members = members; } ClassAST::~ClassAST() @@ -33,16 +37,30 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) CompileError e("Expected {"); throw e; } + std::vector members; while (true) { token = unit->next_tok(); //解析成员方法,成员变量 if (token.type == tok_syntax && token.tokenValue == "}") { break; } + VariableDefExprAST *memberDef = + VariableDefExprAST::ParseVar(unit, nullptr); + members.push_back(memberDef); } token = unit->next_tok(); - ClassAST *classAST = new ClassAST(unit); + ClassAST *classAST = new ClassAST(unit, className, members); return classAST; } -llvm::Type *ClassAST::Codegen() { return nullptr; } +llvm::Type *ClassAST::Codegen() +{ + llvm::StructType *llvm_S = + llvm::StructType::create(*unit->context, className); + std::vector sMembers; + for (VariableDefExprAST *member : members) { + sMembers.push_back(member->variableType->Codegen()); + } + llvm_S->setBody(sMembers); + return llvm_S; +} diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 64da9b7..f0245d9 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -9,14 +9,18 @@ #define SRC_AST_CLASSAST_H_ #include "BaseAST.h" +#include "VariableDefExprAST.h" class ClassAST : public BaseAST { public: - ClassAST(CompileUnit *unit); + ClassAST(CompileUnit *unit, const std::string &className, + std::vector members); virtual ~ClassAST(); - llvm::Type * Codegen(); - static ClassAST *ParseClass(CompileUnit *unit); + llvm::Type * Codegen(); + static ClassAST * ParseClass(CompileUnit *unit); + std::vector members; + std::string className; }; #endif /* SRC_AST_CLASSAST_H_ */ diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index ec51564..9d3e5c7 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -26,15 +26,6 @@ llvm::Type *TypeAST::Codegen() throw e; } return typeAST->second; - /* - //用户定义的类型 - llvm::StructType *llvm_S = - llvm::StructType::create(*unit->context, name); - std::vector members; - for (TypeAST *member : innerType) { - members.push_back(member->Codegen()); - } - return llvm_S;*/ } TypeAST *TypeAST::ParseType(CompileUnit *unit) -- Gitee From 97d44255bc7223a3bbee0df4b73304dd8f76c8a6 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 21:24:51 +0800 Subject: [PATCH 51/98] Add MemberExprAST --- src/Makefile.am | 2 +- src/ast/MemberExprAST.cpp | 24 ++++++++++++++++++++++++ src/ast/MemberExprAST.h | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/ast/MemberExprAST.cpp create mode 100644 src/ast/MemberExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index b7914d4..f7d48de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ 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/ClassAST.cpp ast/CodeBlockAST.cpp ast/EmptyExprAST.cpp ast/ExprAST.cpp ast/ExternAST.cpp\ - ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.cpp ast/PrototypeAST.cpp ast/ReturnExprAST.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 diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp new file mode 100644 index 0000000..d141461 --- /dev/null +++ b/src/ast/MemberExprAST.cpp @@ -0,0 +1,24 @@ +/* + * MemberExprAST.cpp + * + * Created on: Feb 25, 2021 + * Author: zbc + */ + +#include "MemberExprAST.h" + +MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *expr) : ExprAST(unit) +{ + this->expr = expr; +} + +MemberExprAST::~MemberExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector result; + return result; +} diff --git a/src/ast/MemberExprAST.h b/src/ast/MemberExprAST.h new file mode 100644 index 0000000..3d811fc --- /dev/null +++ b/src/ast/MemberExprAST.h @@ -0,0 +1,22 @@ +/* + * 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 *expr); + virtual ~MemberExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); + ExprAST * expr; +}; + +#endif /* SRC_AST_MEMBEREXPRAST_H_ */ -- Gitee From 563294f1458b85310e65837fb83948beb372da93 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 25 Feb 2021 22:22:45 +0800 Subject: [PATCH 52/98] Implement MemberExprAST --- src/Makefile.am | 9 ++++--- src/ast/AssignmentAST.cpp | 57 ++++++++++++++++++++++++++++++++------- src/ast/AssignmentAST.h | 13 +++++---- src/ast/ClassAST.cpp | 15 ++++++----- src/ast/ClassAST.h | 10 +++---- src/ast/ExprAST.cpp | 11 ++++++-- src/ast/MemberExprAST.cpp | 38 ++++++++++++++++++++++++-- src/ast/MemberExprAST.h | 8 ++++-- 8 files changed, 124 insertions(+), 37 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index f7d48de..ce63552 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,10 +2,11 @@ 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/ClassAST.cpp ast/CodeBlockAST.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 + ast/CallExprAST.cpp ast/ClassAST.cpp ast/CodeBlockAST.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 diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index a02d3ce..90ec657 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -7,11 +7,14 @@ #include "AssignmentAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" #include "CodeBlockAST.h" +#include "MemberExprAST.h" +#include "TypeAST.h" #include "VariableExprAST.h" -AssignmentAST::AssignmentAST(CompileUnit * unit, - std::vector LHS, ExprAST *RHS) +AssignmentAST::AssignmentAST(CompileUnit *unit, std::vector LHS, + ExprAST *RHS) : ExprAST(unit) { this->LHS = LHS; @@ -26,19 +29,29 @@ AssignmentAST::~AssignmentAST() AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, CodeBlockAST *codeblock) { - std::vector LHS; //左侧变量 - Token token = *unit->icurTok; + std::vector LHS; //左侧变量 + Token token = *unit->icurTok; while (true) { + token = *unit->icurTok; if (token.type == tok_identifier) { - LHS.push_back( - new VariableExprAST(unit, codeblock, token.tokenValue)); + VariableExprAST *var = + new VariableExprAST(unit, codeblock, token.tokenValue); + if ((unit->icurTok + 1)->type == tok_syntax && + (unit->icurTok + 1)->tokenValue == ".") { + unit->next_tok(); + LHS.push_back( + MemberExprAST::ParseMemberExprAST(unit, codeblock, var)); + } else { + LHS.push_back(var); + token = unit->next_tok(); + } } else if (token.type == tok_syntax) { if (token.tokenValue == "=") { break; } + token = unit->next_tok(); } - token = unit->next_tok(); } unit->next_tok(); return new AssignmentAST(unit, LHS, @@ -53,8 +66,34 @@ std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) throw e; } for (unsigned int i = 0; i < LHS.size(); i++) { - builder->CreateStore(RHSV[i], - LHS[i]->getAlloca()); // todo:对函数参数赋值 + if (MemberExprAST *v = dynamic_cast(LHS[i])) { + std::vector result; + std::vector bases = v->LHS->Codegen(builder); + if (bases.size() != 1) { + CompileError e("Multi/Void type found."); + throw e; + } + + llvm::Value *base = bases[0]; + + ClassAST * baseClass = unit->classes[v->LHS->type[0]->name]; + unsigned int index = + std::distance(std::begin(baseClass->members), + baseClass->members.find(v->member)); + llvm::Value *av = + builder->CreateInsertValue(base, RHSV[i], {index}); + if (VariableExprAST *basev = + dynamic_cast(v->LHS)) { + builder->CreateStore(av, basev->getAlloca()); + } else { + CompileError e("Base isn't variable."); + throw e; + } + } else if (VariableExprAST *v = + dynamic_cast(LHS[i])) { + builder->CreateStore(RHSV[i], + v->getAlloca()); // todo:对函数参数赋值 + } } return std::vector(); } diff --git a/src/ast/AssignmentAST.h b/src/ast/AssignmentAST.h index c3b12a9..2fc6742 100644 --- a/src/ast/AssignmentAST.h +++ b/src/ast/AssignmentAST.h @@ -14,14 +14,13 @@ class VariableExprAST; class AssignmentAST : public ExprAST { public: - AssignmentAST(CompileUnit *unit, std::vector LHS, - ExprAST *RHS); + AssignmentAST(CompileUnit *unit, std::vector LHS, ExprAST *RHS); virtual ~AssignmentAST(); - std::vector Codegen(llvm::IRBuilder<> *builder); - static AssignmentAST * ParseAssignment(CompileUnit * unit, - CodeBlockAST *codeblock); - std::vector LHS; //左侧变量 - ExprAST * RHS; + std::vector Codegen(llvm::IRBuilder<> *builder); + static AssignmentAST * ParseAssignment(CompileUnit * unit, + CodeBlockAST *codeblock); + std::vector LHS; //左侧变量 + ExprAST * RHS; }; #endif /* SRC_AST_ASSIGNMENTAST_H_ */ diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 0db2aab..079d930 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -10,7 +10,7 @@ #include "TypeAST.h" ClassAST::ClassAST(CompileUnit *unit, const std::string &className, - std::vector members) + std::map members) : BaseAST(unit) { this->className = className; @@ -37,7 +37,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) CompileError e("Expected {"); throw e; } - std::vector members; + std::map members; while (true) { token = unit->next_tok(); //解析成员方法,成员变量 @@ -46,7 +46,8 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) } VariableDefExprAST *memberDef = VariableDefExprAST::ParseVar(unit, nullptr); - members.push_back(memberDef); + members.insert(std::pair( + memberDef->idName, memberDef)); } token = unit->next_tok(); ClassAST *classAST = new ClassAST(unit, className, members); @@ -57,9 +58,11 @@ llvm::Type *ClassAST::Codegen() { llvm::StructType *llvm_S = llvm::StructType::create(*unit->context, className); - std::vector sMembers; - for (VariableDefExprAST *member : members) { - sMembers.push_back(member->variableType->Codegen()); + std::vector sMembers; + std::map::iterator member_iter; + for (member_iter = members.begin(); member_iter != members.end(); + member_iter++) { + sMembers.push_back(member_iter->second->variableType->Codegen()); } llvm_S->setBody(sMembers); return llvm_S; diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index f0245d9..67e2d40 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -15,12 +15,12 @@ class ClassAST : public BaseAST { public: ClassAST(CompileUnit *unit, const std::string &className, - std::vector members); + std::map members); virtual ~ClassAST(); - llvm::Type * Codegen(); - static ClassAST * ParseClass(CompileUnit *unit); - std::vector members; - std::string className; + llvm::Type * Codegen(); + static ClassAST * ParseClass(CompileUnit *unit); + std::map members; + std::string className; }; #endif /* SRC_AST_CLASSAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index c570619..24ea6ce 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -9,6 +9,7 @@ #include "EmptyExprAST.h" #include "IfExprAST.h" #include "IntExprAST.h" +#include "MemberExprAST.h" #include "ReturnExprAST.h" #include "UnaryExprAST.h" #include "VariableDefExprAST.h" @@ -114,7 +115,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) if (token.tokenValue == "=") { return AssignmentAST::ParseAssignment(unit, codeblock); break; - } else if (token.tokenValue != ",") { + } else if (token.tokenValue != "," && + token.tokenValue != ".") { //变量 unit->next_tok(); return new VariableExprAST(unit, codeblock, idName); @@ -169,7 +171,12 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (LHS == nullptr) { return nullptr; } - ExprAST *result = ParseBinOpRHS(unit, codeblock, 0, LHS); + ExprAST *result; + if (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ".") { + result = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); + } else { + result = ParseBinOpRHS(unit, codeblock, 0, LHS); + } if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index d141461..6ae28cc 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -6,10 +6,16 @@ */ #include "MemberExprAST.h" +#include "../CompileError.hpp" +#include "ClassAST.h" +#include "TypeAST.h" -MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *expr) : ExprAST(unit) +MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *LHS, + std::string member) + : ExprAST(unit) { - this->expr = expr; + this->LHS = LHS; + this->member = member; } MemberExprAST::~MemberExprAST() @@ -17,8 +23,36 @@ MemberExprAST::~MemberExprAST() // TODO Auto-generated destructor stub } +MemberExprAST *MemberExprAST::ParseMemberExprAST(CompileUnit * unit, + CodeBlockAST *codeblock, + ExprAST * LHS) +{ + Token token = unit->next_tok(); + if (token.type != tok_identifier) { + CompileError e("Expected identifier"); + throw e; + } + MemberExprAST *result = new MemberExprAST(unit, LHS, token.tokenValue); + unit->next_tok(); + return result; +} + std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) { 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]->name]; + unsigned int index = std::distance(std::begin(baseClass->members), + baseClass->members.find(member)); + type.push_back(baseClass->members[member]->variableType); + 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 index 3d811fc..e801465 100644 --- a/src/ast/MemberExprAST.h +++ b/src/ast/MemberExprAST.h @@ -13,10 +13,14 @@ class MemberExprAST : public ExprAST { public: - MemberExprAST(CompileUnit *unit, ExprAST *expr); + MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member); virtual ~MemberExprAST(); std::vector Codegen(llvm::IRBuilder<> *builder); - ExprAST * expr; + static MemberExprAST * ParseMemberExprAST(CompileUnit * unit, + CodeBlockAST *codeblock, + ExprAST * LHS); + ExprAST * LHS; + std::string member; }; #endif /* SRC_AST_MEMBEREXPRAST_H_ */ -- Gitee From 06f35b36a462894af7eb2d8c6c8f73ba9b3359d5 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 25 Feb 2021 22:43:20 +0800 Subject: [PATCH 53/98] Added class support for VSC ext --- .../vscode/alolang/CHANGELOG.md | 4 ++++ .../vscode/alolang/README.md | 4 ++++ .../vscode/alolang/alolang-0.0.5.vsix | Bin 0 -> 5280 bytes .../vscode/alolang/package.json | 2 +- .../alolang/syntaxes/alolang.tmLanguage.json | 4 ++++ test/classcheck.alo | 18 ++++++++++++++++++ 6 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 syntax_highlight_plugin/vscode/alolang/alolang-0.0.5.vsix create mode 100644 test/classcheck.alo diff --git a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md index 2b0ebab..72af2c0 100644 --- a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md +++ b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md @@ -4,6 +4,10 @@ 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.5 + +- Added support for class + ## Dev Beta 0.0.4 - Added support for extern behavior diff --git a/syntax_highlight_plugin/vscode/alolang/README.md b/syntax_highlight_plugin/vscode/alolang/README.md index 181dce0..8a02169 100644 --- a/syntax_highlight_plugin/vscode/alolang/README.md +++ b/syntax_highlight_plugin/vscode/alolang/README.md @@ -31,6 +31,10 @@ 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 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 GIT binary patch literal 5280 zcmai2WmuG3xE;EC=+2QYr6eSVp+P{pQyfZ$l#oFhX%3(?GNhEGv>+he-8Gbiw4iX| z-s?Gfo*VD?T%7qlVGiC-md*}#wlMcny(O1f0pfrIbCM0}ucJkyx*@vwRHc}vPYf9K-&|lb z#L&+WvS00beV0|5^Vl_DWcv2}d||Wk$}y(M&k ze?W6ASj0a2vm?~?;rjf!a}@&UNsxa)l*eZUsW1ho`Wd0c2CK98xfq~Y?vW1HR(hh* zQpZc6^Vj-V>QFF;jR#^>VaTL!_Eu(iv9H#Ajy=|!^~P$G_a>;fs3d?cX3Ul!9|9hp z2Tleix9XS4Bbg=@0|{KBV+d49ze06zXor&_55HsA`n;{lQ=xIXF9w}*D4sz*_;@GHkU<&XJ8*2^thg5V zAtWxS9VI;O@v9#%<3dOmadx7#n&7<(n~&4f#Than1`HTd6C{bNpu_ym)^|oSi`bIg zg5)FyLgde^dra&(B&v&u--A25+EJ3YN+Dz+ANM4H_@(yMQK&3ilPqp@uW-b6Q=hjj zMS+jq=yDz^)sSnX{m8&+Uis$Y2WmI9RUQAPN4qR+Ct@N~99knx-IShq#+p6E-g1Nc z^lF))jQmVVWm2MkHXlP+u)cKw<}rzRB5p7|>9HYPLD8K%sLR&`&TP-x_|Q6dSa0tf zP1#}g=6>n^!=sL8JVSvn$ueH!-c9fe)#Ch1`BLJgcoGT~r7NM`1#f}3(aP=S%09Za zD>Mc82Ll(jEh`htc0!o}8BLiV-ruy;PyZ~qL2FMm*ZPCwiZfb0b+_E+MgaiGZr{f8 zF3z_scQ@DdakYh+@_9Qsdc>;7v2B+Zdo zgjqN=9~_UBG$8Z#XS@=5FEYVmpf>vz1V5f<*1ROo|ZIAxXeKOb%xcl7h zvE_E2|CnWdc_mp52v|)M!sle;q%GxQEQmjU${p_Q07r`dG-{Y348n9u;iHcvto~d8 zGN52&Pm!~JC*qO1I9o+8;getufOpEwR81RzyEy|5D`0VAP8q0CYhFbyS)1gBP zpH@FSR{Jk`UK{TBigh1Na0EDa0(&M@22NC-RtEaM2zr3izThhACxWEV8+1@c3<}$C zSBqG2ri^5jLFzPMql6$o+;sk9>DnfbQ)@A*K;sLVAHdV}(eAg7B@Aaqn-Of^RTGG& zIv=j&r!mdeombk5x@L^*E8&XK$m6Q#u9a{(vZlaHd{f>EPpuD5qjjfT@edN(B~993 zF(m3#?u-3+A73VR+CqLctsuA)$70DmR^+KN*OdoL^WgZt;2;%L7BX}XU95PxPqYw( zaGA~iE^~;zL-dJZjHGrVhYZqrb2YU}UOZPiHeg<=K&d?okP7?t7FX?O58CRsW`!Ku>m;q`g?XB#Z%+ z+9_zv5LWwFkJn~paAy!N8iy5!6k_*{Becq|pvh6FU)^B0kUp`GEI~{mCVrUNPm9(y znV#lY>rKNrzowx>cd=7jza}C>lRt}0{bQjuM3_ulh`Gl{Ta5Xe�B$QM|~&yEBI( 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 C2|5-4 literal 0 HcmV?d00001 diff --git a/syntax_highlight_plugin/vscode/alolang/package.json b/syntax_highlight_plugin/vscode/alolang/package.json index 573ad7d..4d73b30 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.4", + "version": "0.0.5", "publisher": "AloLangDevTeam", "license": "GPLv3", "repository": { diff --git a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json index 44f41a9..f2b738b 100644 --- a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json +++ b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json @@ -203,6 +203,10 @@ { "name": "keyword.const.alolang", "match": "\\bconst\\b" + }, + { + "name": "keyword.class.alolang", + "match": "\\bclass\\b" } ] }, diff --git a/test/classcheck.alo b/test/classcheck.alo new file mode 100644 index 0000000..14cfb3a --- /dev/null +++ b/test/classcheck.alo @@ -0,0 +1,18 @@ +extern func testPrintInt(int i); + +class foo { + int a; + int b; +} + +func main(){ + foo A; + A.a = 3; + A.b = 4; + testPrintInt(A.a); + testPrintInt(A.b); + A.a = 4; + A.b = 5; + // A.c = 999; + // testPrintInt(A.c); +} \ No newline at end of file -- Gitee From 24601697ab526509444e9e9f89994b1cd89ba459 Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 26 Feb 2021 10:12:44 +0800 Subject: [PATCH 54/98] Fix a bug in MemberExprAST --- src/CompileUnit.cpp | 11 +++++------ src/CompileUnit.h | 2 ++ src/ast/ExprAST.cpp | 11 +++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 1ed4bf7..cebd623 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -133,6 +133,7 @@ void CompileUnit::compile() ClassAST *classAST = ClassAST::ParseClass(this); classes.insert(std::pair( classAST->className, classAST)); + classesO.push_back(classAST); break; } default: { @@ -142,12 +143,10 @@ void CompileUnit::compile() } } std::cout << "Start codegen:" << name << std::endl; - std::map::iterator class_iter; - for (class_iter = classes.begin(); class_iter != classes.end(); - class_iter++) { - llvm::Type *classType = class_iter->second->Codegen(); - types.insert( - std::pair(class_iter->first, classType)); + for (ClassAST *classAST : classesO) { + llvm::Type *classType = classAST->Codegen(); + types.insert(std::pair(classAST->className, + classType)); } std::map::iterator gVar_iter; diff --git a/src/CompileUnit.h b/src/CompileUnit.h index cde7dfe..96ce9a5 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -38,7 +38,9 @@ class CompileUnit 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 types; // Codgen用 diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 24ea6ce..d5c146a 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -172,11 +172,14 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, return nullptr; } ExprAST *result; - if (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ".") { - result = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); - } else { - result = ParseBinOpRHS(unit, codeblock, 0, LHS); + + while (unit->icurTok->type == tok_syntax && + unit->icurTok->tokenValue == ".") { + LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); } + + result = ParseBinOpRHS(unit, codeblock, 0, LHS); + if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } -- Gitee From 1766ad8c6712cc165795e1b2f9a5a99f1fe35a24 Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 26 Feb 2021 10:17:02 +0800 Subject: [PATCH 55/98] Add error handler of member not found exception --- src/ast/MemberExprAST.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index 6ae28cc..879f679 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -48,9 +48,15 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) llvm::Value *base = bases[0]; - ClassAST * baseClass = unit->classes[LHS->type[0]->name]; - unsigned int index = std::distance(std::begin(baseClass->members), - baseClass->members.find(member)); + ClassAST *baseClass = unit->classes[LHS->type[0]->name]; + 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->members[member]->variableType); llvm::Value *member = builder->CreateExtractValue(base, {index}); result.push_back(member); -- Gitee From 92f9a17543778ce0e4a796f8327ee593f481138d Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Fri, 26 Feb 2021 22:24:12 +0800 Subject: [PATCH 56/98] class check test --- test/classcheck.alo | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/classcheck.alo b/test/classcheck.alo index 14cfb3a..1f3b432 100644 --- a/test/classcheck.alo +++ b/test/classcheck.alo @@ -5,14 +5,20 @@ class foo { int b; } +class bar { + foo F; +} + func main(){ foo A; + bar B; A.a = 3; A.b = 4; - testPrintInt(A.a); + 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 +} \ No newline at end of file -- Gitee From 5dea58d78837becb056385daf833d6c82c27600c Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 27 Feb 2021 20:35:18 +0800 Subject: [PATCH 57/98] Fix a bug about the assignment of Member of Class --- src/ast/AssignmentAST.cpp | 96 ++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index 90ec657..778486a 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -30,27 +30,31 @@ AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, CodeBlockAST *codeblock) { std::vector LHS; //左侧变量 - Token token = *unit->icurTok; - + Token token = *unit->icurTok; + ExprAST * curVar = nullptr; while (true) { token = *unit->icurTok; if (token.type == tok_identifier) { - VariableExprAST *var = - new VariableExprAST(unit, codeblock, token.tokenValue); - if ((unit->icurTok + 1)->type == tok_syntax && - (unit->icurTok + 1)->tokenValue == ".") { - unit->next_tok(); - LHS.push_back( - MemberExprAST::ParseMemberExprAST(unit, codeblock, var)); - } else { - LHS.push_back(var); - token = unit->next_tok(); + curVar = new VariableExprAST(unit, codeblock, token.tokenValue); + unit->next_tok(); + } + if (token.type == tok_syntax) { + if (curVar == nullptr) { + CompileError e("Expected variable before assignment"); + throw e; } - } else if (token.type == tok_syntax) { if (token.tokenValue == "=") { + LHS.push_back(curVar); + curVar = nullptr; break; + } else if (token.tokenValue == ",") { + unit->next_tok(); + LHS.push_back(curVar); + curVar = nullptr; + } else if (token.tokenValue == ".") { + curVar = + MemberExprAST::ParseMemberExprAST(unit, codeblock, curVar); } - token = unit->next_tok(); } } unit->next_tok(); @@ -66,34 +70,52 @@ std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) throw e; } for (unsigned int i = 0; i < LHS.size(); i++) { - if (MemberExprAST *v = dynamic_cast(LHS[i])) { - std::vector result; - std::vector bases = v->LHS->Codegen(builder); - if (bases.size() != 1) { - CompileError e("Multi/Void type found."); + ExprAST * curAST = LHS[i]; + std::vector chain; + 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; } - - llvm::Value *base = bases[0]; - - ClassAST * baseClass = unit->classes[v->LHS->type[0]->name]; - unsigned int index = - std::distance(std::begin(baseClass->members), - baseClass->members.find(v->member)); - llvm::Value *av = - builder->CreateInsertValue(base, RHSV[i], {index}); - if (VariableExprAST *basev = - dynamic_cast(v->LHS)) { - builder->CreateStore(av, basev->getAlloca()); - } else { - CompileError e("Base isn't variable."); + } + VariableExprAST *start = + dynamic_cast(chain[chain.size() - 1]); + llvm::Value * pointer = start->getAlloca(); + std::vector idx; + std::string curType = start->type[0]->name; + 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; } - } else if (VariableExprAST *v = - dynamic_cast(LHS[i])) { - builder->CreateStore(RHSV[i], - v->getAlloca()); // todo:对函数参数赋值 + 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); + } + + builder->CreateStore(RHSV[i], pointer); } return std::vector(); } -- Gitee From 05a9b3ae78bf116519086fb8d2f503f78a9ab579 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 10:19:38 +0800 Subject: [PATCH 58/98] Rebuild BinaryExprAST to support user-defined operations --- src/CompileUnit.cpp | 56 ++++++++++++++++++++++++++++- src/CompileUnit.h | 4 ++- src/ast/BinaryExprAST.cpp | 76 +++++++++++++++++++-------------------- src/ast/ReturnExprAST.cpp | 56 +++++++++++++++++++++-------- 4 files changed, 137 insertions(+), 55 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index cebd623..b58cbb7 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -21,6 +21,7 @@ #include "ast/TypeAST.h" #include "ast/VariableDefExprAST.h" #include "utils.h" +#include #include #include @@ -34,6 +35,57 @@ void initInnerType(CompileUnit *unit) "bool", llvm::Type::getInt1Ty(*unit->context))); } +void initInnerOperations(CompileUnit *unit) +{ + 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, "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")))); + + 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")))); +} + void scanToken(CompileUnit *unit) { Token token; @@ -95,6 +147,7 @@ void CompileUnit::compile() { std::cout << "Start compiling:" << name << std::endl; initInnerType(this); + initInnerOperations(this); scanToken(this); while (icurTok->type != tok_eof) { switch (icurTok->type) { @@ -106,7 +159,8 @@ void CompileUnit::compile() /*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); diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 96ce9a5..2b8ccf5 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -43,7 +43,9 @@ class CompileUnit std::vector globalVariablesO; std::map functions; std::map externs; - std::map types; // Codgen用 + std::map, std::pair> + binOperators; // LHS type,RHS type,binOP + std::map types; // Codgen用 std::map> globalVariablesValue; // Codgen用 // std::map diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 819dc3b..50e0b98 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -16,22 +16,6 @@ BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, this->binOP = binOP; this->LHS = LHS; this->RHS = RHS; - // todo:类型检查 - this->type = LHS->type; - //整理此段代码,将操作抽象 - if (binOP == "==") { - this->type.push_back(new TypeAST(unit, "bool")); - } else if (binOP == "!=") { - this->type.push_back(new TypeAST(unit, "bool")); - } else if (binOP == ">") { - this->type.push_back(new TypeAST(unit, "bool")); - } else if (binOP == "<") { - this->type.push_back(new TypeAST(unit, "bool")); - } else if (binOP == ">=") { - this->type.push_back(new TypeAST(unit, "bool")); - } else if (binOP == "<=") { - this->type.push_back(new TypeAST(unit, "bool")); - } } BinaryExprAST::~BinaryExprAST() @@ -41,6 +25,7 @@ BinaryExprAST::~BinaryExprAST() std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) { + std::vector L = LHS->CodegenChain(builder); std::vector R = RHS->CodegenChain(builder); std::vector result; @@ -48,30 +33,43 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Bin Expr length != 1"); throw e; } - if (binOP == "+") { - result.push_back(builder->CreateAdd(L[0], R[0])); - } else if (binOP == "-") { - result.push_back(builder->CreateSub(L[0], R[0])); - } else if (binOP == "*") { - result.push_back(builder->CreateMul(L[0], R[0])); - } else if (binOP == "/") { - result.push_back(builder->CreateFDiv(L[0], R[0])); - } else if (binOP == "%") { - result.push_back(builder->CreateSRem(L[0], R[0])); - } else if (binOP == "==") { - result.push_back(builder->CreateICmpEQ(L[0], R[0])); - } else if (binOP == "!=") { - result.push_back(builder->CreateICmpNE(L[0], R[0])); - } else if (binOP == ">") { - result.push_back(builder->CreateICmpSGT(L[0], R[0])); - } else if (binOP == "<") { - result.push_back(builder->CreateICmpSLT(L[0], R[0])); - } else if (binOP == ">=") { - result.push_back(builder->CreateICmpSGE(L[0], R[0])); - } else if (binOP == "<=") { - result.push_back(builder->CreateICmpSLE(L[0], R[0])); + 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) { + //内置运算符 + if (binOP == "+") { + result.push_back(builder->CreateAdd(L[0], R[0])); + } else if (binOP == "-") { + result.push_back(builder->CreateSub(L[0], R[0])); + } else if (binOP == "*") { + result.push_back(builder->CreateMul(L[0], R[0])); + } else if (binOP == "/") { + result.push_back(builder->CreateSDiv(L[0], R[0])); + } else if (binOP == "%") { + result.push_back(builder->CreateSRem(L[0], R[0])); + } else if (binOP == "==") { + result.push_back(builder->CreateICmpEQ(L[0], R[0])); + } else if (binOP == "!=") { + result.push_back(builder->CreateICmpNE(L[0], R[0])); + } else if (binOP == ">") { + result.push_back(builder->CreateICmpSGT(L[0], R[0])); + } else if (binOP == "<") { + result.push_back(builder->CreateICmpSLT(L[0], R[0])); + } else if (binOP == ">=") { + result.push_back(builder->CreateICmpSGE(L[0], R[0])); + } else if (binOP == "<=") { + result.push_back(builder->CreateICmpSLE(L[0], R[0])); + } } else { - CompileError e("Unknown operator:" + binOP); + //用户定义运算符 + CompileError e("User-def operator not implemented"); throw e; } return result; diff --git a/src/ast/ReturnExprAST.cpp b/src/ast/ReturnExprAST.cpp index dadc298..0d375cb 100644 --- a/src/ast/ReturnExprAST.cpp +++ b/src/ast/ReturnExprAST.cpp @@ -23,29 +23,57 @@ ReturnExprAST *ReturnExprAST::ParseReturnExprAST(CompileUnit * unit, { unit->next_tok(); ReturnExprAST *result = new ReturnExprAST(unit); - result->returnExpr = ExprAST::ParseExpression(unit, codeblock, false); + 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) { - std::vector returnValue = returnExpr->CodegenChain(builder); llvm::Function *function = builder->GetInsertBlock()->getParent(); - llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), - function->getEntryBlock().begin()); + 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::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); + 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)); } - builder->CreateRet(builder->CreateLoad(alloca)); return std::vector(); } -- Gitee From c2c7713d2feae20b192326f277112552434c855d Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 12:43:56 +0800 Subject: [PATCH 59/98] Add paser support for generic --- src/ast/ClassAST.cpp | 27 +++++++++++++++++++++------ src/ast/ClassAST.h | 4 +++- src/ast/ExprAST.cpp | 25 ++++++++++++++++--------- src/ast/TypeAST.cpp | 33 +++++++++++++++++++++++++++++---- src/ast/TypeAST.h | 5 ++++- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 079d930..372af20 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -10,11 +10,13 @@ #include "TypeAST.h" ClassAST::ClassAST(CompileUnit *unit, const std::string &className, - std::map members) + std::map members, + std::vector genericTypes) : BaseAST(unit) { - this->className = className; - this->members = members; + this->className = className; + this->members = members; + this->genericTypes = genericTypes; } ClassAST::~ClassAST() @@ -29,10 +31,22 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) CompileError e("Expected identifier"); throw e; } - std::string className = token.tokenValue; + 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 {"); throw e; @@ -50,7 +64,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) memberDef->idName, memberDef)); } token = unit->next_tok(); - ClassAST *classAST = new ClassAST(unit, className, members); + ClassAST *classAST = new ClassAST(unit, className, members, genericTypes); return classAST; } @@ -62,7 +76,8 @@ llvm::Type *ClassAST::Codegen() std::map::iterator member_iter; for (member_iter = members.begin(); member_iter != members.end(); member_iter++) { - sMembers.push_back(member_iter->second->variableType->Codegen()); + VariableDefExprAST *memberVariable = member_iter->second; + sMembers.push_back(memberVariable->variableType->Codegen()); } llvm_S->setBody(sMembers); return llvm_S; diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 67e2d40..bd46b99 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -15,11 +15,13 @@ class ClassAST : public BaseAST { public: ClassAST(CompileUnit *unit, const std::string &className, - std::map members); + std::map members, + std::vector genericTypes); virtual ~ClassAST(); llvm::Type * Codegen(); static ClassAST * ParseClass(CompileUnit *unit); std::map members; + std::vector genericTypes; std::string className; }; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index d5c146a..9c515dd 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -58,6 +58,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); } case tok_key_literal: { + unit->next_tok(); if (token.tokenValue == "true") { return new BoolExprAST(unit, true); } else { @@ -96,19 +97,14 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) //函数调用或定义 std::string idName = token.tokenValue; token = *(unit->icurTok + 1); - if (token.type == tok_identifier) { - //定义 - VariableDefExprAST *varAST = - VariableDefExprAST::ParseVar(unit, codeblock); - return varAST; - } else if (token.tokenValue == "(") { + if (token.tokenValue == "(") { //函数调用 token = unit->next_tok(); ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); return new CallExprAST(unit, idName, args); } else { - //变量或赋值 - int i = 0; + //变量或变量定义或赋值 + int i = 1; while (true) { token = *(unit->icurTok + i); if (token.type == tok_syntax) { @@ -116,11 +112,22 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return AssignmentAST::ParseAssignment(unit, codeblock); break; } else if (token.tokenValue != "," && - token.tokenValue != ".") { + token.tokenValue != "." && + token.tokenValue != "<") { //变量 unit->next_tok(); return new VariableExprAST(unit, codeblock, idName); + } else if (token.tokenValue == "<") { + //变量定义 + VariableDefExprAST *varAST = + VariableDefExprAST::ParseVar(unit, codeblock); + return varAST; } + } else if (token.type == tok_identifier && i == 1) { + //变量定义 + VariableDefExprAST *varAST = + VariableDefExprAST::ParseVar(unit, codeblock); + return varAST; } i++; } diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 9d3e5c7..6753dfd 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -9,9 +9,21 @@ #include "../CompileError.hpp" #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; + //生成name + 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() @@ -35,7 +47,20 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) CompileError e("Expected type but got " + token.dump()); throw e; } - TypeAST *result = new TypeAST(unit, token.tokenValue); - token = unit->next_tok(); + std::string baseClass = token.tokenValue; + + token = unit->next_tok(); + if (token.type == tok_syntax && token.tokenValue == "<") { + std::vector genericTypes; + unit->next_tok(); + while (!(token.type == tok_syntax && token.tokenValue == ">")) { + genericTypes.push_back(TypeAST::ParseType(unit)); + token = *unit->icurTok; + } + unit->next_tok(); + TypeAST *result = new TypeAST(unit, baseClass, genericTypes); + return result; + } + TypeAST *result = new TypeAST(unit, baseClass); return result; } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 389869c..170542a 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -13,12 +13,15 @@ class TypeAST : public BaseAST { public: - TypeAST(CompileUnit *unit, std::string name); + TypeAST(CompileUnit *unit, std::string baseClass, + std::vector genericTypes = std::vector()); virtual ~TypeAST(); static TypeAST * ParseType(CompileUnit *unit); llvm::Type * Codegen(); std::string name; + std::string baseClass; std::vector innerType; + std::vector genericTypes; }; #endif /* SRC_AST_TYPEAST_H_ */ -- Gitee From 3efa3bc51e90437a2c1f54c8a58301c87934d4e9 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 15:23:12 +0800 Subject: [PATCH 60/98] Implement generic type --- src/CompileUnit.cpp | 6 ++---- src/ast/AssignmentAST.cpp | 2 +- src/ast/ClassAST.cpp | 25 +++++++++++++++++++++++-- src/ast/ClassAST.h | 3 ++- src/ast/MemberExprAST.cpp | 7 ++++--- src/ast/TypeAST.cpp | 18 +++++++++++++++--- 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index b58cbb7..3244e01 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -197,11 +197,9 @@ void CompileUnit::compile() } } std::cout << "Start codegen:" << name << std::endl; - for (ClassAST *classAST : classesO) { + /*for (ClassAST *classAST : classesO) { llvm::Type *classType = classAST->Codegen(); - types.insert(std::pair(classAST->className, - classType)); - } + }*/ std::map::iterator gVar_iter; for (gVar_iter = globalVariables.begin(); diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index 778486a..2a0fc62 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -88,7 +88,7 @@ std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) dynamic_cast(chain[chain.size() - 1]); llvm::Value * pointer = start->getAlloca(); std::vector idx; - std::string curType = start->type[0]->name; + 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; diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 372af20..a3a5b64 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -68,16 +68,37 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) return classAST; } -llvm::Type *ClassAST::Codegen() +TypeAST *ClassAST::getRealType(TypeAST * type, + std::vector igenericTypes) { + auto it = find(genericTypes.begin(), genericTypes.end(), type->name); + + 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; + } llvm::StructType *llvm_S = llvm::StructType::create(*unit->context, className); std::vector sMembers; std::map::iterator member_iter; for (member_iter = members.begin(); member_iter != members.end(); member_iter++) { + VariableDefExprAST *memberVariable = member_iter->second; - sMembers.push_back(memberVariable->variableType->Codegen()); + 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 index bd46b99..4ef01e1 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -18,7 +18,8 @@ class ClassAST : public BaseAST std::map members, std::vector genericTypes); virtual ~ClassAST(); - llvm::Type * Codegen(); + llvm::Type *Codegen(std::vector genericTypes); + TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); static ClassAST * ParseClass(CompileUnit *unit); std::map members; std::vector genericTypes; diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index 879f679..a2d44cd 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -48,16 +48,17 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) llvm::Value *base = bases[0]; - ClassAST *baseClass = unit->classes[LHS->type[0]->name]; + 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."); + CompileError e("Member " + member + " not found."); throw e; } unsigned int index = std::distance(std::begin(baseClass->members), memberAST); - type.push_back(baseClass->members[member]->variableType); + 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/TypeAST.cpp b/src/ast/TypeAST.cpp index 6753dfd..e09fdef 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -7,6 +7,7 @@ #include "TypeAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" #include "CompileUnit.h" TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, @@ -34,10 +35,21 @@ llvm::Type *TypeAST::Codegen() { auto typeAST = unit->types.find(name); if (typeAST == unit->types.end()) { - CompileError e("can't find type:" + name); - throw e; + //没有找到实例化过的泛型 + 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); + unit->types.insert( + std::pair(name, classType)); + return classType; + //构建泛型 + } + } else { + return typeAST->second; } - return typeAST->second; } TypeAST *TypeAST::ParseType(CompileUnit *unit) -- Gitee From d42d6f8265ed7ef432ac28ff5d7ba54feb64ae02 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 15:46:11 +0800 Subject: [PATCH 61/98] Add support for pointer type --- src/ast/TypeAST.cpp | 39 ++++++++++++++++++++++++++------------- src/ast/TypeAST.h | 2 ++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index e09fdef..7bd0022 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -16,6 +16,7 @@ TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, { this->baseClass = baseClass; this->genericTypes = genericTypes; + this->pointee = nullptr; //生成name this->name = baseClass; if (genericTypes.size() != 0) { @@ -27,28 +28,40 @@ TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, } } +TypeAST::TypeAST(CompileUnit *unit, TypeAST *pointee) : BaseAST(unit) +{ + this->pointee = pointee; + //生成name + this->name = pointee->name + "*"; +} + TypeAST::~TypeAST() { // TODO Auto-generated destructor stub } llvm::Type *TypeAST::Codegen() { - 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; + 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); + unit->types.insert( + std::pair(name, classType)); + return classType; + //构建泛型 + } } else { - llvm::Type *classType = classAST->second->Codegen(genericTypes); - unit->types.insert( - std::pair(name, classType)); - return classType; - //构建泛型 + return typeAST->second; } } else { - return typeAST->second; + return llvm::PointerType::get(pointee->Codegen(), 0); } } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 170542a..5008869 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -15,6 +15,7 @@ class TypeAST : public BaseAST public: TypeAST(CompileUnit *unit, std::string baseClass, std::vector genericTypes = std::vector()); + TypeAST(CompileUnit *unit, TypeAST *pointee); virtual ~TypeAST(); static TypeAST * ParseType(CompileUnit *unit); llvm::Type * Codegen(); @@ -22,6 +23,7 @@ class TypeAST : public BaseAST std::string baseClass; std::vector innerType; std::vector genericTypes; + TypeAST * pointee; //指向的类型 }; #endif /* SRC_AST_TYPEAST_H_ */ -- Gitee From 10ddb394f5a0237e2fce184af6782086fd04cfc7 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 16:16:25 +0800 Subject: [PATCH 62/98] Add support for double type --- src/CompileUnit.cpp | 4 ++-- src/Makefile.am | 2 +- src/ast/BinaryExprAST.cpp | 7 ++++++- src/ast/DoubleExprAST.cpp | 29 +++++++++++++++++++++++++++++ src/ast/DoubleExprAST.h | 23 +++++++++++++++++++++++ src/ast/ExprAST.cpp | 9 ++++++++- src/ast/IntExprAST.cpp | 2 -- src/lib/testPuts.c | 2 +- 8 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 src/ast/DoubleExprAST.cpp create mode 100644 src/ast/DoubleExprAST.h diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 3244e01..8944d26 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -54,7 +54,7 @@ void initInnerOperations(CompileUnit *unit) unit->binOperators.insert(std::pair, std::pair>( {"int", "int", "/"}, std::pair( - nullptr, new TypeAST(unit, "int")))); + nullptr, new TypeAST(unit, "double")))); unit->binOperators.insert(std::pair, std::pair>( @@ -115,7 +115,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - // std::cout << token.dump() << std::endl; + std::cout << token.dump() << std::endl; unit->tokenList.push_back(token); } while (token.type != tok_eof); diff --git a/src/Makefile.am b/src/Makefile.am index ce63552..ed1fcfd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ 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/ClassAST.cpp ast/CodeBlockAST.cpp ast/EmptyExprAST.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\ diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 50e0b98..db69018 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -51,7 +51,12 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) } else if (binOP == "*") { result.push_back(builder->CreateMul(L[0], R[0])); } else if (binOP == "/") { - result.push_back(builder->CreateSDiv(L[0], R[0])); + TypeAST * doubleType = new TypeAST(unit, "double"); + llvm::Value *lv = + builder->CreateSIToFP(L[0], doubleType->Codegen()); + llvm::Value *rv = + builder->CreateSIToFP(R[0], doubleType->Codegen()); + result.push_back(builder->CreateFDiv(lv, rv)); } else if (binOP == "%") { result.push_back(builder->CreateSRem(L[0], R[0])); } else if (binOP == "==") { diff --git a/src/ast/DoubleExprAST.cpp b/src/ast/DoubleExprAST.cpp new file mode 100644 index 0000000..f31d35c --- /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 0000000..58d2294 --- /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/ExprAST.cpp b/src/ast/ExprAST.cpp index 9c515dd..75df5c8 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -6,6 +6,7 @@ #include "BoolExprAST.h" #include "CallExprAST.h" #include "CodeBlockAST.h" +#include "DoubleExprAST.h" #include "EmptyExprAST.h" #include "IfExprAST.h" #include "IntExprAST.h" @@ -55,7 +56,13 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) switch (token.type) { case tok_number: { unit->next_tok(); - return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); + if (token.tokenValue.find(".") == std::string::npos) { + return new IntExprAST(unit, + strtol(token.tokenValue.c_str(), NULL, 10)); + + } else { + return new DoubleExprAST(unit, std::stod(token.tokenValue.c_str())); + } } case tok_key_literal: { unit->next_tok(); diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 75a0c05..7353b5f 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -7,8 +7,6 @@ #include "IntExprAST.h" #include "TypeAST.h" -#include -#include IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) { diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 3bf21f2..744e555 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -3,7 +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_12testPrintDouble6double(double a) { printf("%lf\n", a); } +extern void _alolang_15testPrintDouble6double(double a) { printf("%lf\n", a); } extern void _alolang_13testPrintBool4bool(int a) { if (a) { -- Gitee From 3520767248bbe162e71bdbc113d9da686d77ca16 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 16:32:57 +0800 Subject: [PATCH 63/98] Add support for double in binary operator --- src/CompileUnit.cpp | 52 +++++++++++++++++++++++ src/ast/BinaryExprAST.cpp | 87 ++++++++++++++++++++++++++------------- src/ast/BinaryExprAST.h | 4 ++ 3 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 8944d26..55e4cb6 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -55,6 +55,10 @@ void initInnerOperations(CompileUnit *unit) 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>( @@ -84,6 +88,54 @@ void initInnerOperations(CompileUnit *unit) 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) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index db69018..77d2a84 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -23,6 +23,64 @@ BinaryExprAST::~BinaryExprAST() // TODO Auto-generated destructor stub } +llvm::Value * +BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, + llvm::IRBuilder<> *builder) +{ + 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) { @@ -44,34 +102,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) this->type.push_back(operate->second.second); if (operate->second.first == nullptr) { //内置运算符 - if (binOP == "+") { - result.push_back(builder->CreateAdd(L[0], R[0])); - } else if (binOP == "-") { - result.push_back(builder->CreateSub(L[0], R[0])); - } else if (binOP == "*") { - result.push_back(builder->CreateMul(L[0], R[0])); - } else if (binOP == "/") { - TypeAST * doubleType = new TypeAST(unit, "double"); - llvm::Value *lv = - builder->CreateSIToFP(L[0], doubleType->Codegen()); - llvm::Value *rv = - builder->CreateSIToFP(R[0], doubleType->Codegen()); - result.push_back(builder->CreateFDiv(lv, rv)); - } else if (binOP == "%") { - result.push_back(builder->CreateSRem(L[0], R[0])); - } else if (binOP == "==") { - result.push_back(builder->CreateICmpEQ(L[0], R[0])); - } else if (binOP == "!=") { - result.push_back(builder->CreateICmpNE(L[0], R[0])); - } else if (binOP == ">") { - result.push_back(builder->CreateICmpSGT(L[0], R[0])); - } else if (binOP == "<") { - result.push_back(builder->CreateICmpSLT(L[0], R[0])); - } else if (binOP == ">=") { - result.push_back(builder->CreateICmpSGE(L[0], R[0])); - } else if (binOP == "<=") { - result.push_back(builder->CreateICmpSLE(L[0], R[0])); - } + result.push_back(processInnerBinaryOperator(L[0], R[0], builder)); } else { //用户定义运算符 CompileError e("User-def operator not implemented"); diff --git a/src/ast/BinaryExprAST.h b/src/ast/BinaryExprAST.h index 786ce3a..2641b76 100644 --- a/src/ast/BinaryExprAST.h +++ b/src/ast/BinaryExprAST.h @@ -21,6 +21,10 @@ class BinaryExprAST : public ExprAST 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_ */ -- Gitee From 9913dadec87ee7788cb42a63491df8dad6e4d43b Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sun, 28 Feb 2021 16:43:03 +0800 Subject: [PATCH 64/98] Fixed bug for float tokenizer --- src/CompileUnit.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index cebd623..826e6ea 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -54,7 +54,10 @@ void scanToken(CompileUnit *unit) else if (token.tokenValue.substr(0, 1) == "0") numTypeFlag = 8; char tmp[256]; - sprintf(tmp, "%ld", + 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) { -- Gitee From 3c24183664abd11ab7e6cd4860f0e56240998ca8 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 28 Feb 2021 20:29:47 +0800 Subject: [PATCH 65/98] Implement UnaryExprAST --- src/CompileUnit.cpp | 3 ++- src/ast/AssignmentAST.cpp | 24 ++++++++++++++++++++---- src/ast/ExprAST.cpp | 10 +++++++--- src/ast/TypeAST.cpp | 15 +++++++++------ src/ast/UnaryExprAST.cpp | 35 ++++++++++++++++++++++++++++++----- 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index e0aa61e..0373adb 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -37,6 +37,7 @@ void initInnerType(CompileUnit *unit) void initInnerOperations(CompileUnit *unit) { + // binOP unit->binOperators.insert(std::pair, std::pair>( {"int", "int", "+"}, std::pair( @@ -162,7 +163,7 @@ void scanToken(CompileUnit *unit) sprintf(tmp, "%f", strtod(token.tokenValue.c_str(), NULL)); else sprintf(tmp, "%ld", - strtol(token.tokenValue.c_str(), NULL, numTypeFlag)); + strtol(token.tokenValue.c_str(), NULL, numTypeFlag)); token.tokenValue = tmp; } else if (token.type == tok_str) { std::string str = token.tokenValue; diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp index 2a0fc62..e32aa63 100644 --- a/src/ast/AssignmentAST.cpp +++ b/src/ast/AssignmentAST.cpp @@ -11,6 +11,7 @@ #include "CodeBlockAST.h" #include "MemberExprAST.h" #include "TypeAST.h" +#include "UnaryExprAST.h" #include "VariableExprAST.h" AssignmentAST::AssignmentAST(CompileUnit *unit, std::vector LHS, @@ -30,8 +31,9 @@ AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, CodeBlockAST *codeblock) { std::vector LHS; //左侧变量 - Token token = *unit->icurTok; - ExprAST * curVar = nullptr; + Token token = *unit->icurTok; + ExprAST * curVar = nullptr; + int pointnum = 0; while (true) { token = *unit->icurTok; if (token.type == tok_identifier) { @@ -44,16 +46,30 @@ AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, throw e; } if (token.tokenValue == "=") { + for (int i = 0; i < pointnum; i++) { + curVar = new UnaryExprAST(unit, "*", curVar); + } LHS.push_back(curVar); - curVar = nullptr; + curVar = nullptr; + pointnum = 0; break; } else if (token.tokenValue == ",") { + for (int i = 0; i < pointnum; i++) { + curVar = new UnaryExprAST(unit, "*", curVar); + } unit->next_tok(); LHS.push_back(curVar); - curVar = nullptr; + curVar = nullptr; + pointnum = 0; + } else if (token.tokenValue == ".") { curVar = MemberExprAST::ParseMemberExprAST(unit, codeblock, curVar); + } else if (token.tokenValue == "*") { + pointnum++; + } else { + CompileError e("Unknown token:" + token.dump()); + throw e; } } } diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 75df5c8..de70587 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -59,7 +59,6 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) if (token.tokenValue.find(".") == std::string::npos) { return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); - } else { return new DoubleExprAST(unit, std::stod(token.tokenValue.c_str())); } @@ -111,10 +110,15 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) return new CallExprAST(unit, idName, args); } else { //变量或变量定义或赋值 - int i = 1; + int i = 1, ci = 1; while (true) { token = *(unit->icurTok + i); if (token.type == tok_syntax) { + if (token.tokenValue == "*") { + i++; + ci++; + continue; + } if (token.tokenValue == "=") { return AssignmentAST::ParseAssignment(unit, codeblock); break; @@ -130,7 +134,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) VariableDefExprAST::ParseVar(unit, codeblock); return varAST; } - } else if (token.type == tok_identifier && i == 1) { + } else if (token.type == tok_identifier && i == ci) { //变量定义 VariableDefExprAST *varAST = VariableDefExprAST::ParseVar(unit, codeblock); diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 7bd0022..f521b25 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -72,20 +72,23 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) CompileError e("Expected type but got " + token.dump()); throw e; } - std::string baseClass = token.tokenValue; + std::string baseClass = token.tokenValue; + std::vector genericTypes; token = unit->next_tok(); if (token.type == tok_syntax && token.tokenValue == "<") { - std::vector genericTypes; + unit->next_tok(); while (!(token.type == tok_syntax && token.tokenValue == ">")) { genericTypes.push_back(TypeAST::ParseType(unit)); token = *unit->icurTok; } - unit->next_tok(); - TypeAST *result = new TypeAST(unit, baseClass, genericTypes); - return result; + 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(); } - TypeAST *result = new TypeAST(unit, baseClass); return result; } diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 025720f..048128c 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -8,6 +8,7 @@ #include "UnaryExprAST.h" #include "../CompileError.hpp" #include "TypeAST.h" +#include "VariableExprAST.h" UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand) @@ -15,12 +16,14 @@ UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, { this->op = op; this->operand = operand; - if (op == "!") { + /*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() @@ -31,14 +34,36 @@ UnaryExprAST::~UnaryExprAST() std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; - if (op == "!") { - + if (op == "&") { + if (VariableExprAST *v = dynamic_cast(operand)) { + result.push_back(v->getAlloca()); + this->type.push_back(new TypeAST(unit, operand->type[0])); + } 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; } - result.push_back(builder->CreateXor(Rs[0], 1)); + + 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; } -- Gitee From 7d53cfcf3d0b78368650a3e870b6af2a61ab7c4c Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 1 Mar 2021 08:37:10 +0800 Subject: [PATCH 66/98] Rebuild Assignment AST --- src/ast/BinaryExprAST.cpp | 111 ++++++++++++++++++++++++++++++-------- src/ast/ExprAST.cpp | 44 ++++++++------- 2 files changed, 109 insertions(+), 46 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 77d2a84..dcc5246 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -7,7 +7,10 @@ #include "BinaryExprAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" +#include "MemberExprAST.h" #include "TypeAST.h" +#include "VariableExprAST.h" BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, ExprAST *RHS) @@ -80,33 +83,95 @@ BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, } return nullptr; } - std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) { - - std::vector L = LHS->CodegenChain(builder); - std::vector R = RHS->CodegenChain(builder); std::vector result; - 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)); + + 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; + 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]); + llvm::Value * 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); + } + + builder->CreateStore(RHSV[i], pointer); + } } else { - //用户定义运算符 - CompileError e("User-def operator not implemented"); - 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/ExprAST.cpp b/src/ast/ExprAST.cpp index de70587..cec0482 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -24,16 +24,17 @@ int GetTokPrecedence(Token tok) return -1; } std::map BinopPrecedence; - BinopPrecedence["=="] = 100; - BinopPrecedence[">"] = 100; - BinopPrecedence["<"] = 100; - BinopPrecedence[">="] = 100; - BinopPrecedence["<="] = 100; - BinopPrecedence["+"] = 200; - BinopPrecedence["-"] = 200; - BinopPrecedence["*"] = 300; - BinopPrecedence["/"] = 300; - BinopPrecedence["%"] = 300; + BinopPrecedence["=="] = 200; + BinopPrecedence[">"] = 200; + BinopPrecedence["<"] = 200; + BinopPrecedence[">="] = 200; + BinopPrecedence["<="] = 200; + BinopPrecedence["+"] = 300; + BinopPrecedence["-"] = 300; + BinopPrecedence["*"] = 400; + BinopPrecedence["/"] = 400; + BinopPrecedence["%"] = 400; + BinopPrecedence["="] = 100; int TokPrec = BinopPrecedence[tok.tokenValue]; if (TokPrec <= 0) { @@ -119,12 +120,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) ci++; continue; } - if (token.tokenValue == "=") { - return AssignmentAST::ParseAssignment(unit, codeblock); - break; - } else if (token.tokenValue != "," && - token.tokenValue != "." && - token.tokenValue != "<") { + if (token.tokenValue != "." && token.tokenValue != "<") { //变量 unit->next_tok(); return new VariableExprAST(unit, codeblock, idName); @@ -189,14 +185,20 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (LHS == nullptr) { return nullptr; } - ExprAST *result; + ExprAST *result = LHS; while (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ".") { LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); } - result = ParseBinOpRHS(unit, codeblock, 0, LHS); + Token token = *(unit->icurTok); + if (token.type == tok_syntax && token.tokenValue == ",") { + unit->next_tok(); + result->subExpr = ExprAST::ParseExpression(unit, codeblock, false); + } + + result = ParseBinOpRHS(unit, codeblock, 0, result); if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 @@ -204,11 +206,7 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (WhileExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } - Token token = *(unit->icurTok); - if (token.type == tok_syntax && token.tokenValue == ",") { - unit->next_tok(); - result->subExpr = ExprAST::ParseExpression(unit, codeblock, false); - } + token = *(unit->icurTok); if (root) { if (token.type != tok_syntax || token.tokenValue != ";") { CompileError e("丟失分号: \"" + token.dump() + "\" 前"); -- Gitee From 6d74cc4a9b857da6a6ff3a1141919371648d0762 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 1 Mar 2021 09:02:27 +0800 Subject: [PATCH 67/98] Fix a bug of multi-value expression --- src/ast/ExprAST.cpp | 75 ++++++++++++++++++++++++++------------------- src/ast/ExprAST.h | 2 ++ 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index cec0482..f7af486 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -35,6 +35,7 @@ int GetTokPrecedence(Token tok) BinopPrecedence["/"] = 400; BinopPrecedence["%"] = 400; BinopPrecedence["="] = 100; + BinopPrecedence[","] = 200; int TokPrec = BinopPrecedence[tok.tokenValue]; if (TokPrec <= 0) { @@ -52,51 +53,54 @@ ExprAST::~ExprAST() ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) { + ExprAST *result; // todo:除了函数调用之外的语句解析 Token token = *unit->icurTok; switch (token.type) { case tok_number: { unit->next_tok(); if (token.tokenValue.find(".") == std::string::npos) { - return new IntExprAST(unit, - strtol(token.tokenValue.c_str(), NULL, 10)); + result = new IntExprAST(unit, + strtol(token.tokenValue.c_str(), NULL, 10)); } else { - return new DoubleExprAST(unit, std::stod(token.tokenValue.c_str())); + 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: { - return WhileExprAST::ParseWhileExpr(unit, codeblock); + result = WhileExprAST::ParseWhileExpr(unit, codeblock); + break; } case tok_syntax: { if (token.tokenValue == "(") { unit->next_tok(); - ExprAST *result = ParseExpression(unit, codeblock, false); - token = *unit->icurTok; + result = ParseExpression(unit, codeblock, false); + token = *unit->icurTok; if (token.type != tok_syntax || token.tokenValue != ")") { CompileError e("missing ')'"); throw e; } unit->next_tok(); - return result; } else if (token.tokenValue == ")") { - return new EmptyExprAST(unit); + result = new EmptyExprAST(unit); } else { unit->next_tok(); - return new UnaryExprAST(unit, token.tokenValue, - ParseExpression(unit, codeblock, false)); - std::cerr << "error3:" << token.dump() << std::endl; + result = new UnaryExprAST(unit, token.tokenValue, + ParseExpression(unit, codeblock, false)); } break; } @@ -108,7 +112,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) //函数调用 token = unit->next_tok(); ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); - return new CallExprAST(unit, idName, args); + result = new CallExprAST(unit, idName, args); } else { //变量或变量定义或赋值 int i = 1, ci = 1; @@ -123,18 +127,16 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) if (token.tokenValue != "." && token.tokenValue != "<") { //变量 unit->next_tok(); - return new VariableExprAST(unit, codeblock, idName); + result = new VariableExprAST(unit, codeblock, idName); } else if (token.tokenValue == "<") { //变量定义 - VariableDefExprAST *varAST = - VariableDefExprAST::ParseVar(unit, codeblock); - return varAST; + result = VariableDefExprAST::ParseVar(unit, codeblock); } + break; } else if (token.type == tok_identifier && i == ci) { //变量定义 - VariableDefExprAST *varAST = - VariableDefExprAST::ParseVar(unit, codeblock); - return varAST; + result = VariableDefExprAST::ParseVar(unit, codeblock); + break; } i++; } @@ -149,12 +151,24 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) throw e; } } - return nullptr; + if (result == nullptr) { + 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; int TokPrec = GetTokPrecedence(token); @@ -174,7 +188,12 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, return nullptr; } } - LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); + if (token.tokenValue == ",") { + cExpr->subExpr = RHS; + cExpr = RHS; + } else { + LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); + } } } @@ -192,12 +211,6 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); } - Token token = *(unit->icurTok); - if (token.type == tok_syntax && token.tokenValue == ",") { - unit->next_tok(); - result->subExpr = ExprAST::ParseExpression(unit, codeblock, false); - } - result = ParseBinOpRHS(unit, codeblock, 0, result); if (IfExprAST *v = dynamic_cast(result)) { @@ -206,7 +219,7 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, if (WhileExprAST *v = dynamic_cast(result)) { return result; //跳过分号 } - token = *(unit->icurTok); + Token token = *(unit->icurTok); if (root) { if (token.type != tok_syntax || token.tokenValue != ";") { CompileError e("丟失分号: \"" + token.dump() + "\" 前"); diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index ee4c87f..c5770ad 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -18,4 +18,6 @@ class ExprAST : public BaseAST ExprAST * subExpr; }; +static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, + int ExprPrec, ExprAST *LHS); #endif /* COMPILER_AST_ASTEXPR_H_ */ -- Gitee From af18c036257a00595b5eb5450a810167858096e8 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 1 Mar 2021 09:10:58 +0800 Subject: [PATCH 68/98] Support assignment of pointer --- src/Makefile.am | 2 +- src/ast/AssignmentAST.cpp | 137 -------------------------------------- src/ast/AssignmentAST.h | 26 -------- src/ast/BinaryExprAST.cpp | 89 ++++++++++++++----------- src/ast/ExprAST.cpp | 1 - 5 files changed, 52 insertions(+), 203 deletions(-) delete mode 100644 src/ast/AssignmentAST.cpp delete mode 100644 src/ast/AssignmentAST.h diff --git a/src/Makefile.am b/src/Makefile.am index ed1fcfd..325ae09 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ 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/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\ diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp deleted file mode 100644 index e32aa63..0000000 --- a/src/ast/AssignmentAST.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * AssignmentAST.cpp - * - * Created on: Feb 17, 2021 - * Author: zbc - */ - -#include "AssignmentAST.h" -#include "../CompileError.hpp" -#include "ClassAST.h" -#include "CodeBlockAST.h" -#include "MemberExprAST.h" -#include "TypeAST.h" -#include "UnaryExprAST.h" -#include "VariableExprAST.h" - -AssignmentAST::AssignmentAST(CompileUnit *unit, std::vector 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) -{ - std::vector LHS; //左侧变量 - Token token = *unit->icurTok; - ExprAST * curVar = nullptr; - int pointnum = 0; - while (true) { - token = *unit->icurTok; - if (token.type == tok_identifier) { - curVar = new VariableExprAST(unit, codeblock, token.tokenValue); - unit->next_tok(); - } - if (token.type == tok_syntax) { - if (curVar == nullptr) { - CompileError e("Expected variable before assignment"); - throw e; - } - if (token.tokenValue == "=") { - for (int i = 0; i < pointnum; i++) { - curVar = new UnaryExprAST(unit, "*", curVar); - } - LHS.push_back(curVar); - curVar = nullptr; - pointnum = 0; - break; - } else if (token.tokenValue == ",") { - for (int i = 0; i < pointnum; i++) { - curVar = new UnaryExprAST(unit, "*", curVar); - } - unit->next_tok(); - LHS.push_back(curVar); - curVar = nullptr; - pointnum = 0; - - } else if (token.tokenValue == ".") { - curVar = - MemberExprAST::ParseMemberExprAST(unit, codeblock, curVar); - } else if (token.tokenValue == "*") { - pointnum++; - } else { - CompileError e("Unknown token:" + token.dump()); - throw e; - } - } - } - unit->next_tok(); - return new AssignmentAST(unit, LHS, - ExprAST::ParseExpression(unit, codeblock, false)); -} - -std::vector AssignmentAST::Codegen(llvm::IRBuilder<> *builder) -{ - std::vector RHSV = RHS->CodegenChain(builder); - 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; - 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]); - llvm::Value * 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); - } - - builder->CreateStore(RHSV[i], pointer); - } - return std::vector(); -} diff --git a/src/ast/AssignmentAST.h b/src/ast/AssignmentAST.h deleted file mode 100644 index 2fc6742..0000000 --- a/src/ast/AssignmentAST.h +++ /dev/null @@ -1,26 +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, std::vector LHS, ExprAST *RHS); - virtual ~AssignmentAST(); - std::vector Codegen(llvm::IRBuilder<> *builder); - static AssignmentAST * ParseAssignment(CompileUnit * unit, - CodeBlockAST *codeblock); - std::vector LHS; //左侧变量 - ExprAST * RHS; -}; - -#endif /* SRC_AST_ASSIGNMENTAST_H_ */ diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index dcc5246..e19cc9f 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -10,6 +10,7 @@ #include "ClassAST.h" #include "MemberExprAST.h" #include "TypeAST.h" +#include "UnaryExprAST.h" #include "VariableExprAST.h" BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, @@ -102,48 +103,60 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) for (unsigned int i = 0; i < LHS.size(); i++) { ExprAST * curAST = LHS[i]; std::vector chain; - 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."); + llvm::Value * pointer; + 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]; } - } - VariableExprAST *start = - dynamic_cast(chain[chain.size() - 1]); - llvm::Value * 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; + } else { + 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; + } } - 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); + 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); + 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); + } } builder->CreateStore(RHSV[i], pointer); diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index f7af486..f9a16c4 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -1,7 +1,6 @@ #include "ExprAST.h" #include "../CompileError.hpp" #include "../utils.h" -#include "AssignmentAST.h" #include "BinaryExprAST.h" #include "BoolExprAST.h" #include "CallExprAST.h" -- Gitee From 09c748623a0ba1d1a19b875a53e7c7c9bf09320d Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 1 Mar 2021 13:42:12 +0800 Subject: [PATCH 69/98] Fix a bug in Unary operation --- src/ast/ExprAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index f9a16c4..225a94f 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -99,7 +99,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) } else { unit->next_tok(); result = new UnaryExprAST(unit, token.tokenValue, - ParseExpression(unit, codeblock, false)); + ParsePrimary(unit, codeblock)); } break; } -- Gitee From 5b1a97122da0a8d78ac1dc0fa128d9676d75f825 Mon Sep 17 00:00:00 2001 From: gongzichun2 <27604962238@qq.com> Date: Mon, 1 Mar 2021 20:15:54 +0800 Subject: [PATCH 70/98] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=BA=86=E8=AE=B8?= =?UTF-8?q?=E5=A4=9A=E2=80=9CAlolang=E5=85=B3=E9=94=AE=E5=AD=97:=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/_sidebar.md | 82 ++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 0375d35..ffcad92 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,54 +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关键字:type](language/keyword/type/type/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) + * [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) * [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) + * [int16_t](language/keyword/type/int16_t/index) + * [array](language/keyword/type/array/index) + * [int32_t](language/keyword/type/int32_t/index) * [alolang关键词: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) -- Gitee From b19960f0f860ad662c5c4278c03127e153f95e20 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 1 Mar 2021 22:44:36 +0800 Subject: [PATCH 71/98] added test code --- test/classanytype.alo | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/classanytype.alo diff --git a/test/classanytype.alo b/test/classanytype.alo new file mode 100644 index 0000000..4aba7db --- /dev/null +++ b/test/classanytype.alo @@ -0,0 +1,27 @@ +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; + + testPrintInt(test1.data); + testPrintInt(test2.data); + testPrintInt(test3.data); + testPrintInt(*test1.succ.data); + testPrintInt(*test1.pred.data); + +} \ No newline at end of file -- Gitee From 224cb96dad4c13061eac0228d36c81ff3d197df9 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 1 Mar 2021 22:49:21 +0800 Subject: [PATCH 72/98] fixed lexer part --- src/yacc_stuff/tokenizer.lpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 03c3936..cff2c9b 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -37,7 +37,7 @@ fun token = tok_fun; return token func token = tok_fun; return token; extern token = tok_extern; return token; return token = tok_return; return token; -[a-zA-Z_][a-zA-Z_]* token = tok_identifier; 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; -- Gitee From f20a0f1944ab5f91c1297f2d4f55195c55a0b5f1 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 1 Mar 2021 23:03:01 +0800 Subject: [PATCH 73/98] Fix a bug in expression paser --- src/ast/ExprAST.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 225a94f..a97ad83 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -113,7 +113,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); result = new CallExprAST(unit, idName, args); } else { - //变量或变量定义或赋值 + //变量或变量定义 int i = 1, ci = 1; while (true) { token = *(unit->icurTok + i); @@ -123,7 +123,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) ci++; continue; } - if (token.tokenValue != "." && token.tokenValue != "<") { + if (token.tokenValue != "<") { //变量 unit->next_tok(); result = new VariableExprAST(unit, codeblock, idName); -- Gitee From 40f062c1eeb219ba8928cc6dbf604afdba28ade2 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 19:07:02 +0800 Subject: [PATCH 74/98] Fixed some syntax errors within the classanytype.alo --- test/classanytype.alo | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 4aba7db..3f56bd5 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -15,13 +15,13 @@ func main() { test1.succ = &test3; test1.data = 1; - *test1.pred.data = 2; - *test1.succ.data = 3; + *(test1.pred).data = 2; + *(test1.succ).data = 3; testPrintInt(test1.data); testPrintInt(test2.data); testPrintInt(test3.data); - testPrintInt(*test1.succ.data); - testPrintInt(*test1.pred.data); + testPrintInt(*(test1.succ).data); + testPrintInt(*(test1.pred).data); } \ No newline at end of file -- Gitee From 431338e5ef4b78b395bf1f6706bd0d1e31f13ab1 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 19:31:32 +0800 Subject: [PATCH 75/98] Lowered the VSC ext required vsc version --- .../vscode/alolang/alolang-0.0.6.vsix | Bin 0 -> 5279 bytes .../vscode/alolang/package.json | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 syntax_highlight_plugin/vscode/alolang/alolang-0.0.6.vsix 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 GIT binary patch literal 5279 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 IMR51^KTB&h@c;k- literal 0 HcmV?d00001 diff --git a/syntax_highlight_plugin/vscode/alolang/package.json b/syntax_highlight_plugin/vscode/alolang/package.json index 4d73b30..b4d50f1 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.5", + "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" -- Gitee From 861f5ba72cdaaac9bddd062d74890bb616b80efb Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 19:43:45 +0800 Subject: [PATCH 76/98] midified test case --- test/classanytype.alo | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 3f56bd5..c460879 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -18,10 +18,12 @@ func main() { *(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); } \ No newline at end of file -- Gitee From 90450cd5abb29a2309e39800797fd2c195dbeb5b Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 2 Mar 2021 20:12:39 +0800 Subject: [PATCH 77/98] Rebuild ExprAST --- src/ast/ExprAST.cpp | 116 ++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 31 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index a97ad83..22ad527 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -17,24 +17,55 @@ #include "WhileExprAST.h" #include -int GetTokPrecedence(Token tok) +std::map BinopPrecedence; +std::map UnaryopPrecedence; + +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; + + UnaryopPrecedence["!"] = 13; + UnaryopPrecedence["&"] = 13; +} + +int GetBinTokPrecedence(Token tok) { if (tok.type != tok_syntax) { return -1; } - std::map BinopPrecedence; - BinopPrecedence["=="] = 200; - BinopPrecedence[">"] = 200; - BinopPrecedence["<"] = 200; - BinopPrecedence[">="] = 200; - BinopPrecedence["<="] = 200; - BinopPrecedence["+"] = 300; - BinopPrecedence["-"] = 300; - BinopPrecedence["*"] = 400; - BinopPrecedence["/"] = 400; - BinopPrecedence["%"] = 400; - BinopPrecedence["="] = 100; - BinopPrecedence[","] = 200; int TokPrec = BinopPrecedence[tok.tokenValue]; if (TokPrec <= 0) { @@ -43,7 +74,24 @@ int GetTokPrecedence(Token tok) return TokPrec; } -ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) { subExpr = nullptr; } +int GetUnaryTokPrecedence(Token tok) +{ + if (tok.type != tok_syntax) { + return -1; + } + + int TokPrec = UnaryopPrecedence[tok.tokenValue]; + if (TokPrec <= 0) { + return -1; + } + return TokPrec; +} + +ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) +{ + subExpr = nullptr; + initTokPrecedence(); +} ExprAST::~ExprAST() { @@ -96,10 +144,11 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) unit->next_tok(); } else if (token.tokenValue == ")") { result = new EmptyExprAST(unit); + } else if (GetUnaryTokPrecedence(token) != -1) { + result = nullptr; } else { - unit->next_tok(); - result = new UnaryExprAST(unit, token.tokenValue, - ParsePrimary(unit, codeblock)); + CompileError e("不期待的syntax_token:" + token.dump()); + throw e; } break; } @@ -150,9 +199,6 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) throw e; } } - if (result == nullptr) { - return nullptr; - } /*if (token.type == tok_syntax && token.tokenValue == ",") { unit->next_tok(); ExprAST *subExpr = ParseBinOpRHS(unit, codeblock, 200, result); @@ -169,8 +215,13 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, { ExprAST *cExpr = LHS; while (1) { - Token token = *unit->icurTok; - int TokPrec = GetTokPrecedence(token); + Token token = *unit->icurTok; + int TokPrec; + if (LHS == nullptr) { + TokPrec = GetUnaryTokPrecedence(token); + } else { + TokPrec = GetBinTokPrecedence(token); + } if (TokPrec < ExprPrec) { return LHS; } @@ -180,7 +231,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, if (!RHS) return nullptr; - int NextPrec = GetTokPrecedence(*(unit->icurTok)); + int NextPrec = GetBinTokPrecedence(*(unit->icurTok)); if (TokPrec < NextPrec) { RHS = ParseBinOpRHS(unit, codeblock, TokPrec + 1, RHS); if (RHS == nullptr) { @@ -190,6 +241,13 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, 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); + } else { + CompileError e("成员方法调用未实现"); + throw e; + } } else { LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); } @@ -199,16 +257,12 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root) { - ExprAST *LHS = ParsePrimary(unit, codeblock); - if (LHS == nullptr) { - return nullptr; - } - ExprAST *result = LHS; + ExprAST *result = ParsePrimary(unit, codeblock); - while (unit->icurTok->type == tok_syntax && + /*while (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ".") { LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); - } + }*/ result = ParseBinOpRHS(unit, codeblock, 0, result); -- Gitee From c44d36e44888418e6f07b13995897c68b38da9d1 Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 2 Mar 2021 20:50:55 +0800 Subject: [PATCH 78/98] Fix a bug in UnaryExprAST --- src/ast/ExprAST.cpp | 42 ++++++++++++++++++++++++++++------------ src/ast/UnaryExprAST.cpp | 3 ++- src/ast/UnaryExprAST.h | 4 +++- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 22ad527..9827985 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -18,7 +18,8 @@ #include std::map BinopPrecedence; -std::map UnaryopPrecedence; +std::map LUnaryopPrecedence; +std::map RUnaryopPrecedence; void initTokPrecedence() { @@ -57,8 +58,9 @@ void initTokPrecedence() BinopPrecedence["."] = 14; - UnaryopPrecedence["!"] = 13; - UnaryopPrecedence["&"] = 13; + LUnaryopPrecedence["*"] = 13; + LUnaryopPrecedence["!"] = 13; + LUnaryopPrecedence["&"] = 13; } int GetBinTokPrecedence(Token tok) @@ -74,13 +76,26 @@ int GetBinTokPrecedence(Token tok) return TokPrec; } -int GetUnaryTokPrecedence(Token tok) +int GetLUnaryTokPrecedence(Token tok) { if (tok.type != tok_syntax) { return -1; } - int TokPrec = UnaryopPrecedence[tok.tokenValue]; + 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; } @@ -142,13 +157,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) throw e; } unit->next_tok(); - } else if (token.tokenValue == ")") { - result = new EmptyExprAST(unit); - } else if (GetUnaryTokPrecedence(token) != -1) { - result = nullptr; } else { - CompileError e("不期待的syntax_token:" + token.dump()); - throw e; + result = new EmptyExprAST(unit); } break; } @@ -218,7 +228,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, Token token = *unit->icurTok; int TokPrec; if (LHS == nullptr) { - TokPrec = GetUnaryTokPrecedence(token); + TokPrec = GetLUnaryTokPrecedence(token); } else { TokPrec = GetBinTokPrecedence(token); } @@ -248,6 +258,14 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, 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); } diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 048128c..902d82e 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -11,11 +11,12 @@ #include "VariableExprAST.h" UnaryExprAST::UnaryExprAST(CompileUnit *unit, const std::string &op, - ExprAST *operand) + 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 == "&") { diff --git a/src/ast/UnaryExprAST.h b/src/ast/UnaryExprAST.h index 2b080e0..7db1f32 100644 --- a/src/ast/UnaryExprAST.h +++ b/src/ast/UnaryExprAST.h @@ -13,11 +13,13 @@ class UnaryExprAST : public ExprAST { public: - UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand); + 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_ */ -- Gitee From d71486e3936795209c634908f2a2dae736bdd1ee Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 20:59:25 +0800 Subject: [PATCH 79/98] some random bug. idk what caused it --- src/preprocessor.h | 3 +++ test/demoa+b.alo | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/preprocessor.h b/src/preprocessor.h index a89cba3..b3e69a6 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -4,9 +4,12 @@ #include #include #include +#include +#include #include #include std::string preProcess(const std::string &code, int cnt); +// extern static std::vector>; #endif diff --git a/test/demoa+b.alo b/test/demoa+b.alo index 3ceb74e..b78f0c5 100644 --- a/test/demoa+b.alo +++ b/test/demoa+b.alo @@ -14,6 +14,12 @@ func main() a = testGetInt(); b = testGetInt(); - c = a + b; + // c = a & b; + // testPrintInt(c); + // c = a | b; + // testPrintInt(c); + c = a - b; + testPrintInt(c); + c = a * b; testPrintInt(c); } \ No newline at end of file -- Gitee From 9b2b4e3d5ae43221fc292b4b997d27b4b409786b Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 2 Mar 2021 22:08:39 +0800 Subject: [PATCH 80/98] Fix a bug in the parser of definition --- src/ast/ExprAST.cpp | 7 ++++--- src/ast/ExprAST.h | 3 ++- src/ast/UnaryExprAST.cpp | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 9827985..ad14f5f 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -113,7 +113,8 @@ 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:除了函数调用之外的语句解析 @@ -177,7 +178,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) while (true) { token = *(unit->icurTok + i); if (token.type == tok_syntax) { - if (token.tokenValue == "*") { + if (token.tokenValue == "*" && root) { i++; ci++; continue; @@ -275,7 +276,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root) { - ExprAST *result = ParsePrimary(unit, codeblock); + ExprAST *result = ParsePrimary(unit, codeblock, root); /*while (unit->icurTok->type == tok_syntax && unit->icurTok->tokenValue == ".") { diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index c5770ad..f76f396 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -13,7 +13,8 @@ class ExprAST : public BaseAST std::vector CodegenChain(llvm::IRBuilder<> *builder); static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); - static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock); + static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, + bool root = false); std::vector type; ExprAST * subExpr; }; diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 902d82e..74d0cf6 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -7,6 +7,7 @@ #include "UnaryExprAST.h" #include "../CompileError.hpp" +#include "MemberExprAST.h" #include "TypeAST.h" #include "VariableExprAST.h" @@ -39,6 +40,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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)) { } else { CompileError e("& can only be used with variable"); throw e; -- Gitee From dc8d0e08f737b2a38f7f96c8843647c8a3a4d390 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 22:19:51 +0800 Subject: [PATCH 81/98] Rework of preprocessor and lexer. Now tokens are corresponding with the correct line no --- src/CompileUnit.cpp | 81 +++++++++++++++++++++++--------------------- src/CompileUnit.h | 12 ++++--- src/Token.h | 1 + src/aloc.cpp | 4 +-- src/preprocessor.cpp | 29 +++++++++------- src/preprocessor.h | 6 ++-- 6 files changed, 73 insertions(+), 60 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 0373adb..43ca721 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -141,52 +141,57 @@ void initInnerOperations(CompileUnit *unit) void scanToken(CompileUnit *unit) { - Token token; - do { - int tokenid = unit->lexer->yylex(); - token.type = TokenType(tokenid); - token.lineno = unit->lexer->lineno(); - 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]; - if (token.tokenValue.find(".") != std::string::npos) - sprintf(tmp, "%f", strtod(token.tokenValue.c_str(), NULL)); - else - sprintf(tmp, "%ld", + for (Tline line : unit->srclines) { + std::istringstream is(line.second); + FlexLexer * lexer = new yyFlexLexer(is, std::cerr); + Token token; + + do { + 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); - } + 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; + // Debug token dump + std::cout << token.dump() << std::endl; - unit->tokenList.push_back(token); - } while (token.type != tok_eof); + unit->tokenList.push_back(token); + } while (token.type != tok_eof); + } unit->icurTok = unit->tokenList.begin(); } -CompileUnit::CompileUnit(std::string name, std::string source) +CompileUnit::CompileUnit(std::string name, 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(name, *context); + name = name; + srclines = lines; + context = new llvm::LLVMContext(); + module = new llvm::Module(name, *context); } CompileUnit::~CompileUnit() {} diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 2b8ccf5..0c8ceda 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 @@ -23,16 +24,17 @@ 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; + // FlexLexer * lexer; + std::string name; + // std::string source; + // std::istringstream sis; + std::vector srclines; llvm::LLVMContext * context; llvm::Module * module; std::vector tokenList; diff --git a/src/Token.h b/src/Token.h index 3944c6d..ec517de 100644 --- a/src/Token.h +++ b/src/Token.h @@ -46,6 +46,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 7cb97c4..417ff9f 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -101,13 +101,13 @@ 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); - cout << preProcessed; + // cout << preProcessed; // todo:这行代码写的极不规范,尽快修改 CompileUnit(input_file_name, preProcessed).compile(); system(("llc ./" + input_file_name + diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 9f83202..5c6b608 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); //解析后的预编译指令 @@ -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,26 +158,29 @@ std::string doReplace(std::string &line) } //递归预处理 -std::string preProcess(const std::string &code, int cnt) +std::vector preProcess(const std::string &code, int cnt) { 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); //处理块注释 @@ -216,10 +219,10 @@ std::string preProcess(const std::string &code, int cnt) } int plen = result.length(); if (plen > 0) { - preprocessoroutput << result << std::endl; + processedLines.push_back(Tline(std::pair("",lineno),result)); } } temp.erase(); } - return preprocessoroutput.str(); + return processedLines; } diff --git a/src/preprocessor.h b/src/preprocessor.h index b3e69a6..2462083 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -9,7 +9,9 @@ #include #include -std::string preProcess(const std::string &code, int cnt); -// extern static std::vector>; +typedef std::pair,std::string> Tline; + +std::vector preProcess(const std::string &code, int cnt); + #endif -- Gitee From 6e783ad871d7e9a8a94cf60832744c96374510ce Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 2 Mar 2021 22:44:02 +0800 Subject: [PATCH 82/98] Fix the bug of '&' operator of MemberExprAST --- src/ast/UnaryExprAST.cpp | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 74d0cf6..1aa70f9 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -7,6 +7,7 @@ #include "UnaryExprAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" #include "MemberExprAST.h" #include "TypeAST.h" #include "VariableExprAST.h" @@ -41,6 +42,53 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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; -- Gitee From 6c60c767410f38c057c0e3990f89455cf5473d0f Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 22:46:57 +0800 Subject: [PATCH 83/98] Fixed a lot of things. And add the utimate test case for current todo --- .vscode/launch.json | 27 +++++++++++++++++++++++++++ .vscode/settings.json | 21 ++++++++++++++++++++- src/CompileUnit.cpp | 15 +++++++++------ test/classanytype.alo | 4 ++++ 4 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6feb2a4 --- /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 cc67606..6d68035 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/src/CompileUnit.cpp b/src/CompileUnit.cpp index 43ca721..90a2325 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -146,7 +146,7 @@ void scanToken(CompileUnit *unit) FlexLexer * lexer = new yyFlexLexer(is, std::cerr); Token token; - do { + while (1) { int tokenid = lexer->yylex(); token.type = TokenType(tokenid); token.file = line.first.first; @@ -178,17 +178,20 @@ void scanToken(CompileUnit *unit) // Debug token dump std::cout << token.dump() << std::endl; - + if (token.type == tok_eof) + break; unit->tokenList.push_back(token); - } while (token.type != tok_eof); + } } - + Token TEOF; + TEOF.type = tok_eof; + unit->tokenList.push_back(TEOF); unit->icurTok = unit->tokenList.begin(); } -CompileUnit::CompileUnit(std::string name, std::vector lines) +CompileUnit::CompileUnit(std::string Iname, std::vector lines) { - name = name; + name = Iname; srclines = lines; context = new llvm::LLVMContext(); module = new llvm::Module(name, *context); diff --git a/test/classanytype.alo b/test/classanytype.alo index c460879..d24d989 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -26,4 +26,8 @@ func main() { testPrintInt(*(test1.succ).data); testPrintInt(*(test1.pred).data); testPrintInt(*testint1); + + if (1) + testPrintInt(114514); + } \ No newline at end of file -- Gitee From 8125820d8c4a391e2dd768b13d8cc2911d979f13 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 22:59:45 +0800 Subject: [PATCH 84/98] done with all filename and lineno things --- src/Token.cpp | 2 +- src/aloc.cpp | 2 +- src/preprocessor.cpp | 6 +++--- src/preprocessor.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Token.cpp b/src/Token.cpp index 744f0e0..8c7984e 100644 --- a/src/Token.cpp +++ b/src/Token.cpp @@ -102,7 +102,7 @@ std::string Token::dump() default: typeStr = "not defined"; } - ss << std::left << "Line " << std::setw(6) << lineno + 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/aloc.cpp b/src/aloc.cpp index 417ff9f..b8ee59e 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -106,7 +106,7 @@ int main(int argc, char *argv[]) // 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/preprocessor.cpp b/src/preprocessor.cpp index 5c6b608..2e5be87 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -45,7 +45,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l 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; @@ -158,7 +158,7 @@ std::string doReplace(std::string &line) } //递归预处理 -std::vector 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"); @@ -219,7 +219,7 @@ std::vector preProcess(const std::string &code, int cnt) } int plen = result.length(); if (plen > 0) { - processedLines.push_back(Tline(std::pair("",lineno),result)); + processedLines.push_back(Tline(std::pair(FN,lineno),result)); } } temp.erase(); diff --git a/src/preprocessor.h b/src/preprocessor.h index 2462083..6d56b80 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -11,7 +11,7 @@ typedef std::pair,std::string> Tline; -std::vector preProcess(const std::string &code, int cnt); +std::vector preProcess(const std::string &code, int cnt, std::string FN); #endif -- Gitee From bed32fc3995334f03588f6b718f4514b78ceaebd Mon Sep 17 00:00:00 2001 From: gongzichun2 <27604962238@qq.com> Date: Tue, 2 Mar 2021 23:06:30 +0800 Subject: [PATCH 85/98] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E4=BF=AE=E9=A5=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/language/keyword/alternative/and/index.md | 2 +- docs/language/keyword/alternative/not/index.md | 2 +- docs/language/keyword/alternative/or/index.md | 2 +- docs/language/keyword/alternative/xor/index.md | 2 +- docs/language/keyword/literal/EOF/index.md | 2 +- docs/language/keyword/literal/false/index.md | 2 +- docs/language/keyword/literal/true/index.md | 2 +- docs/language/keyword/statements/break/index.md | 2 +- docs/language/keyword/statements/case/index.md | 2 +- docs/language/keyword/statements/catch/index.md | 2 +- docs/language/keyword/statements/continue/index.md | 2 +- docs/language/keyword/statements/do/index.md | 2 +- docs/language/keyword/statements/else/index.md | 2 +- docs/language/keyword/statements/export/index.md | 2 +- docs/language/keyword/statements/extern/index.md | 2 +- docs/language/keyword/statements/for/index.md | 2 +- docs/language/keyword/statements/foreach/index.md | 2 +- docs/language/keyword/statements/goto/index.md | 2 +- docs/language/keyword/statements/if/index.md | 2 +- docs/language/keyword/statements/return/index.md | 2 +- docs/language/keyword/statements/switch/index.md | 2 +- docs/language/keyword/statements/try/index.md | 2 +- docs/language/keyword/statements/while/index.md | 2 +- docs/language/keyword/type/anytype/index.md | 2 +- docs/language/keyword/type/array/index.md | 2 +- docs/language/keyword/type/auto/index.md | 2 +- docs/language/keyword/type/bool/index.md | 2 +- docs/language/keyword/type/char/index.md | 2 +- docs/language/keyword/type/double/index.md | 2 +- docs/language/keyword/type/enum/index.md | 2 +- docs/language/keyword/type/float/index.md | 2 +- docs/language/keyword/type/int/index.md | 2 +- docs/language/keyword/type/int16_t/index.md | 2 +- docs/language/keyword/type/int32_t/index.md | 2 +- docs/language/keyword/type/int8_t/index.md | 2 +- docs/language/keyword/type/long/index.md | 2 +- docs/language/keyword/type/signed/index.md | 2 +- docs/language/keyword/type/string/index.md | 2 +- docs/language/keyword/type/struct/index.md | 2 +- docs/language/keyword/type/type/index.md | 2 +- docs/language/keyword/type/unsigned/index.md | 2 +- docs/language/keyword/type/void/index.md | 2 +- docs/library/graph/index.md | 2 +- docs/library/math/index.md | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/docs/language/keyword/alternative/and/index.md b/docs/language/keyword/alternative/and/index.md index 3ff2b5e..5c93427 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 d821dec..b3de3d5 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 22494f6..2bcbece 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 fae5145..1f01e02 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/literal/EOF/index.md b/docs/language/keyword/literal/EOF/index.md index c0e89ce..8058f76 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 92187ba..f329e82 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 f48833c..43fa7f4 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 4c67158..b548031 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 4706a93..be5b8aa 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 9180827..1acaf8a 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 5b17c45..b462977 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 0cc3655..2173ecf 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 26b9314..95a8145 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 7243710..8ee897d 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 f9ca999..94ef703 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 e63ffa8..9de2a9b 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 154b3bb..2d1eb17 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 d9d94ec..8966368 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 88fbb74..1838d62 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 07c8cc2..553b91f 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 5c2cdb4..e41b5db 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 20af4b1..ec7df3b 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 a65549e..a8c40e6 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 2488a87..34865ea 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 10857c7..7dd5450 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 c94c56e..c424048 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 6a66e00..ea6a73f 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 eb657d2..6a3cb48 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 6767579..74bfbd3 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 254e144..234fdc1 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 0d028a7..f663297 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/int/index.md b/docs/language/keyword/type/int/index.md index 034f8af..31378ca 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 273d20b..8dae763 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 5d7f43f..a076f99 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 9955c01..074768b 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 9d50199..cf1fd0a 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 3715571..40650cb 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 935151a..b1782b9 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 73bdaae..eecdc5e 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 index 547309c..b56b89b 100644 --- a/docs/language/keyword/type/type/index.md +++ b/docs/language/keyword/type/type/index.md @@ -1,4 +1,4 @@ -# alolang关键字:type +# type * 类型别名标识符 diff --git a/docs/language/keyword/type/unsigned/index.md b/docs/language/keyword/type/unsigned/index.md index e601524..2390515 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 513e5bc..575d9db 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 63456fb..6a33e51 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 291ae7a..c0cc1c3 100644 --- a/docs/library/math/index.md +++ b/docs/library/math/index.md @@ -1,4 +1,4 @@ -# alolang库:math +# math #### **abs(x)** -- Gitee From 8b5ae206eb81834d3caea899be3b5c97e7e057b0 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 23:12:19 +0800 Subject: [PATCH 86/98] Changed all parser compile error, to make more readable error message --- src/ast/ExprAST.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index ad14f5f..eb70a21 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -206,7 +206,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, return ReturnExprAST::ParseReturnExprAST(unit, codeblock); } default: { - CompileError e("不期待的token:" + token.dump()); + CompileError e("不期待的token:" + token.dump(),token.file,token.lineno); throw e; } } @@ -294,7 +294,8 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, Token token = *(unit->icurTok); if (root) { if (token.type != tok_syntax || token.tokenValue != ";") { - CompileError e("丟失分号: \"" + token.dump() + "\" 前"); + CompileError e("丟失分号: \"" + token.dump() + "\" 前", token.file, + token.lineno); throw e; } unit->next_tok(); -- Gitee From 52d0bfa9a99626fe18ec03ec04d04300fef70bdb Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 23:13:33 +0800 Subject: [PATCH 87/98] last commit didn't commited correctly... --- src/CompileError.hpp | 2 +- src/ast/ClassAST.cpp | 4 ++-- src/ast/CodeBlockAST.cpp | 2 +- src/ast/ExternAST.cpp | 5 +++-- src/ast/MemberExprAST.cpp | 2 +- src/ast/PrototypeAST.cpp | 4 ++-- src/ast/TypeAST.cpp | 2 +- src/ast/VariableDefExprAST.cpp | 2 +- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/CompileError.hpp b/src/CompileError.hpp index ac3108c..1413c74 100644 --- a/src/CompileError.hpp +++ b/src/CompileError.hpp @@ -28,7 +28,7 @@ class CompileError : public std::exception error = whatError; file = whatFile; line = whatLine; - message = file + ": " + std::to_string(line) + ": " + error; + message = file + ":" + std::to_string(line) + ": " + error; } }; #endif diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index a3a5b64..53c4bcf 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -28,7 +28,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) { Token token = unit->next_tok(); if (token.type != tok_identifier) { - CompileError e("Expected identifier"); + CompileError e("Expected identifier",token.file,token.lineno); throw e; } std::string className = token.tokenValue; @@ -48,7 +48,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) token = unit->next_tok(); } if (token.type != tok_syntax || token.tokenValue != "{") { - CompileError e("Expected {"); + CompileError e("Expected {",token.file,token.lineno); throw e; } std::map members; diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 2be5131..cbd9b79 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -57,7 +57,7 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, } return codeblock; } else { - CompileError e("Expected codeblock"); + CompileError e("Expected codeblock",token.file,token.lineno); throw e; } } diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 3c64a14..3f6c5bd 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -30,7 +30,7 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) } else if (flag.tokenValue == "C") { C = true; } else { - CompileError e("Unknown flag:" + flag.tokenValue); + CompileError e("Unknown flag:" + flag.tokenValue,flag.file,flag.lineno); throw e; } } @@ -44,7 +44,8 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) << "Function extern found:" << proto->name << std::endl; Token token = *(unit->icurTok); if (token.type != tok_syntax || token.tokenValue != ";") { - CompileError e("丟失分号: \"" + token.dump() + "\" 前"); + CompileError e("丟失分号: \"" + token.dump() + "\" 前", token.file, + token.lineno); throw e; } token = unit->next_tok(); diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index a2d44cd..3275984 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -29,7 +29,7 @@ MemberExprAST *MemberExprAST::ParseMemberExprAST(CompileUnit * unit, { Token token = unit->next_tok(); if (token.type != tok_identifier) { - CompileError e("Expected identifier"); + CompileError e("Expected identifier",token.file,token.lineno); throw e; } MemberExprAST *result = new MemberExprAST(unit, LHS, token.tokenValue); diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index aa09eca..9aa187c 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -107,13 +107,13 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } 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; } } diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index f521b25..cd90d0a 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -69,7 +69,7 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) { Token token = *unit->icurTok; if (token.type != tok_identifier) { - CompileError e("Expected type but got " + token.dump()); + CompileError e("Expected type but got " + token.dump(),token.file,token.lineno); throw e; } std::string baseClass = token.tokenValue; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index 890e96e..f7c1c29 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -115,7 +115,7 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, unit->next_tok(); initValue = ExprAST::ParseExpression(unit, codeblock, false); } else { - CompileError e("Unknown token:" + nexToken.dump()); + CompileError e("Unknown token:" + nexToken.dump(),nexToken.file,nexToken.lineno); throw e; } } -- Gitee From fbb99bf1d8437e529dcb22e02adf44e644018152 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 23:14:04 +0800 Subject: [PATCH 88/98] A little bugfix --- src/CompileError.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CompileError.hpp b/src/CompileError.hpp index 1413c74..5e3da65 100644 --- a/src/CompileError.hpp +++ b/src/CompileError.hpp @@ -20,7 +20,7 @@ class CompileError : public std::exception error = whatError; file = whatFile; line = whatLine; - message = file + ": " + std::to_string(line) + ": " + error; + message = file + ":" + std::to_string(line) + ": " + error; } CompileError(const std::string &whatError, std::string whatFile = "", uint64_t whatLine = 0) -- Gitee From e477d8904a58d7405b481d3569350bdac89a4960 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Tue, 2 Mar 2021 23:15:33 +0800 Subject: [PATCH 89/98] Sync website --- docs/_sidebar.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index ffcad92..1611859 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -24,12 +24,12 @@ * [signed](language/keyword/type/signed/index) * [double](language/keyword/type/double/index) * [int8_t](language/keyword/type/int8_t/index) - * [alolang关键词:unsigned](language/keyword/type/unsigned/index) - * [alolang关键字:int](language/keyword/type/int/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) - * [alolang关键词:auto](language/keyword/type/auto/index) + * [auto](language/keyword/type/auto/index) * [空标识符 `_`](language/keyword/blank/index) * [代用运算符的关键字](language/keyword/alternative/index) * [and](language/keyword/alternative/and/index) -- Gitee From 9db088be3e293c70ef7e63b496fee7cf0c0fb2a6 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 3 Mar 2021 22:31:12 +0800 Subject: [PATCH 90/98] bug a lot --- src/lib/testPuts.c | 7 +++++++ test/demoa+b.alo | 22 ++++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 744e555..c7e9ade 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -19,3 +19,10 @@ extern int _alolang_10testGetInt() scanf("%d", &a); return a; } + +extern double _alolang_13testGetDouble() +{ + double a; + scanf("%f", &a); + return a; +} \ No newline at end of file diff --git a/test/demoa+b.alo b/test/demoa+b.alo index b78f0c5..82ac5b6 100644 --- a/test/demoa+b.alo +++ b/test/demoa+b.alo @@ -1,25 +1,27 @@ -extern func testPrintInt(int i); -extern "S" func testGetInt() -> int; +extern func testPrintDouble(double i); +extern "S" func testGetDouble() -> double; func main() { - int a = 2; - int b; - int c; + double a = 2; + double b; + double c; b = 9; c = a + b; - testPrintInt(c); + testPrintDouble(c); - a = testGetInt(); - b = testGetInt(); + a = testGetDouble(); + b = testGetDouble(); // c = a & b; // testPrintInt(c); // c = a | b; // testPrintInt(c); + c = a + b; + testPrintDouble(c); c = a - b; - testPrintInt(c); + testPrintDouble(c); c = a * b; - testPrintInt(c); + testPrintDouble(c); } \ No newline at end of file -- Gitee From 178c5c71b1cf8e197c22f63a683a39afeb1e28dd Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 3 Mar 2021 22:34:34 +0800 Subject: [PATCH 91/98] bugfix --- src/lib/testPuts.c | 2 +- test/demoa+b.alo | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index c7e9ade..2fab4ee 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -23,6 +23,6 @@ extern int _alolang_10testGetInt() extern double _alolang_13testGetDouble() { double a; - scanf("%f", &a); + scanf("%lf", &a); return a; } \ No newline at end of file diff --git a/test/demoa+b.alo b/test/demoa+b.alo index 82ac5b6..d79af8a 100644 --- a/test/demoa+b.alo +++ b/test/demoa+b.alo @@ -3,17 +3,19 @@ extern "S" func testGetDouble() -> double; func main() { - double a = 2; + double a = 2.0; double b; double c; - b = 9; + b = 9.0; c = a + b; testPrintDouble(c); a = testGetDouble(); b = testGetDouble(); + testPrintDouble(a); + testPrintDouble(b); // c = a & b; // testPrintInt(c); // c = a | b; -- Gitee From 29eb09bf7ea4f6daaf4fb8d44c8718ebe04a3f20 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 4 Mar 2021 19:02:13 +0800 Subject: [PATCH 92/98] Remove old code --- src/CompileUnit.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 0c8ceda..4a9be8a 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -30,10 +30,7 @@ class CompileUnit Token next_tok(); void build(); - // FlexLexer * lexer; - std::string name; - // std::string source; - // std::istringstream sis; + std::string name; std::vector srclines; llvm::LLVMContext * context; llvm::Module * module; -- Gitee From 507c3b0d9eefed145e7cc7ad35c3359b6eb1d07b Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 4 Mar 2021 19:06:09 +0800 Subject: [PATCH 93/98] Support single-expression codeblock --- src/ast/CodeBlockAST.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index cbd9b79..7c599db 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -31,10 +31,11 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, CodeBlockAST * parent, const std::vector args) { - Token token = *unit->icurTok; + Token token = *unit->icurTok; + CodeBlockAST *codeblock = + new CodeBlockAST(unit, std::vector(), name, parent); + if (token.type == tok_syntax && token.tokenValue == "{") { - CodeBlockAST *codeblock = - new CodeBlockAST(unit, std::vector(), name, parent); std::vector &body = codeblock->body; for (VariableDefExprAST *argDef : args) { argDef->codeblock = codeblock; @@ -55,11 +56,16 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, } body.push_back(ExprAST::ParseExpression(unit, codeblock, true)); } - return codeblock; } else { - CompileError e("Expected codeblock",token.file,token.lineno); - throw e; + 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; } llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) -- Gitee From e41cc1197bb0924ecf40e1de0528913b9d31c3e7 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 4 Mar 2021 20:12:15 +0800 Subject: [PATCH 94/98] Fix the bug related to the pointer of incomplete types --- src/CompileUnit.cpp | 2 +- src/CompileUnit.h | 1 - src/ast/ClassAST.cpp | 24 ++++++++++++++++++++++-- src/ast/TypeAST.cpp | 10 +++++++--- src/ast/TypeAST.h | 4 +++- src/ast/VariableExprAST.cpp | 3 +++ 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 90a2325..de656c6 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -177,7 +177,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - std::cout << token.dump() << std::endl; + // std::cout << token.dump() << std::endl; if (token.type == tok_eof) break; unit->tokenList.push_back(token); diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 4a9be8a..7c620ab 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -47,7 +47,6 @@ class CompileUnit std::map types; // Codgen用 std::map> globalVariablesValue; // Codgen用 - // std::map }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 53c4bcf..d9f935f 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -28,7 +28,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) { Token token = unit->next_tok(); if (token.type != tok_identifier) { - CompileError e("Expected identifier",token.file,token.lineno); + CompileError e("Expected identifier", token.file, token.lineno); throw e; } std::string className = token.tokenValue; @@ -48,7 +48,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) token = unit->next_tok(); } if (token.type != tok_syntax || token.tokenValue != "{") { - CompileError e("Expected {",token.file,token.lineno); + CompileError e("Expected {", token.file, token.lineno); throw e; } std::map members; @@ -71,8 +71,17 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) 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(); @@ -88,8 +97,18 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) 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(); @@ -101,5 +120,6 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) sMembers.push_back(mType->Codegen()); } llvm_S->setBody(sMembers); + return llvm_S; } diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index cd90d0a..b6235b9 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -17,7 +17,12 @@ TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, this->baseClass = baseClass; this->genericTypes = genericTypes; this->pointee = nullptr; + initName(); //生成name +} + +void TypeAST::initName() +{ this->name = baseClass; if (genericTypes.size() != 0) { this->name += "<"; @@ -52,8 +57,6 @@ llvm::Type *TypeAST::Codegen() throw e; } else { llvm::Type *classType = classAST->second->Codegen(genericTypes); - unit->types.insert( - std::pair(name, classType)); return classType; //构建泛型 } @@ -69,7 +72,8 @@ 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); + CompileError e("Expected type but got " + token.dump(), token.file, + token.lineno); throw e; } std::string baseClass = token.tokenValue; diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 5008869..ea0269a 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -17,7 +17,9 @@ class TypeAST : public BaseAST std::vector genericTypes = std::vector()); TypeAST(CompileUnit *unit, TypeAST *pointee); virtual ~TypeAST(); - static TypeAST * ParseType(CompileUnit *unit); + static TypeAST *ParseType(CompileUnit *unit); + void initName(); + llvm::Type * Codegen(); std::string name; std::string baseClass; diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 93b3973..fbe3c5d 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -41,6 +41,9 @@ llvm::Value *VariableExprAST::getAlloca() } else { alloca = varAST->second.second; type.push_back(varAST->second.first); + if (varAST->second.first->name == "") { + std::cout << "fuck" << std::endl; + } return alloca; } } -- Gitee From 3d7859af3ffb599f229dd692c18bde5c49e5c232 Mon Sep 17 00:00:00 2001 From: uebian <2452973529@qq.com> Date: Thu, 4 Mar 2021 20:35:43 +0800 Subject: [PATCH 95/98] Fix the bug in test --- test/classanytype.alo | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index d24d989..73844a7 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -15,16 +15,16 @@ func main() { test1.succ = &test3; test1.data = 1; - *(test1.pred).data = 2; - *(test1.succ).data = 3; + (*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((*test1.succ).data); + testPrintInt((*test1.pred).data); testPrintInt(*testint1); if (1) -- Gitee From 4236d148c8a470ffe809a9aaadba53b78c4d2a77 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 4 Mar 2021 22:00:33 +0800 Subject: [PATCH 96/98] Implement '->' operator --- src/Token.cpp | 8 +++----- src/Token.h | 1 - src/ast/BinaryExprAST.cpp | 30 ++++++++++++++++++++++++------ src/ast/ExprAST.cpp | 15 ++++++++++++--- src/ast/MemberExprAST.cpp | 23 +++++++---------------- src/ast/MemberExprAST.h | 7 +++---- src/ast/PrototypeAST.cpp | 7 ++++--- src/yacc_stuff/tokenizer.lpp | 3 +-- 8 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/Token.cpp b/src/Token.cpp index 8c7984e..bc963b8 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; @@ -102,7 +99,8 @@ std::string Token::dump() default: typeStr = "not defined"; } - ss << std::right << std::setw(25) << file << ":" << std::left << 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 ec517de..7943dd7 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, diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index e19cc9f..4f5dd4a 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -104,6 +104,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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 + @@ -117,20 +118,35 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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; } } - VariableExprAST *start = - dynamic_cast(chain[chain.size() - 1]); - pointer = start->getAlloca(); + 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; - 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; @@ -154,8 +170,10 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); } if (idx.size() != 0) { - pointer = builder->CreateGEP(start->type[0]->Codegen(), - pointer, idxl); + auto typeAST = unit->types.find(startType); + + pointer = + builder->CreateGEP(typeAST->second, pointer, idxl); } } diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index eb70a21..b227f25 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -56,7 +56,8 @@ void initTokPrecedence() BinopPrecedence[".*"] = 12; - BinopPrecedence["."] = 14; + BinopPrecedence["."] = 14; + BinopPrecedence["->"] = 14; LUnaryopPrecedence["*"] = 13; LUnaryopPrecedence["!"] = 13; @@ -206,7 +207,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, return ReturnExprAST::ParseReturnExprAST(unit, codeblock); } default: { - CompileError e("不期待的token:" + token.dump(),token.file,token.lineno); + CompileError e("不期待的token:" + token.dump(), token.file, + token.lineno); throw e; } } @@ -254,7 +256,14 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, cExpr = RHS; } else if (token.tokenValue == ".") { if (VariableExprAST *v = dynamic_cast(RHS)) { - LHS = new MemberExprAST(unit, LHS, v->idName); + 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; diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index 3275984..b460a15 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -11,11 +11,12 @@ #include "TypeAST.h" MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *LHS, - std::string member) + std::string member, bool isPointer) : ExprAST(unit) { - this->LHS = LHS; - this->member = member; + this->LHS = LHS; + this->member = member; + this->isPointer = isPointer; } MemberExprAST::~MemberExprAST() @@ -23,22 +24,12 @@ MemberExprAST::~MemberExprAST() // TODO Auto-generated destructor stub } -MemberExprAST *MemberExprAST::ParseMemberExprAST(CompileUnit * unit, - CodeBlockAST *codeblock, - ExprAST * LHS) +std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) { - Token token = unit->next_tok(); - if (token.type != tok_identifier) { - CompileError e("Expected identifier",token.file,token.lineno); + if (isPointer) { + CompileError e("未实现."); throw e; } - MemberExprAST *result = new MemberExprAST(unit, LHS, token.tokenValue); - unit->next_tok(); - return result; -} - -std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) -{ std::vector result; std::vector bases = LHS->Codegen(builder); if (bases.size() != 1) { diff --git a/src/ast/MemberExprAST.h b/src/ast/MemberExprAST.h index e801465..410e5f4 100644 --- a/src/ast/MemberExprAST.h +++ b/src/ast/MemberExprAST.h @@ -13,14 +13,13 @@ class MemberExprAST : public ExprAST { public: - MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member); + MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member, + bool isPointer); virtual ~MemberExprAST(); std::vector Codegen(llvm::IRBuilder<> *builder); - static MemberExprAST * ParseMemberExprAST(CompileUnit * unit, - CodeBlockAST *codeblock, - ExprAST * LHS); 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 9aa187c..044efe5 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -80,7 +80,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) token = *(unit->icurTok); // -> or ; or { std::vector returnTypes; - if (token.type == tok_return_type) { + if (token.type == tok_syntax && token.tokenValue == "->") { unit->next_tok(); int bc = 0; while (true) { @@ -107,13 +107,14 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } else { if (token.tokenValue == "{") { if (!hasBody) { - CompileError e("Unexpected function body",token.file,token.lineno); + CompileError e("Unexpected function body", token.file, + token.lineno); throw e; } } if (token.tokenValue == ";") { if (hasBody) { - CompileError e("Unexpected ;",token.file,token.lineno); + CompileError e("Unexpected ;", token.file, token.lineno); throw e; } } diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index cff2c9b..f2f0d44 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -32,7 +32,6 @@ case|switch token = tok_key_switch; return token class token = tok_key_class; return token; --> token = tok_return_type; return token; fun token = tok_fun; return token; func token = tok_fun; return token; extern token = tok_extern; return token; @@ -46,7 +45,7 @@ return token = tok_return; 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; -- Gitee From 78883783f38db884529702114ecfe86a12419139 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 4 Mar 2021 22:09:13 +0800 Subject: [PATCH 97/98] changed test --- test/classanytype.alo | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 73844a7..5b75efc 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -15,19 +15,19 @@ func main() { test1.succ = &test3; test1.data = 1; - (*test1.pred).data = 2; - (*test1.succ).data = 3; + 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(*(test1.succ).data); + testPrintInt(*(test1.pred).data); testPrintInt(*testint1); - if (1) + if (true) testPrintInt(114514); } \ No newline at end of file -- Gitee From bae2afe58c8446c00f03ee652aea39ffa54cc4ee Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 4 Mar 2021 22:20:48 +0800 Subject: [PATCH 98/98] fixed test code bug --- test/classanytype.alo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 5b75efc..92f0abc 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -23,8 +23,8 @@ func main() { testPrintInt(test1.data); testPrintInt(test2.data); testPrintInt(test3.data); - testPrintInt(*(test1.succ).data); - testPrintInt(*(test1.pred).data); + testPrintInt((*(test1.succ)).data); + testPrintInt((*(test1.pred)).data); testPrintInt(*testint1); if (true) -- Gitee