From 93acb12b9f15e34048b3aa5acaf18b8f62a46f86 Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 5 Mar 2021 19:52:21 +0800 Subject: [PATCH 01/95] Fix a bug in multi generic types --- src/ast/TypeAST.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index b6235b9..a50feec 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -83,9 +83,20 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) if (token.type == tok_syntax && token.tokenValue == "<") { unit->next_tok(); - while (!(token.type == tok_syntax && token.tokenValue == ">")) { + while (true) { genericTypes.push_back(TypeAST::ParseType(unit)); token = *unit->icurTok; + if (token.type == tok_syntax) { + if (token.tokenValue == ",") { + token = unit->next_tok(); + } else if (token.tokenValue == ">") { + break; + } else { + CompileError e("Unknown token " + token.dump(), token.file, + token.lineno); + throw e; + } + } } token = unit->next_tok(); } -- Gitee From 2e51d4b40768f3a41360fecadd7e06887956f9c5 Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 5 Mar 2021 20:05:22 +0800 Subject: [PATCH 02/95] Implement demangle of class --- src/ast/ClassAST.cpp | 11 +++++++---- src/ast/ClassAST.h | 1 + src/utils.cpp | 6 +++++- src/utils.h | 3 ++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index d9f935f..3b0fbfe 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -58,10 +58,13 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) if (token.type == tok_syntax && token.tokenValue == "}") { break; } - VariableDefExprAST *memberDef = - VariableDefExprAST::ParseVar(unit, nullptr); - members.insert(std::pair( - memberDef->idName, memberDef)); + if (token.type == tok_fun) { + } else { + VariableDefExprAST *memberDef = + VariableDefExprAST::ParseVar(unit, nullptr); + members.insert(std::pair( + memberDef->idName, memberDef)); + } } token = unit->next_tok(); ClassAST *classAST = new ClassAST(unit, className, members, genericTypes); diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 4ef01e1..45cb0ac 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -22,6 +22,7 @@ class ClassAST : public BaseAST TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); static ClassAST * ParseClass(CompileUnit *unit); std::map members; + std::map functions; std::vector genericTypes; std::string className; }; diff --git a/src/utils.cpp b/src/utils.cpp index 65a81c7..4ef9fa5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -15,10 +15,14 @@ char syntax[] = {'!', '%', '^', '&', '*', '(', ')', '+', '=', '{', ',', '<', '>', '?', '.', '/', '#', ' '}; std::string demangle(const std::string & fnName, - const std::vector &argTypes) + const std::vector &argTypes, + const std::string & className) { std::stringstream ss; ss << "_alolang_"; + if (className != "") { + ss << "C" << className.length() << className; + } ss << fnName.length() << fnName; for (TypeAST *word : argTypes) { ss << word->name.length() << word->name; //得到类型 diff --git a/src/utils.h b/src/utils.h index 2532903..bc2b521 100644 --- a/src/utils.h +++ b/src/utils.h @@ -13,7 +13,8 @@ #include std::string demangle(const std::string & fnName, - const std::vector &argTypes); + const std::vector &argTypes, + const std::string & className = ""); bool isSyntax(char c); void skipSpace(const std::vector &words, long unsigned int &i); -- Gitee From a289e968d73f9a09fd65f32f4e3fb6af85dea5a8 Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 5 Mar 2021 20:58:05 +0800 Subject: [PATCH 03/95] Implement the codegen of method --- src/ast/ClassAST.cpp | 30 ++++++++++++++++++++++++------ src/ast/ClassAST.h | 1 + src/ast/CodeBlockAST.cpp | 22 ++++++++++++---------- src/ast/CodeBlockAST.h | 6 ++++-- src/ast/FunctionAST.cpp | 24 ++++++++++++++++-------- src/ast/FunctionAST.h | 14 +++++++++----- src/ast/IfExprAST.cpp | 6 ++++-- src/ast/PrototypeAST.cpp | 19 +++++++++++++------ src/ast/PrototypeAST.h | 10 +++++++--- src/ast/WhileExprAST.cpp | 3 ++- 10 files changed, 92 insertions(+), 43 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 3b0fbfe..9a1518b 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -7,15 +7,18 @@ #include "ClassAST.h" #include "../CompileError.hpp" +#include "FunctionAST.h" #include "TypeAST.h" ClassAST::ClassAST(CompileUnit *unit, const std::string &className, std::map members, + std::map functions, std::vector genericTypes) : BaseAST(unit) { this->className = className; this->members = members; + this->functions = functions; this->genericTypes = genericTypes; } @@ -51,23 +54,32 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) CompileError e("Expected {", token.file, token.lineno); throw e; } - std::map members; + + ClassAST *classAST = new ClassAST( + unit, className, std::map(), + std::map(), genericTypes); + unit->next_tok(); while (true) { - token = unit->next_tok(); //解析成员方法,成员变量 + token = *(unit->icurTok); if (token.type == tok_syntax && token.tokenValue == "}") { break; } if (token.type == tok_fun) { + FunctionAST *funDef = FunctionAST::ParseFunction(unit, classAST); + classAST->functions.insert(std::pair( + funDef->getDemangledName(), funDef)); + } else { VariableDefExprAST *memberDef = VariableDefExprAST::ParseVar(unit, nullptr); - members.insert(std::pair( - memberDef->idName, memberDef)); + classAST->members.insert( + std::pair(memberDef->idName, + memberDef)); + unit->next_tok(); } } - token = unit->next_tok(); - ClassAST *classAST = new ClassAST(unit, className, members, genericTypes); + token = unit->next_tok(); return classAST; } @@ -124,5 +136,11 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) } llvm_S->setBody(sMembers); + std::map::iterator function_iter; + for (function_iter = functions.begin(); function_iter != functions.end(); + function_iter++) { + function_iter->second->Codegen(); + } + return llvm_S; } diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 45cb0ac..3959533 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -16,6 +16,7 @@ class ClassAST : public BaseAST public: ClassAST(CompileUnit *unit, const std::string &className, std::map members, + std::map functions, std::vector genericTypes); virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 7c599db..8c4183e 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -11,14 +11,16 @@ #include CodeBlockAST::CodeBlockAST(CompileUnit *unit, std::vector body, - std::string name, CodeBlockAST *parent) + std::string name, FunctionAST *baseFunction, + CodeBlockAST *parent) : BaseAST(unit) { - this->builder = new llvm::IRBuilder<>(*unit->context); - this->body = body; - this->name = name; - this->parent = parent; - this->endBB = nullptr; + this->builder = new llvm::IRBuilder<>(*unit->context); + this->body = body; + this->name = name; + this->parent = parent; + this->endBB = nullptr; + this->baseFunction = baseFunction; } CodeBlockAST::~CodeBlockAST() @@ -28,12 +30,12 @@ CodeBlockAST::~CodeBlockAST() CodeBlockAST * CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, - CodeBlockAST * parent, + FunctionAST *baseFunction, CodeBlockAST *parent, const std::vector args) { - Token token = *unit->icurTok; - CodeBlockAST *codeblock = - new CodeBlockAST(unit, std::vector(), name, parent); + Token token = *unit->icurTok; + CodeBlockAST *codeblock = new CodeBlockAST(unit, std::vector(), + name, baseFunction, parent); if (token.type == tok_syntax && token.tokenValue == "{") { std::vector &body = codeblock->body; diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 6ec37d0..789a0d0 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -18,10 +18,11 @@ class CodeBlockAST : public BaseAST { public: CodeBlockAST(CompileUnit *unit, std::vector exprs, - std::string name, CodeBlockAST *parent = nullptr); + std::string name, FunctionAST *baseFunction, + CodeBlockAST *parent = nullptr); virtual ~CodeBlockAST(); static CodeBlockAST * - ParseCodeBlock(CompileUnit *unit, std::string name, + ParseCodeBlock(CompileUnit *unit, std::string name,FunctionAST *baseFunction, CodeBlockAST * parent = nullptr, const std::vector args = std::vector()); @@ -34,6 +35,7 @@ class CodeBlockAST : public BaseAST std::string name; CodeBlockAST * parent; llvm::BasicBlock *endBB; + FunctionAST * baseFunction; }; #endif /* COMPILER_AST_CODEBLOCKAST_H_ */ diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index 8d70a59..ccc3b2a 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -16,11 +16,12 @@ #include FunctionAST::FunctionAST(CompileUnit *unit, PrototypeAST *proto, - CodeBlockAST *body) + CodeBlockAST *body, ClassAST *parentClass) : BaseAST(unit) { - this->proto = proto; - this->body = body; + this->proto = proto; + this->body = body; + this->parentClass = parentClass; } FunctionAST::~FunctionAST() @@ -28,7 +29,7 @@ FunctionAST::~FunctionAST() // TODO Auto-generated destructor stub } -llvm::Function *FunctionAST::Codegen() +llvm::Function *FunctionAST::Codegen(std::vector igenericTypes) { llvm::Function * func = proto->Codegen(); llvm::BasicBlock *bb = body->Codegen(func); @@ -37,9 +38,11 @@ llvm::Function *FunctionAST::Codegen() return func; } -FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) +FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit, + ClassAST * parentClass) { - PrototypeAST *protoType = PrototypeAST::ParsePrototype(unit, true); + PrototypeAST *protoType = + PrototypeAST::ParsePrototype(unit, true, parentClass); std::cout << std::left << std::setw(35) << "Function definition found:" << protoType->name << std::endl; std::vector args; @@ -48,8 +51,13 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) args.push_back(new VariableDefExprAST(unit, nullptr, arg.second, arg.first, nullptr, i)); } + FunctionAST *result = + new FunctionAST(unit, protoType, nullptr, parentClass); + CodeBlockAST *body = - CodeBlockAST::ParseCodeBlock(unit, "entry", nullptr, args); - return new FunctionAST(unit, protoType, body); + CodeBlockAST::ParseCodeBlock(unit, "entry", result, nullptr, args); + result->body = body; + + return result; } std::string FunctionAST::getDemangledName() { return proto->demangledName; } diff --git a/src/ast/FunctionAST.h b/src/ast/FunctionAST.h index ea78823..17d1dad 100644 --- a/src/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -17,14 +17,18 @@ class FunctionAST : public BaseAST { public: - FunctionAST(CompileUnit *unit, PrototypeAST *proto, CodeBlockAST *body); + FunctionAST(CompileUnit *unit, PrototypeAST *proto, CodeBlockAST *body, + ClassAST *parentClass = nullptr); virtual ~FunctionAST(); - llvm::Function *Codegen(); - std::string getDemangledName(); - PrototypeAST * proto; + llvm::Function * + Codegen(std::vector igenericTypes = std::vector()); + std::string getDemangledName(); + PrototypeAST *proto; + ClassAST * parentClass; CodeBlockAST * body; - static FunctionAST *ParseFunction(CompileUnit *unit); + static FunctionAST *ParseFunction(CompileUnit *unit, + ClassAST * parentClass = nullptr); }; #endif /* COMPILER_AST_FUNCTIONAST_H_ */ diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index d799786..4265545 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -29,12 +29,14 @@ IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) { unit->next_tok(); ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); - CodeBlockAST *thenBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); + CodeBlockAST *thenBlock = + CodeBlockAST::ParseCodeBlock(unit, "", parent->baseFunction, parent); CodeBlockAST *elseBlock = nullptr; if ((unit->icurTok + 1)->type == tok_key_else) { unit->next_tok(); - elseBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); + elseBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent->baseFunction, + parent); } return new IfExprAST(unit, parent, condition, thenBlock, elseBlock); } diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 044efe5..53c4022 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -8,26 +8,32 @@ #include "PrototypeAST.h" #include "../CompileError.hpp" #include "../utils.h" +#include "ClassAST.h" #include "TypeAST.h" - #include PrototypeAST::PrototypeAST( CompileUnit *unit, const std::string &name, const std::vector> &args, - const std::vector & returnTypes) + const std::vector &returnTypes, ClassAST *parentClass) : BaseAST(unit) { this->name = name; this->args = args; this->returnDirectly = false; this->returnTypes = returnTypes; + this->parentClass = parentClass; std::vector argStr; for (std::pair pair : args) { argStr.push_back(pair.first); } if (name != "main") { - this->demangledName = demangle(name, argStr); + if (parentClass == nullptr) { + this->demangledName = demangle(name, argStr); + } else { + this->demangledName = + demangle(name, argStr, parentClass->className); + } } else { this->demangledName = "main"; } @@ -38,7 +44,8 @@ PrototypeAST::~PrototypeAST() // TODO Auto-generated destructor stub } -PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) +PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, + ClassAST *parentClass) { std::vector> args; Token token = unit->next_tok(); @@ -119,10 +126,10 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) } } } - return new PrototypeAST(unit, FnName, args, returnTypes); + return new PrototypeAST(unit, FnName, args, returnTypes, parentClass); } -llvm::Function *PrototypeAST::Codegen() +llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) { std::vector llvmArgs; for (int i = 0; i < args.size(); i++) { diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index 886d3f7..f3f0963 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -15,10 +15,13 @@ class PrototypeAST : public BaseAST public: PrototypeAST(CompileUnit *unit, const std::string &name, const std::vector> &args, - const std::vector &returnTypes); + const std::vector &returnTypes, + ClassAST * parentClass); virtual ~PrototypeAST(); - llvm::Function * Codegen(); - static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody); + llvm::Function * + Codegen(std::vector igenericTypes = std::vector()); + static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody, + ClassAST *parentClass = nullptr); std::vector> args; std::string demangledName; @@ -26,6 +29,7 @@ class PrototypeAST : public BaseAST std::vector returnTypes; std::string name; bool returnDirectly; //直接返回 + ClassAST * parentClass; }; #endif /* COMPILER_AST_PROTOTYPEAST_H_ */ diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 585ade1..5ca4440 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -57,6 +57,7 @@ WhileExprAST *WhileExprAST::ParseWhileExpr(CompileUnit * unit, { unit->next_tok(); ExprAST * condition = ExprAST::ParseExpression(unit, parent, false); - CodeBlockAST *body = CodeBlockAST::ParseCodeBlock(unit, "", parent); + CodeBlockAST *body = + CodeBlockAST::ParseCodeBlock(unit, "", parent->baseFunction, parent); return new WhileExprAST(unit, parent, condition, body); } -- Gitee From 50a6e88ccd28fd84dac9d4ad40c300f918b7719e Mon Sep 17 00:00:00 2001 From: uebian Date: Fri, 5 Mar 2021 23:44:48 +0800 Subject: [PATCH 04/95] Implement method --- src/CompileUnit.cpp | 31 +++++++++++++------------------ src/CompileUnit.h | 26 ++++++++++++++------------ src/ast/CallExprAST.cpp | 31 +++++++++++++------------------ src/ast/CallExprAST.h | 4 +++- src/ast/ClassAST.cpp | 33 +++++++++++++++++++++++++-------- src/ast/ClassAST.h | 3 +++ src/ast/ExprAST.cpp | 9 ++++++--- src/ast/ExternAST.cpp | 11 +++-------- src/ast/ExternAST.h | 1 - src/ast/FunctionAST.cpp | 10 +++++++--- src/ast/FunctionAST.h | 1 - src/ast/PrototypeAST.cpp | 33 ++++++++++++++++----------------- src/ast/PrototypeAST.h | 2 -- src/ast/TypeAST.cpp | 13 +++++++++++++ src/ast/TypeAST.h | 1 + src/utils.cpp | 2 +- 16 files changed, 118 insertions(+), 93 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index de656c6..ac5e1b7 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -217,8 +217,7 @@ void CompileUnit::compile() switch (icurTok->type) { case tok_fun: { FunctionAST *func_ast = FunctionAST::ParseFunction(this); - functions.insert(std::pair( - func_ast->getDemangledName(), func_ast)); + functions.push_back(func_ast); // llvm::Function *func = func_ast->Codegen(); /*llvm::Type* type=llvm::FunctionType::get(llvm::Type::getVoidTy(*context), @@ -234,8 +233,7 @@ void CompileUnit::compile() } case tok_extern: { ExternAST *externast = ExternAST::ParseExtern(this); - externs.insert(std::pair( - externast->getDemangledName(), externast)); + externs.push_back(externast); break; } case tok_identifier: { @@ -243,15 +241,13 @@ void CompileUnit::compile() VariableDefExprAST *var = VariableDefExprAST::ParseVar(this, nullptr); Token token = next_tok(); - globalVariables.insert( - std::pair(var->idName, var)); + globalVariables.push_back(var); break; } case tok_key_class: { ClassAST *classAST = ClassAST::ParseClass(this); classes.insert(std::pair( classAST->className, classAST)); - classesO.push_back(classAST); break; } default: { @@ -265,20 +261,19 @@ void CompileUnit::compile() llvm::Type *classType = classAST->Codegen(); }*/ - std::map::iterator gVar_iter; - for (gVar_iter = globalVariables.begin(); - gVar_iter != globalVariables.end(); gVar_iter++) { - gVar_iter->second->Codegen(nullptr); + for (VariableDefExprAST *v : globalVariables) { + v->Codegen(nullptr); //自动插入globalVariablesValue } std::map::iterator extern_iter; - for (extern_iter = externs.begin(); extern_iter != externs.end(); - extern_iter++) { - extern_iter->second->Codegen(); + for (ExternAST *v : externs) { + llvm::Function *f = v->Codegen(); + globalFunctions.insert( + std::pair>( + f->getName(), + std::pair(v->proto, f))); } - std::map::iterator function_iter; - for (function_iter = functions.begin(); function_iter != functions.end(); - function_iter++) { - function_iter->second->Codegen(); + for (FunctionAST *v : functions) { + llvm::Function *f = v->Codegen(); //自动插入globalFunctions } build(); diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 7c620ab..47b997b 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -21,6 +21,7 @@ class FunctionAST; class ExternAST; class VariableDefExprAST; class ClassAST; +class PrototypeAST; class CompileUnit { public: @@ -30,23 +31,24 @@ class CompileUnit Token next_tok(); void build(); - std::string name; - std::vector srclines; - llvm::LLVMContext * context; - llvm::Module * module; - std::vector tokenList; - std::vector::iterator icurTok; - std::map classes; - std::vector classesO; - std::map globalVariables; - std::vector globalVariablesO; - std::map functions; - std::map externs; + std::string name; + std::vector srclines; + llvm::LLVMContext * context; + llvm::Module * module; + std::vector tokenList; + std::vector::iterator icurTok; + std::map classes; + std::vector globalVariables; + std::vector functions; + std::vector externs; + std::map, std::pair> binOperators; // LHS type,RHS type,binOP std::map types; // Codgen用 std::map> globalVariablesValue; // Codgen用 + std::map> + globalFunctions; // Codegen用 }; #endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 5fe2ced..11ab213 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -15,11 +15,12 @@ #include "../utils.h" CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, - ExprAST *args) + ExprAST *args, ExprAST *LHS) : ExprAST(unit) { this->callee = callee; this->args = args; + this->LHS = LHS; std::cout << std::left << std::setw(35) << "Function call found:" << this->callee << std::endl; } @@ -38,20 +39,22 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) for (TypeAST *ast : args->type) { argStr.push_back(ast); } - std::string dname = demangle(callee, argStr); + std::string dname; + llvm::Value *LHSv; //新构造 + if (LHS == nullptr) { + dname = demangle(callee, argStr); + } else { + LHSv = LHS->Codegen(builder)[0]; + dname = demangle(callee, argStr, LHS->type[0]->getMangleName()); + } 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; + auto functionAST = unit->globalFunctions.find(dname); + if (functionAST != unit->globalFunctions.end()) { + proto = functionAST->second.first; } if (proto == nullptr) { @@ -70,16 +73,8 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) 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/CallExprAST.h b/src/ast/CallExprAST.h index 2c5531b..ffab9de 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -13,12 +13,14 @@ class CallExprAST : public ExprAST { public: - CallExprAST(CompileUnit *unit, const std::string &callee, ExprAST *args); + CallExprAST(CompileUnit *unit, const std::string &callee, ExprAST *args, + ExprAST *LHS = nullptr); virtual ~CallExprAST(); std::vector Codegen(llvm::IRBuilder<> *builder); std::string callee; ExprAST * args; + ExprAST * LHS; }; #endif /* COMPILER_AST_CALLEXPRAST_H_ */ diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 9a1518b..10c2cda 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -68,7 +68,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) if (token.type == tok_fun) { FunctionAST *funDef = FunctionAST::ParseFunction(unit, classAST); classAST->functions.insert(std::pair( - funDef->getDemangledName(), funDef)); + funDef->proto->name, funDef)); } else { VariableDefExprAST *memberDef = @@ -106,12 +106,8 @@ TypeAST *ClassAST::getRealType(TypeAST * type, } } -llvm::Type *ClassAST::Codegen(std::vector igenericTypes) +std::string ClassAST::getRealName(std::vector igenericTypes) { - if (igenericTypes.size() != genericTypes.size()) { - CompileError e("generic isn't equal"); - throw e; - } std::string name = className; if (igenericTypes.size() != 0) { name += "<"; @@ -120,7 +116,29 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) } name += igenericTypes[igenericTypes.size() - 1]->name + ">"; } + return name; +} + +std::string ClassAST::getRealNameForMangle(std::vector igenericTypes) +{ + std::stringstream ss; + ss << "C" << className.length() << className; + if (igenericTypes.size() != 0) { + for (unsigned int i = 0; i < igenericTypes.size() - 1; i++) { + ss << igenericTypes[i]->name.length() << igenericTypes[i]->name; + } + } + ss << "E"; + return ss.str(); +} +llvm::Type *ClassAST::Codegen(std::vector igenericTypes) +{ + if (igenericTypes.size() != genericTypes.size()) { + CompileError e("generic isn't equal"); + throw e; + } + std::string name = getRealName(igenericTypes); llvm::StructType *llvm_S = llvm::StructType::create(*unit->context, className); unit->types.insert(std::pair(name, llvm_S)); @@ -128,7 +146,6 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) std::map::iterator member_iter; for (member_iter = members.begin(); member_iter != members.end(); member_iter++) { - VariableDefExprAST *memberVariable = member_iter->second; TypeAST * mType = getRealType(memberVariable->variableType, igenericTypes); @@ -139,7 +156,7 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) std::map::iterator function_iter; for (function_iter = functions.begin(); function_iter != functions.end(); function_iter++) { - function_iter->second->Codegen(); + function_iter->second->Codegen(igenericTypes); } return llvm_S; diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 3959533..b5645f9 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -21,6 +21,9 @@ class ClassAST : public BaseAST virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); + std::string getRealName(std::vector igenericTypes); + std::string getRealNameForMangle(std::vector igenericTypes); + static ClassAST * ParseClass(CompileUnit *unit); std::map members; std::map functions; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index b227f25..67943ca 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -184,11 +184,11 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, ci++; continue; } - if (token.tokenValue != "<") { + if (token.tokenValue != "<" || !root) { //变量 unit->next_tok(); result = new VariableExprAST(unit, codeblock, idName); - } else if (token.tokenValue == "<") { + } else if (token.tokenValue == "<" && root) { //变量定义 result = VariableDefExprAST::ParseVar(unit, codeblock); } @@ -257,8 +257,11 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, } else if (token.tokenValue == ".") { if (VariableExprAST *v = dynamic_cast(RHS)) { LHS = new MemberExprAST(unit, LHS, v->idName, false); + } else if (CallExprAST *v = dynamic_cast(RHS)) { + v->LHS = LHS; + LHS = v; } else { - CompileError e("成员方法调用未实现"); + CompileError e("未知的操作"); throw e; } } else if (token.tokenValue == "->") { diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index 3f6c5bd..b0fe708 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -30,7 +30,8 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) } else if (flag.tokenValue == "C") { C = true; } else { - CompileError e("Unknown flag:" + flag.tokenValue,flag.file,flag.lineno); + CompileError e("Unknown flag:" + flag.tokenValue, flag.file, + flag.lineno); throw e; } } @@ -53,10 +54,4 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) return new ExternAST(unit, proto); } -std::string ExternAST::getDemangledName() { return proto->demangledName; } - -llvm::Function *ExternAST::Codegen() -{ - proto->Codegen(); - return 0; -} +llvm::Function *ExternAST::Codegen() { return proto->Codegen(); } diff --git a/src/ast/ExternAST.h b/src/ast/ExternAST.h index 6549d76..aa47819 100644 --- a/src/ast/ExternAST.h +++ b/src/ast/ExternAST.h @@ -19,7 +19,6 @@ 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 ccc3b2a..f23dc1d 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -31,8 +31,13 @@ FunctionAST::~FunctionAST() llvm::Function *FunctionAST::Codegen(std::vector igenericTypes) { - llvm::Function * func = proto->Codegen(); - llvm::BasicBlock *bb = body->Codegen(func); + llvm::Function *func = proto->Codegen(igenericTypes); + unit->globalFunctions.insert( + std::pair>( + func->getName(), + std::pair(proto, func))); + + llvm::BasicBlock *bb = body->Codegen(func); // func->getBasicBlockList().push_back(bb); return func; @@ -60,4 +65,3 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit, return result; } -std::string FunctionAST::getDemangledName() { return proto->demangledName; } diff --git a/src/ast/FunctionAST.h b/src/ast/FunctionAST.h index 17d1dad..8e0b901 100644 --- a/src/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -22,7 +22,6 @@ class FunctionAST : public BaseAST virtual ~FunctionAST(); llvm::Function * Codegen(std::vector igenericTypes = std::vector()); - std::string getDemangledName(); PrototypeAST *proto; ClassAST * parentClass; diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 53c4022..5f85b21 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -23,20 +23,6 @@ PrototypeAST::PrototypeAST( this->returnDirectly = false; this->returnTypes = returnTypes; this->parentClass = parentClass; - std::vector argStr; - for (std::pair pair : args) { - argStr.push_back(pair.first); - } - if (name != "main") { - if (parentClass == nullptr) { - this->demangledName = demangle(name, argStr); - } else { - this->demangledName = - demangle(name, argStr, parentClass->className); - } - } else { - this->demangledName = "main"; - } } PrototypeAST::~PrototypeAST() @@ -131,6 +117,22 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) { + std::vector argStr; + for (std::pair pair : args) { + argStr.push_back(pair.first); + } + std::string demangledName; + if (name != "main") { + if (parentClass == nullptr) { + demangledName = demangle(name, argStr); + } else { + demangledName = demangle( + name, argStr, parentClass->getRealNameForMangle(igenericTypes)); + } + } else { + demangledName = "main"; + } + std::vector llvmArgs; for (int i = 0; i < args.size(); i++) { llvmArgs.push_back(args[i].first->Codegen()); @@ -185,9 +187,6 @@ llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) return 0; } }*/ - // todo:参数处理 - // Set names for all arguments. - unsigned Idx = 0; for (llvm::Function::arg_iterator AI = F->arg_begin(); Idx != args.size(); ++AI, ++Idx) { diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h index f3f0963..e804492 100644 --- a/src/ast/PrototypeAST.h +++ b/src/ast/PrototypeAST.h @@ -24,8 +24,6 @@ class PrototypeAST : public BaseAST ClassAST *parentClass = nullptr); std::vector> args; - std::string demangledName; - std::vector returnTypes; std::string name; bool returnDirectly; //直接返回 diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index a50feec..147a004 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -107,3 +107,16 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) } return result; } + +std::string TypeAST::getMangleName() +{ + std::stringstream ss; + ss << "C" << baseClass.length() << baseClass; + if (genericTypes.size() != 0) { + for (unsigned int i = 0; i < genericTypes.size() - 1; i++) { + ss << genericTypes[i]->name.length() << genericTypes[i]->name; + } + } + ss << "E"; + return ss.str(); +} diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index ea0269a..37a2830 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -21,6 +21,7 @@ class TypeAST : public BaseAST void initName(); llvm::Type * Codegen(); + std::string getMangleName(); std::string name; std::string baseClass; std::vector innerType; diff --git a/src/utils.cpp b/src/utils.cpp index 4ef9fa5..1cf1ffb 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -21,7 +21,7 @@ std::string demangle(const std::string & fnName, std::stringstream ss; ss << "_alolang_"; if (className != "") { - ss << "C" << className.length() << className; + ss << className; } ss << fnName.length() << fnName; for (TypeAST *word : argTypes) { -- Gitee From 4c2084050510bc2c60237df269896c7c7e180e88 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 09:02:53 +0800 Subject: [PATCH 05/95] Implement sizeof --- src/Makefile.am | 2 +- src/Token.h | 3 ++- src/ast/ExprAST.cpp | 20 +++++++++++--------- src/ast/SizeofExprAST.cpp | 30 ++++++++++++++++++++++++++++++ src/ast/SizeofExprAST.h | 21 +++++++++++++++++++++ src/yacc_stuff/tokenizer.lpp | 1 + 6 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/ast/SizeofExprAST.cpp create mode 100644 src/ast/SizeofExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index 325ae09..fcfebdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ aloc_SOURCES = aloc.cpp CompileUnit.cpp preprocessor.cpp Token.cpp utils.cpp\ ast/CallExprAST.cpp ast/ClassAST.cpp ast/CodeBlockAST.cpp ast/DoubleExprAST.cpp ast/EmptyExprAST.cpp\ ast/ExprAST.cpp ast/ExternAST.cpp ast/FunctionAST.cpp ast/IntExprAST.cpp\ ast/IfExprAST.cpp ast/MemberExprAST.cpp ast/PrototypeAST.cpp\ - ast/ReturnExprAST.cpp ast/TypeAST.cpp ast/VariableDefExprAST.cpp ast/VariableExprAST.cpp\ + ast/ReturnExprAST.cpp ast/SizeofExprAST.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/Token.h b/src/Token.h index 7943dd7..2958942 100644 --- a/src/Token.h +++ b/src/Token.h @@ -33,7 +33,8 @@ enum TokenType { tok_key_if, tok_key_while, tok_key_switch, - tok_key_class + tok_key_class, + tok_key_sizeof }; class Token diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 67943ca..d419ea1 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -11,6 +11,7 @@ #include "IntExprAST.h" #include "MemberExprAST.h" #include "ReturnExprAST.h" +#include "SizeofExprAST.h" #include "UnaryExprAST.h" #include "VariableDefExprAST.h" #include "VariableExprAST.h" @@ -204,7 +205,16 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, break; } case tok_return: { - return ReturnExprAST::ParseReturnExprAST(unit, codeblock); + result = ReturnExprAST::ParseReturnExprAST(unit, codeblock); + break; + } + case tok_key_sizeof: { + unit->next_tok(); // sizeof + unit->next_tok(); //( + TypeAST *type = TypeAST::ParseType(unit); + unit->next_tok(); //) + result = new SizeofExprAST(unit, type); + break; } default: { CompileError e("不期待的token:" + token.dump(), token.file, @@ -212,14 +222,6 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, throw e; } } - /*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; } diff --git a/src/ast/SizeofExprAST.cpp b/src/ast/SizeofExprAST.cpp new file mode 100644 index 0000000..e243144 --- /dev/null +++ b/src/ast/SizeofExprAST.cpp @@ -0,0 +1,30 @@ +/* + * SizeofExprAST.cpp + * + * Created on: Mar 6, 2021 + * Author: zbc + */ + +#include "SizeofExprAST.h" +#include "IntExprAST.h" +#include "TypeAST.h" + +SizeofExprAST::SizeofExprAST(CompileUnit *unit, TypeAST *Stype) : ExprAST(unit) +{ + this->Stype = Stype; +} + +SizeofExprAST::~SizeofExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector SizeofExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + std::vector result; + this->type.push_back(new TypeAST(unit, "int")); + llvm::DataLayout *TD = new llvm::DataLayout(unit->module); + int size = TD->getTypeAllocSize(Stype->Codegen()); + result.push_back((new IntExprAST(unit, size))->Codegen(builder)[0]); + return result; +} diff --git a/src/ast/SizeofExprAST.h b/src/ast/SizeofExprAST.h new file mode 100644 index 0000000..db3272e --- /dev/null +++ b/src/ast/SizeofExprAST.h @@ -0,0 +1,21 @@ +/* + * SizeofExprAST.h + * + * Created on: Mar 6, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_SIZEOFEXPRAST_H_ +#define SRC_AST_SIZEOFEXPRAST_H_ + +#include "ExprAST.h" + +class SizeofExprAST : public ExprAST +{ + public: + SizeofExprAST(CompileUnit *unit, TypeAST *type); + virtual ~SizeofExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); + TypeAST * Stype; +}; +#endif /* SRC_AST_SIZEOFEXPRAST_H_ */ diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index f2f0d44..50fe167 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -27,6 +27,7 @@ foreach token = tok_key_foreach; return token goto token = tok_key_goto; return token; if token = tok_key_if; return token; while token = tok_key_while; return token; +sizeof token = tok_key_sizeof; return token; case|switch token = tok_key_switch; return token; -- Gitee From de100802f6c240d973f2311b855e23b740e556eb Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 09:14:13 +0800 Subject: [PATCH 06/95] Implement the getAlloca of ExprAST --- src/ast/ExprAST.cpp | 2 ++ src/ast/ExprAST.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index d419ea1..179bee9 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -115,6 +115,8 @@ ExprAST::~ExprAST() // TODO Auto-generated destructor stub } +llvm::Value *ExprAST::getAlloca() { return nullptr; } + ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root) { diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index f76f396..86eb4f7 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -11,10 +11,12 @@ class ExprAST : public BaseAST virtual ~ExprAST(); virtual std::vector Codegen(llvm::IRBuilder<> *builder) = 0; std::vector CodegenChain(llvm::IRBuilder<> *builder); + llvm::Value * getAlloca(); static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root = false); + std::vector type; ExprAST * subExpr; }; -- Gitee From 8730b956610dbc9ab58f329e44a2f03f4bfe31f7 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 09:35:21 +0800 Subject: [PATCH 07/95] Rebuild getAlloca --- src/ast/BinaryExprAST.cpp | 68 ++----------------------------------- src/ast/ExprAST.cpp | 2 +- src/ast/ExprAST.h | 2 +- src/ast/MemberExprAST.cpp | 68 +++++++++++++++++++++++++++++++++++++ src/ast/MemberExprAST.h | 1 + src/ast/UnaryExprAST.cpp | 4 +-- src/ast/VariableExprAST.cpp | 4 +-- src/ast/VariableExprAST.h | 2 +- 8 files changed, 79 insertions(+), 72 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 4f5dd4a..63af14c 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -101,10 +101,8 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } for (unsigned int i = 0; i < LHS.size(); i++) { - ExprAST * curAST = LHS[i]; - std::vector chain; - llvm::Value * pointer; - bool pointerFlag; + ExprAST * curAST = LHS[i]; + llvm::Value *pointer; if (UnaryExprAST *v = dynamic_cast(curAST)) { if (v->op != "*") { CompileError e("Operator " + v->op + @@ -114,67 +112,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) pointer = v->operand->Codegen(builder)[0]; } } else { - while (true) { - chain.push_back(curAST); - if (MemberExprAST *v = - dynamic_cast(curAST)) { - if (v->isPointer) { - pointerFlag = true; - chain.push_back(v->LHS); - break; - } - curAST = v->LHS; - } else if (VariableExprAST *v = - dynamic_cast(curAST)) { - pointerFlag = false; - break; - } else { - CompileError e("Unknown AST."); - throw e; - } - } - std::string curType, startType; - if (pointerFlag) { - ExprAST *start = chain[chain.size() - 1]; - pointer = start->Codegen(builder)[0]; - curType = start->type[0]->pointee->baseClass; - startType = start->type[0]->pointee->name; - } else { - VariableExprAST *start = dynamic_cast( - chain[chain.size() - 1]); - pointer = start->getAlloca(); - curType = start->type[0]->baseClass; - startType = start->type[0]->name; - } - std::vector idx; - for (int i = chain.size() - 2; i >= 0; i--) { - MemberExprAST *v = dynamic_cast(chain[i]); - std::string member = v->member; - ClassAST * baseClass = unit->classes[curType]; - auto memberAST = baseClass->members.find(member); - if (memberAST == baseClass->members.end()) { - CompileError e("Member" + member + " not found."); - throw e; - } - unsigned int index = std::distance( - std::begin(baseClass->members), memberAST); - idx.push_back(index); - curType = baseClass->members[member]->variableType->name; - } - std::vector idxl; - llvm::IntegerType * itype = - llvm::IntegerType::get(*unit->context, 32); - - idxl.push_back(llvm::ConstantInt::get(itype, 0, true)); - for (unsigned int pid : idx) { - idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); - } - if (idx.size() != 0) { - auto typeAST = unit->types.find(startType); - - pointer = - builder->CreateGEP(typeAST->second, pointer, idxl); - } + pointer = curAST->getAlloca(builder); } builder->CreateStore(RHSV[i], pointer); diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 179bee9..eaa4850 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -115,7 +115,7 @@ ExprAST::~ExprAST() // TODO Auto-generated destructor stub } -llvm::Value *ExprAST::getAlloca() { return nullptr; } +llvm::Value *ExprAST::getAlloca(llvm::IRBuilder<> *builder) { return nullptr; } ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root) diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index 86eb4f7..4509e41 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -11,7 +11,7 @@ class ExprAST : public BaseAST virtual ~ExprAST(); virtual std::vector Codegen(llvm::IRBuilder<> *builder) = 0; std::vector CodegenChain(llvm::IRBuilder<> *builder); - llvm::Value * getAlloca(); + virtual llvm::Value * getAlloca(llvm::IRBuilder<> *builder); static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root); static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index b460a15..fb07cab 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -9,6 +9,7 @@ #include "../CompileError.hpp" #include "ClassAST.h" #include "TypeAST.h" +#include "VariableExprAST.h" MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member, bool isPointer) @@ -54,3 +55,70 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) result.push_back(member); return result; } + +llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) +{ + ExprAST * curAST = this; + std::vector chain; + llvm::Value * pointer; + bool pointerFlag = false; + while (true) { + chain.push_back(curAST); + if (MemberExprAST *v = dynamic_cast(curAST)) { + if (v->isPointer) { + pointerFlag = true; + chain.push_back(v->LHS); + break; + } + curAST = v->LHS; + } else if (VariableExprAST *v = + dynamic_cast(curAST)) { + pointerFlag = false; + break; + } else { + CompileError e("Unknown AST."); + throw e; + } + } + std::string curType, startType; + if (pointerFlag) { + ExprAST *start = chain[chain.size() - 1]; + pointer = start->Codegen(builder)[0]; + curType = start->type[0]->pointee->baseClass; + startType = start->type[0]->pointee->name; + } else { + VariableExprAST *start = + dynamic_cast(chain[chain.size() - 1]); + pointer = start->getAlloca(builder); + curType = start->type[0]->baseClass; + startType = start->type[0]->name; + } + std::vector idx; + for (int i = chain.size() - 2; i >= 0; i--) { + MemberExprAST *v = dynamic_cast(chain[i]); + std::string member = v->member; + ClassAST * baseClass = unit->classes[curType]; + auto memberAST = baseClass->members.find(member); + if (memberAST == baseClass->members.end()) { + CompileError e("Member" + member + " not found."); + throw e; + } + unsigned int index = + std::distance(std::begin(baseClass->members), memberAST); + idx.push_back(index); + curType = baseClass->members[member]->variableType->name; + } + std::vector idxl; + llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); + + idxl.push_back(llvm::ConstantInt::get(itype, 0, true)); + for (unsigned int pid : idx) { + idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); + } + if (idx.size() != 0) { + auto typeAST = unit->types.find(startType); + + pointer = builder->CreateGEP(typeAST->second, pointer, idxl); + } + return pointer; +} diff --git a/src/ast/MemberExprAST.h b/src/ast/MemberExprAST.h index 410e5f4..b084ede 100644 --- a/src/ast/MemberExprAST.h +++ b/src/ast/MemberExprAST.h @@ -16,6 +16,7 @@ class MemberExprAST : public ExprAST MemberExprAST(CompileUnit *unit, ExprAST *LHS, std::string member, bool isPointer); virtual ~MemberExprAST(); + virtual llvm::Value * getAlloca(llvm::IRBuilder<> *builder); std::vector Codegen(llvm::IRBuilder<> *builder); ExprAST * LHS; std::string member; diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 1aa70f9..774d7d3 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -39,7 +39,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) std::vector result; if (op == "&") { if (VariableExprAST *v = dynamic_cast(operand)) { - result.push_back(v->getAlloca()); + result.push_back(v->getAlloca(builder)); this->type.push_back(new TypeAST(unit, operand->type[0])); } else if (MemberExprAST *v = dynamic_cast(operand)) { llvm::Value * pointer; @@ -59,7 +59,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) } VariableExprAST *start = dynamic_cast(chain[chain.size() - 1]); - pointer = start->getAlloca(); + pointer = start->getAlloca(builder); std::vector idx; std::string curType = start->type[0]->baseClass; for (int i = chain.size() - 2; i >= 0; i--) { diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index fbe3c5d..73726c8 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -27,7 +27,7 @@ VariableExprAST::~VariableExprAST() // TODO Auto-generated destructor stub } -llvm::Value *VariableExprAST::getAlloca() +llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) { if (alloca != nullptr) { return alloca; @@ -62,6 +62,6 @@ llvm::Value *VariableExprAST::getAlloca() std::vector VariableExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; - result.push_back(builder->CreateLoad(getAlloca())); + result.push_back(builder->CreateLoad(getAlloca(builder))); return result; } diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index 5b4de5e..7189545 100644 --- a/src/ast/VariableExprAST.h +++ b/src/ast/VariableExprAST.h @@ -15,7 +15,7 @@ class VariableExprAST : public ExprAST VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, const std::string &idName); virtual ~VariableExprAST(); - llvm::Value * getAlloca(); + virtual llvm::Value * getAlloca(llvm::IRBuilder<> *builder); std::vector Codegen(llvm::IRBuilder<> *builder); std::string idName; CodeBlockAST * codeblock; -- Gitee From 3a9301ef0519407a35384732e51e31f645ddf653 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 09:41:48 +0800 Subject: [PATCH 08/95] Implement getAlloca of UnaryExprAST --- src/ast/BinaryExprAST.cpp | 16 ++-------- src/ast/ExprAST.cpp | 6 +++- src/ast/UnaryExprAST.cpp | 66 +++++++-------------------------------- src/ast/UnaryExprAST.h | 2 ++ 4 files changed, 20 insertions(+), 70 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 63af14c..76e05c5 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -101,20 +101,8 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } for (unsigned int i = 0; i < LHS.size(); i++) { - ExprAST * curAST = LHS[i]; - 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]; - } - } else { - pointer = curAST->getAlloca(builder); - } - + ExprAST * curAST = LHS[i]; + llvm::Value *pointer = curAST->getAlloca(builder); builder->CreateStore(RHSV[i], pointer); } } else { diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index eaa4850..849c1bd 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -115,7 +115,11 @@ ExprAST::~ExprAST() // TODO Auto-generated destructor stub } -llvm::Value *ExprAST::getAlloca(llvm::IRBuilder<> *builder) { return nullptr; } +llvm::Value *ExprAST::getAlloca(llvm::IRBuilder<> *builder) +{ + CompileError e("No memory allocaed"); + throw e; +} ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root) diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 774d7d3..6fe7b99 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -33,66 +33,22 @@ UnaryExprAST::~UnaryExprAST() { // TODO Auto-generated destructor stub } +llvm::Value *UnaryExprAST::getAlloca(llvm::IRBuilder<> *builder) +{ + if (op != "*") { + CompileError e("Operator " + op + " can not be used as assignment"); + throw e; + } else { + return operand->Codegen(builder)[0]; + } +} std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; if (op == "&") { - if (VariableExprAST *v = dynamic_cast(operand)) { - result.push_back(v->getAlloca(builder)); - 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(builder); - 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; - } + llvm::Value *pointer = operand->getAlloca(builder); + result.push_back(pointer); } else { //值操作 std::vector Rs = operand->CodegenChain(builder); diff --git a/src/ast/UnaryExprAST.h b/src/ast/UnaryExprAST.h index 7db1f32..6e4ad57 100644 --- a/src/ast/UnaryExprAST.h +++ b/src/ast/UnaryExprAST.h @@ -16,6 +16,8 @@ class UnaryExprAST : public ExprAST UnaryExprAST(CompileUnit *unit, const std::string &op, ExprAST *operand, bool leftop); virtual ~UnaryExprAST(); + virtual llvm::Value *getAlloca(llvm::IRBuilder<> *builder); + std::vector Codegen(llvm::IRBuilder<> *builder); std::string op; ExprAST * operand; -- Gitee From f0f299a7b821a36de28de3e684cb1e036eecb589 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 10:32:52 +0800 Subject: [PATCH 09/95] Implment "this" key word --- src/ast/CallExprAST.cpp | 13 +++++++++++-- src/ast/ClassAST.h | 1 + src/ast/ExprAST.cpp | 6 +----- src/ast/FunctionAST.cpp | 15 +++++++++++++++ src/ast/MemberExprAST.cpp | 10 +++++++++- src/ast/UnaryExprAST.cpp | 4 ++++ 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 11ab213..f6f2a2f 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -9,6 +9,7 @@ #include "../CompileError.hpp" #include "ExternAST.h" #include "FunctionAST.h" +#include "TypeAST.h" #include @@ -33,9 +34,17 @@ CallExprAST::~CallExprAST() std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { std::vector result; + std::vector argStr; std::vector argsV = args->CodegenChain(builder); - - std::vector argStr; + if (LHS != nullptr) { + llvm::Value *thisV = LHS->getAlloca(builder); + if (thisV == nullptr) { + CompileError e("No memory allocaed"); + throw e; + } + argsV.insert(argsV.begin(), thisV); + argStr.push_back(new TypeAST(unit, LHS->type[0])); + } for (TypeAST *ast : args->type) { argStr.push_back(ast); } diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index b5645f9..12157b2 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -22,6 +22,7 @@ class ClassAST : public BaseAST llvm::Type *Codegen(std::vector genericTypes); TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); std::string getRealName(std::vector igenericTypes); + std::string getRealNameForMangle(std::vector igenericTypes); static ClassAST * ParseClass(CompileUnit *unit); diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 849c1bd..eaa4850 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -115,11 +115,7 @@ ExprAST::~ExprAST() // TODO Auto-generated destructor stub } -llvm::Value *ExprAST::getAlloca(llvm::IRBuilder<> *builder) -{ - CompileError e("No memory allocaed"); - throw e; -} +llvm::Value *ExprAST::getAlloca(llvm::IRBuilder<> *builder) { return nullptr; } ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root) diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index f23dc1d..aaa29e0 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -7,8 +7,10 @@ #include "FunctionAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" #include "CodeBlockAST.h" #include "PrototypeAST.h" +#include "TypeAST.h" #include "VariableDefExprAST.h" #include "VariableExprAST.h" #include @@ -48,9 +50,22 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit, { PrototypeAST *protoType = PrototypeAST::ParsePrototype(unit, true, parentClass); + if (parentClass != nullptr) { + std::vector genericTypes; + for (std::string gType : parentClass->genericTypes) { + genericTypes.push_back(new TypeAST(unit, gType)); + } + protoType->args.insert( + protoType->args.begin(), + std::pair( + new TypeAST(unit, new TypeAST(unit, parentClass->className, + genericTypes)), + "this")); + } std::cout << std::left << std::setw(35) << "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]; args.push_back(new VariableDefExprAST(unit, nullptr, arg.second, diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index fb07cab..ad2a2ef 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -27,6 +27,7 @@ MemberExprAST::~MemberExprAST() std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) { + type.clear(); if (isPointer) { CompileError e("未实现."); throw e; @@ -58,6 +59,7 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) { + type.clear(); ExprAST * curAST = this; std::vector chain; llvm::Value * pointer; @@ -89,7 +91,11 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) } else { VariableExprAST *start = dynamic_cast(chain[chain.size() - 1]); - pointer = start->getAlloca(builder); + pointer = start->getAlloca(builder); + if (pointer == nullptr) { + CompileError e("No memory allocaed"); + throw e; + } curType = start->type[0]->baseClass; startType = start->type[0]->name; } @@ -120,5 +126,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) pointer = builder->CreateGEP(typeAST->second, pointer, idxl); } + type.push_back(new TypeAST(unit, curType)); + return pointer; } diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 6fe7b99..9c51f93 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -48,6 +48,10 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) std::vector result; if (op == "&") { llvm::Value *pointer = operand->getAlloca(builder); + if (pointer == nullptr) { + CompileError e("No memory allocaed"); + throw e; + } result.push_back(pointer); } else { //值操作 -- Gitee From 87890a0e887b66974c2c4bcb38dd4a9af5ed20f0 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 6 Mar 2021 15:05:55 +0800 Subject: [PATCH 10/95] testcode --- test/classanytype.alo | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 92f0abc..822a522 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -1,15 +1,18 @@ extern func testPrintInt(int i); -class node { - node* pred; - node* succ; - A data; +class node { + node* pred; + node* succ; + int data; + func getdata() -> int { + return (*this).data; + } } func main() { - node test1; - node test2; - node test3; + node test1; + node test2; + node test3; test1.pred = &test2; test1.succ = &test3; @@ -20,11 +23,11 @@ func main() { int* testint1 = &(test1.data); - testPrintInt(test1.data); - testPrintInt(test2.data); - testPrintInt(test3.data); - testPrintInt((*(test1.succ)).data); - testPrintInt((*(test1.pred)).data); + testPrintInt(test1.getdata()); + testPrintInt(test2.getdata()); + testPrintInt(test3.getdata()); + testPrintInt((*(test1.succ)).getdata()); + testPrintInt((*(test1.pred)).getdata()); testPrintInt(*testint1); if (true) -- Gitee From 3f2cd6649b8c9d41da4c976819a42c08d2d8cd71 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sat, 6 Mar 2021 15:14:53 +0800 Subject: [PATCH 11/95] testcode --- test/classanytype.alo | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/test/classanytype.alo b/test/classanytype.alo index 822a522..c384dde 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -1,18 +1,15 @@ extern func testPrintInt(int i); -class node { - node* pred; - node* succ; - int data; - func getdata() -> int { - return (*this).data; - } +class node { + node* pred; + node* succ; + A data; } func main() { - node test1; - node test2; - node test3; + node test1; + node test2; + node test3; test1.pred = &test2; test1.succ = &test3; @@ -23,13 +20,17 @@ func main() { int* testint1 = &(test1.data); - testPrintInt(test1.getdata()); - testPrintInt(test2.getdata()); - testPrintInt(test3.getdata()); - testPrintInt((*(test1.succ)).getdata()); - testPrintInt((*(test1.pred)).getdata()); + testPrintInt(test1.data); + testPrintInt(test2.data); + testPrintInt(test3.data); + testPrintInt((*(test1.succ)).data); + testPrintInt((*(test1.pred)).data); testPrintInt(*testint1); + node> test4; + test4.data = test1; + testPrintInt(test4.data.data); + if (true) testPrintInt(114514); -- Gitee From 8a0d980f6b875cd9a6f4ed782308a64f7300cb1e Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 15:21:18 +0800 Subject: [PATCH 12/95] Add type in UnaryExprAST --- src/ast/CallExprAST.cpp | 4 ++++ src/ast/UnaryExprAST.cpp | 9 ++++++--- test/classanytype.alo | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index f6f2a2f..b3944af 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -43,6 +43,10 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } argsV.insert(argsV.begin(), thisV); + if (LHS->type.size() != 1) { + CompileError e("Multi/void value detected"); + throw e; + } argStr.push_back(new TypeAST(unit, LHS->type[0])); } for (TypeAST *ast : args->type) { diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 9c51f93..9ff6f48 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -35,11 +35,14 @@ UnaryExprAST::~UnaryExprAST() } llvm::Value *UnaryExprAST::getAlloca(llvm::IRBuilder<> *builder) { - if (op != "*") { + if (op == "*") { + type.clear(); + llvm::Value *ret = operand->Codegen(builder)[0]; + type.push_back(operand->type[0]->pointee); + return ret; + } else { CompileError e("Operator " + op + " can not be used as assignment"); throw e; - } else { - return operand->Codegen(builder)[0]; } } diff --git a/test/classanytype.alo b/test/classanytype.alo index 822a522..0328d0e 100644 --- a/test/classanytype.alo +++ b/test/classanytype.alo @@ -26,8 +26,8 @@ func main() { testPrintInt(test1.getdata()); testPrintInt(test2.getdata()); testPrintInt(test3.getdata()); - testPrintInt((*(test1.succ)).getdata()); - testPrintInt((*(test1.pred)).getdata()); + //testPrintInt((*(test1.succ)).getdata()); + //testPrintInt((*(test1.pred)).getdata()); testPrintInt(*testint1); if (true) -- Gitee From ee853061c10c5930e93b51227a7e6602946d731d Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 21:43:01 +0800 Subject: [PATCH 13/95] Fix lots of bug and rebuild mangle to support generic --- src/ast/CallExprAST.cpp | 8 ++++++-- src/ast/ClassAST.cpp | 4 ++-- src/ast/ExprAST.cpp | 13 ++++++++++--- src/ast/ExprAST.h | 2 +- src/ast/FunctionAST.cpp | 1 + src/ast/FunctionAST.h | 7 ++++--- src/ast/MemberExprAST.cpp | 20 +++++++++++--------- src/ast/PrototypeAST.cpp | 16 ++++++---------- src/ast/TypeAST.cpp | 18 ++++++++++++------ src/ast/TypeAST.h | 7 ++++--- src/ast/VariableExprAST.cpp | 5 ++--- src/lib/testPuts.c | 14 +++++++------- src/utils.cpp | 3 ++- 13 files changed, 68 insertions(+), 50 deletions(-) diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index b3944af..36eba27 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -7,6 +7,7 @@ #include "CallExprAST.h" #include "../CompileError.hpp" +#include "ClassAST.h" #include "ExternAST.h" #include "FunctionAST.h" #include "TypeAST.h" @@ -57,8 +58,11 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) if (LHS == nullptr) { dname = demangle(callee, argStr); } else { - LHSv = LHS->Codegen(builder)[0]; - dname = demangle(callee, argStr, LHS->type[0]->getMangleName()); + LHSv = LHS->Codegen(builder)[0]; + ClassAST * baseClass = unit->classes[LHS->type[0]->baseClass]; + std::string typeMangledName = + baseClass->getRealNameForMangle(LHS->type[0]->genericTypes); + dname = demangle(callee, argStr, typeMangledName); } if (callee == "main") { dname = "main"; diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 10c2cda..2d06f60 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -125,7 +125,8 @@ std::string ClassAST::getRealNameForMangle(std::vector igenericTypes) ss << "C" << className.length() << className; if (igenericTypes.size() != 0) { for (unsigned int i = 0; i < igenericTypes.size() - 1; i++) { - ss << igenericTypes[i]->name.length() << igenericTypes[i]->name; + std::string typeMangleName = igenericTypes[i]->getMangleName(); + ss << typeMangleName.length() << typeMangleName; } } ss << "E"; @@ -152,7 +153,6 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) sMembers.push_back(mType->Codegen()); } llvm_S->setBody(sMembers); - std::map::iterator function_iter; for (function_iter = functions.begin(); function_iter != functions.end(); function_iter++) { diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index eaa4850..4b5c815 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -227,10 +227,18 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, return result; } +void ExprAST::appendSubExpr(ExprAST *expr) +{ + ExprAST *curAST = this; + while (curAST->subExpr == nullptr) { + curAST = curAST->subExpr; + } + curAST->subExpr = expr; +} + static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, int ExprPrec, ExprAST *LHS) { - ExprAST *cExpr = LHS; while (1) { Token token = *unit->icurTok; int TokPrec; @@ -256,8 +264,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, } } if (token.tokenValue == ",") { - cExpr->subExpr = RHS; - cExpr = RHS; + LHS->appendSubExpr(RHS); } else if (token.tokenValue == ".") { if (VariableExprAST *v = dynamic_cast(RHS)) { LHS = new MemberExprAST(unit, LHS, v->idName, false); diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h index 4509e41..f010885 100644 --- a/src/ast/ExprAST.h +++ b/src/ast/ExprAST.h @@ -16,7 +16,7 @@ class ExprAST : public BaseAST bool root); static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, bool root = false); - + void appendSubExpr(ExprAST *expr); std::vector type; ExprAST * subExpr; }; diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index aaa29e0..bb2d931 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -33,6 +33,7 @@ FunctionAST::~FunctionAST() llvm::Function *FunctionAST::Codegen(std::vector igenericTypes) { + this->igenericTypes = igenericTypes; llvm::Function *func = proto->Codegen(igenericTypes); unit->globalFunctions.insert( std::pair>( diff --git a/src/ast/FunctionAST.h b/src/ast/FunctionAST.h index 8e0b901..db7eb82 100644 --- a/src/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -25,9 +25,10 @@ class FunctionAST : public BaseAST PrototypeAST *proto; ClassAST * parentClass; - CodeBlockAST * body; - static FunctionAST *ParseFunction(CompileUnit *unit, - ClassAST * parentClass = nullptr); + CodeBlockAST * body; + std::vector igenericTypes; + static FunctionAST * ParseFunction(CompileUnit *unit, + ClassAST * parentClass = nullptr); }; #endif /* COMPILER_AST_FUNCTIONAST_H_ */ diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index ad2a2ef..9155c27 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -28,10 +28,7 @@ MemberExprAST::~MemberExprAST() std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) { type.clear(); - if (isPointer) { - CompileError e("未实现."); - throw e; - } + std::vector result; std::vector bases = LHS->Codegen(builder); if (bases.size() != 1) { @@ -39,10 +36,15 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } - llvm::Value *base = bases[0]; - - ClassAST *baseClass = unit->classes[LHS->type[0]->baseClass]; - auto memberAST = baseClass->members.find(member); + llvm::Value * base = bases[0]; + ClassAST * baseClass = unit->classes[LHS->type[0]->baseClass]; + std::vector genericTypes = LHS->type[0]->genericTypes; + if (isPointer) { + baseClass = unit->classes[LHS->type[0]->pointee->baseClass]; + base = builder->CreateLoad(base); + genericTypes = LHS->type[0]->pointee->genericTypes; + } + auto memberAST = baseClass->members.find(member); if (memberAST == baseClass->members.end()) { CompileError e("Member " + member + " not found."); throw e; @@ -51,7 +53,7 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) std::distance(std::begin(baseClass->members), memberAST); type.push_back(baseClass->getRealType( - baseClass->members[member]->variableType, LHS->type[0]->genericTypes)); + baseClass->members[member]->variableType, genericTypes)); llvm::Value *member = builder->CreateExtractValue(base, {index}); result.push_back(member); return result; diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 5f85b21..dffb6ba 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -119,7 +119,12 @@ llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) { std::vector argStr; for (std::pair pair : args) { - argStr.push_back(pair.first); + if (parentClass == nullptr) { + argStr.push_back(pair.first); + } else { + argStr.push_back( + parentClass->getRealType(pair.first, igenericTypes)); + } } std::string demangledName; if (name != "main") { @@ -187,14 +192,5 @@ llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) return 0; } }*/ - unsigned Idx = 0; - for (llvm::Function::arg_iterator AI = F->arg_begin(); Idx != args.size(); - ++AI, ++Idx) { - AI->setName(args[Idx].second); - - // Add arguments to variable symbol table. - // NamedValues[args[Idx]] = AI; - } - return F; } diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 147a004..988c100 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -111,12 +111,18 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) std::string TypeAST::getMangleName() { std::stringstream ss; - ss << "C" << baseClass.length() << baseClass; - if (genericTypes.size() != 0) { - for (unsigned int i = 0; i < genericTypes.size() - 1; i++) { - ss << genericTypes[i]->name.length() << genericTypes[i]->name; + if (pointee == nullptr) { + ss << baseClass.length() << baseClass; + if (genericTypes.size() != 0) { + for (unsigned int i = 0; i < genericTypes.size(); i++) { + ss << genericTypes[i]->name.length() << genericTypes[i]->name; + } } + ss << "e"; + return ss.str(); + } else { + ss << "P"; + ss << pointee->getMangleName(); + return ss.str(); } - ss << "E"; - return ss.str(); } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 37a2830..ee7f5e6 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -20,13 +20,14 @@ class TypeAST : public BaseAST static TypeAST *ParseType(CompileUnit *unit); void initName(); - llvm::Type * Codegen(); - std::string getMangleName(); - std::string name; + llvm::Type *Codegen(); + std::string getMangleName(); + std::string baseClass; std::vector innerType; std::vector genericTypes; TypeAST * pointee; //指向的类型 + std::string name; }; #endif /* SRC_AST_TYPEAST_H_ */ diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 73726c8..1c98edb 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -29,9 +29,11 @@ VariableExprAST::~VariableExprAST() llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) { + if (alloca != nullptr) { return alloca; } + type.clear(); //找局部变量 CodeBlockAST *curCodeBlock = codeblock; while (curCodeBlock != nullptr) { @@ -41,9 +43,6 @@ llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) } else { alloca = varAST->second.second; type.push_back(varAST->second.first); - if (varAST->second.first->name == "") { - std::cout << "fuck" << std::endl; - } return alloca; } } diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 2fab4ee..630226b 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -2,9 +2,9 @@ extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } -extern void _alolang_12testPrintInt3int(long long a) { printf("%lld\n", a); } -extern void _alolang_15testPrintDouble6double(double a) { printf("%lf\n", a); } -extern void _alolang_13testPrintBool4bool(int a) +extern void _alolang_12testPrintInt3inte(long long a) { printf("%lld\n", a); } +extern void _alolang_15testPrintDouble6doublee(double a) { printf("%lf\n", a); } +extern void _alolang_13testPrintBool4boole(int a) { if (a) { printf("true\n"); @@ -13,16 +13,16 @@ extern void _alolang_13testPrintBool4bool(int a) } } -extern int _alolang_10testGetInt() +extern int _alolang_10testGetInte() { int a; scanf("%d", &a); return a; } -extern double _alolang_13testGetDouble() +extern double _alolang_13testGetDoublee() { double a; scanf("%lf", &a); - return a; -} \ No newline at end of file + return a; +} diff --git a/src/utils.cpp b/src/utils.cpp index 1cf1ffb..2067389 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -25,7 +25,8 @@ std::string demangle(const std::string & fnName, } ss << fnName.length() << fnName; for (TypeAST *word : argTypes) { - ss << word->name.length() << word->name; //得到类型 + std::string mangleName = word->getMangleName(); + ss << mangleName; //得到类型 } return ss.str(); } -- Gitee From 0f2dda2a9dc8be941a785417d34bd371d1405be5 Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 22:18:05 +0800 Subject: [PATCH 14/95] Implement generic method --- src/ast/ClassAST.cpp | 24 ++++++++++++++++++++++++ src/ast/ClassAST.h | 2 ++ src/ast/PrototypeAST.cpp | 9 ++++++--- src/ast/TypeAST.cpp | 21 ++++++++++++++------- src/ast/TypeAST.h | 4 +++- src/ast/VariableDefExprAST.cpp | 7 ++++++- 6 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 2d06f60..17b241c 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -106,6 +106,29 @@ TypeAST *ClassAST::getRealType(TypeAST * type, } } +TypeAST *ClassAST::getRealType(TypeAST *type) +{ + std::vector igenericTypes = this->igenericTypes; + if (type->pointee != nullptr) { + type->pointee = getRealType(type->pointee, igenericTypes); + } + for (unsigned int i = 0; i < type->genericTypes.size(); i++) { + type->genericTypes[i] = + getRealType(type->genericTypes[i], igenericTypes); + } + auto it = find(genericTypes.begin(), genericTypes.end(), type->name); + + type->initName(); + + if (it != genericTypes.end()) { + //泛型 + int index = it - genericTypes.begin(); + return igenericTypes[index]; + } else { + return type; + } +} + std::string ClassAST::getRealName(std::vector igenericTypes) { std::string name = className; @@ -139,6 +162,7 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) CompileError e("generic isn't equal"); throw e; } + this->igenericTypes = igenericTypes; std::string name = getRealName(igenericTypes); llvm::StructType *llvm_S = llvm::StructType::create(*unit->context, className); diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 12157b2..8a4e3d6 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -21,6 +21,7 @@ class ClassAST : public BaseAST virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); + TypeAST *getRealType(TypeAST *type); std::string getRealName(std::vector igenericTypes); std::string getRealNameForMangle(std::vector igenericTypes); @@ -30,6 +31,7 @@ class ClassAST : public BaseAST std::map functions; std::vector genericTypes; std::string className; + std::vector igenericTypes; // todo:注意多线程的情形 }; #endif /* SRC_AST_CLASSAST_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index dffb6ba..7816512 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -62,8 +62,9 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, token = *unit->icurTok; std::string name = token.tokenValue; std::pair pair; - pair.first = type; - pair.second = name; + type->inClass = parentClass; + pair.first = type; + pair.second = name; args.push_back(pair); } if (token.type != tok_syntax || token.tokenValue != ")") { @@ -95,7 +96,9 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, break; } } - returnTypes.push_back(TypeAST::ParseType(unit)); + TypeAST *returnType = TypeAST::ParseType(unit); + returnType->inClass = parentClass; + returnTypes.push_back(returnType); } } else { if (token.tokenValue == "{") { diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 988c100..61e874e 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -11,12 +11,13 @@ #include "CompileUnit.h" TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, - std::vector genericTypes) + std::vector genericTypes, ClassAST *inClass) : BaseAST(unit) { this->baseClass = baseClass; this->genericTypes = genericTypes; this->pointee = nullptr; + this->inClass = inClass; initName(); //生成name } @@ -37,7 +38,8 @@ TypeAST::TypeAST(CompileUnit *unit, TypeAST *pointee) : BaseAST(unit) { this->pointee = pointee; //生成name - this->name = pointee->name + "*"; + this->name = pointee->name + "*"; + this->inClass = nullptr; } TypeAST::~TypeAST() @@ -46,17 +48,22 @@ TypeAST::~TypeAST() } llvm::Type *TypeAST::Codegen() { + TypeAST *realType = this; + if (inClass != nullptr) { + realType = inClass->getRealType(realType); + } if (pointee == nullptr) { //非指针类型 - auto typeAST = unit->types.find(name); + auto typeAST = unit->types.find(realType->name); if (typeAST == unit->types.end()) { //没有找到实例化过的泛型 - auto classAST = unit->classes.find(baseClass); + auto classAST = unit->classes.find(realType->baseClass); if (classAST == unit->classes.end()) { - CompileError e("can't find class:" + baseClass); + CompileError e("can't find class:" + realType->baseClass); throw e; } else { - llvm::Type *classType = classAST->second->Codegen(genericTypes); + llvm::Type *classType = + classAST->second->Codegen(realType->genericTypes); return classType; //构建泛型 } @@ -64,7 +71,7 @@ llvm::Type *TypeAST::Codegen() return typeAST->second; } } else { - return llvm::PointerType::get(pointee->Codegen(), 0); + return llvm::PointerType::get(realType->pointee->Codegen(), 0); } } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index ee7f5e6..4328947 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -14,7 +14,8 @@ class TypeAST : public BaseAST { public: TypeAST(CompileUnit *unit, std::string baseClass, - std::vector genericTypes = std::vector()); + std::vector genericTypes = std::vector(), + ClassAST * inClass = nullptr); TypeAST(CompileUnit *unit, TypeAST *pointee); virtual ~TypeAST(); static TypeAST *ParseType(CompileUnit *unit); @@ -28,6 +29,7 @@ class TypeAST : public BaseAST std::vector genericTypes; TypeAST * pointee; //指向的类型 std::string name; + ClassAST * inClass; }; #endif /* SRC_AST_TYPEAST_H_ */ diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index f7c1c29..d07857d 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -9,6 +9,7 @@ #include "../CompileError.hpp" #include "CodeBlockAST.h" +#include "FunctionAST.h" #include "IntExprAST.h" #include "TypeAST.h" #include @@ -100,6 +101,9 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, CodeBlockAST *codeblock) { TypeAST *typeAST = TypeAST::ParseType(unit); + if (codeblock != nullptr) { + typeAST->inClass = codeblock->baseFunction->parentClass; + } Token nexToken = *(unit->icurTok); std::string idName = nexToken.tokenValue; @@ -115,7 +119,8 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, unit->next_tok(); initValue = ExprAST::ParseExpression(unit, codeblock, false); } else { - CompileError e("Unknown token:" + nexToken.dump(),nexToken.file,nexToken.lineno); + CompileError e("Unknown token:" + nexToken.dump(), nexToken.file, + nexToken.lineno); throw e; } } -- Gitee From 6ccaa17d8e8e31c891e613428af08ed0372cf20b Mon Sep 17 00:00:00 2001 From: uebian Date: Sat, 6 Mar 2021 22:28:55 +0800 Subject: [PATCH 15/95] Fix bug related to generic type --- src/ast/BinaryExprAST.cpp | 10 +++--- src/ast/ClassAST.cpp | 12 +++---- src/ast/MemberExprAST.cpp | 6 ++-- src/ast/TypeAST.cpp | 59 ++++++++++++++++++++-------------- src/ast/TypeAST.h | 5 ++- src/ast/VariableDefExprAST.cpp | 8 ++--- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 76e05c5..289f004 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -31,7 +31,7 @@ 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 (LHS->type[0]->getName() == "int" && RHS->type[0]->getName() == "int") { if (binOP == "+") { return builder->CreateAdd(L, R); } else if (binOP == "-") { @@ -58,8 +58,8 @@ BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, } else if (binOP == "<=") { return builder->CreateICmpSLE(L, R); } - } else if (LHS->type[0]->name == "double" && - RHS->type[0]->name == "double") { + } else if (LHS->type[0]->getName() == "double" && + RHS->type[0]->getName() == "double") { if (binOP == "+") { return builder->CreateFAdd(L, R); } else if (binOP == "-") { @@ -112,8 +112,8 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Bin Expr length != 1"); throw e; } - std::string LHStype = LHS->type[0]->name; - std::string RHStype = RHS->type[0]->name; + std::string LHStype = LHS->type[0]->getName(); + std::string RHStype = RHS->type[0]->getName(); auto operate = unit->binOperators.find({LHStype, RHStype, binOP}); if (operate == unit->binOperators.end()) { CompileError e("Unknown operator " + binOP + "with type " + diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 17b241c..bc12b77 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -93,9 +93,7 @@ TypeAST *ClassAST::getRealType(TypeAST * type, type->genericTypes[i] = getRealType(type->genericTypes[i], igenericTypes); } - auto it = find(genericTypes.begin(), genericTypes.end(), type->name); - - type->initName(); + auto it = find(genericTypes.begin(), genericTypes.end(), type->baseClass); if (it != genericTypes.end()) { //泛型 @@ -116,9 +114,7 @@ TypeAST *ClassAST::getRealType(TypeAST *type) type->genericTypes[i] = getRealType(type->genericTypes[i], igenericTypes); } - auto it = find(genericTypes.begin(), genericTypes.end(), type->name); - - type->initName(); + auto it = find(genericTypes.begin(), genericTypes.end(), type->baseClass); if (it != genericTypes.end()) { //泛型 @@ -135,9 +131,9 @@ std::string ClassAST::getRealName(std::vector igenericTypes) if (igenericTypes.size() != 0) { name += "<"; for (unsigned int i = 0; i < igenericTypes.size() - 1; i++) { - name += igenericTypes[i]->name + ","; + name += igenericTypes[i]->getName() + ","; } - name += igenericTypes[igenericTypes.size() - 1]->name + ">"; + name += igenericTypes[igenericTypes.size() - 1]->getName() + ">"; } return name; } diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index 9155c27..d10a644 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -89,7 +89,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) ExprAST *start = chain[chain.size() - 1]; pointer = start->Codegen(builder)[0]; curType = start->type[0]->pointee->baseClass; - startType = start->type[0]->pointee->name; + startType = start->type[0]->pointee->getName(); } else { VariableExprAST *start = dynamic_cast(chain[chain.size() - 1]); @@ -99,7 +99,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) throw e; } curType = start->type[0]->baseClass; - startType = start->type[0]->name; + startType = start->type[0]->getName(); } std::vector idx; for (int i = chain.size() - 2; i >= 0; i--) { @@ -114,7 +114,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) unsigned int index = std::distance(std::begin(baseClass->members), memberAST); idx.push_back(index); - curType = baseClass->members[member]->variableType->name; + curType = baseClass->members[member]->variableType->getName(); } std::vector idxl; llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 61e874e..71ab241 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -18,27 +18,11 @@ TypeAST::TypeAST(CompileUnit *unit, std::string baseClass, this->genericTypes = genericTypes; this->pointee = nullptr; this->inClass = inClass; - initName(); - //生成name -} - -void TypeAST::initName() -{ - this->name = baseClass; - if (genericTypes.size() != 0) { - this->name += "<"; - for (unsigned int i = 0; i < genericTypes.size() - 1; i++) { - this->name += genericTypes[i]->name + ","; - } - this->name += genericTypes[genericTypes.size() - 1]->name + ">"; - } } TypeAST::TypeAST(CompileUnit *unit, TypeAST *pointee) : BaseAST(unit) { this->pointee = pointee; - //生成name - this->name = pointee->name + "*"; this->inClass = nullptr; } @@ -54,7 +38,7 @@ llvm::Type *TypeAST::Codegen() } if (pointee == nullptr) { //非指针类型 - auto typeAST = unit->types.find(realType->name); + auto typeAST = unit->types.find(realType->getName()); if (typeAST == unit->types.end()) { //没有找到实例化过的泛型 auto classAST = unit->classes.find(realType->baseClass); @@ -75,7 +59,7 @@ llvm::Type *TypeAST::Codegen() } } -TypeAST *TypeAST::ParseType(CompileUnit *unit) +TypeAST *TypeAST::ParseType(CompileUnit *unit, ClassAST *inClass) { Token token = *unit->icurTok; if (token.type != tok_identifier) { @@ -107,7 +91,7 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) } token = unit->next_tok(); } - TypeAST *result = new TypeAST(unit, baseClass, genericTypes); + TypeAST *result = new TypeAST(unit, baseClass, genericTypes, inClass); while (token.type == tok_syntax && token.tokenValue == "*") { result = new TypeAST(unit, result); token = unit->next_tok(); @@ -115,21 +99,46 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit) return result; } +std::string TypeAST::getName() +{ + TypeAST *realType = this; + if (inClass != nullptr) { + realType = inClass->getRealType(realType); + } + + std::string name = realType->baseClass; + if (realType->genericTypes.size() != 0) { + name += "<"; + for (unsigned int i = 0; i < realType->genericTypes.size() - 1; i++) { + name += realType->genericTypes[i]->getName() + ","; + } + name += realType->genericTypes[realType->genericTypes.size() - 1] + ->getName() + + ">"; + } + return name; +} + std::string TypeAST::getMangleName() { + TypeAST *realType = this; + if (inClass != nullptr) { + realType = inClass->getRealType(realType); + } std::stringstream ss; - if (pointee == nullptr) { - ss << baseClass.length() << baseClass; - if (genericTypes.size() != 0) { - for (unsigned int i = 0; i < genericTypes.size(); i++) { - ss << genericTypes[i]->name.length() << genericTypes[i]->name; + if (realType->pointee == nullptr) { + ss << realType->baseClass.length() << realType->baseClass; + if (realType->genericTypes.size() != 0) { + for (unsigned int i = 0; i < realType->genericTypes.size(); i++) { + std::string name = realType->genericTypes[i]->getName(); + ss << name.length() << name; } } ss << "e"; return ss.str(); } else { ss << "P"; - ss << pointee->getMangleName(); + ss << realType->pointee->getMangleName(); return ss.str(); } } diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h index 4328947..3185c53 100644 --- a/src/ast/TypeAST.h +++ b/src/ast/TypeAST.h @@ -18,17 +18,16 @@ class TypeAST : public BaseAST ClassAST * inClass = nullptr); TypeAST(CompileUnit *unit, TypeAST *pointee); virtual ~TypeAST(); - static TypeAST *ParseType(CompileUnit *unit); - void initName(); + static TypeAST *ParseType(CompileUnit *unit, ClassAST *inClass = nullptr); llvm::Type *Codegen(); std::string getMangleName(); + std::string getName(); std::string baseClass; std::vector innerType; std::vector genericTypes; TypeAST * pointee; //指向的类型 - std::string name; ClassAST * inClass; }; diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index d07857d..7dc37bc 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -52,16 +52,16 @@ VariableDefExprAST::Codegen(llvm::IRBuilder<> *builder) *unit->module, variableType->Codegen(), false, llvm::GlobalValue::ExternalLinkage, nullptr, idName); // todo:初始填0 - if (variableType->name == "int") { + if (variableType->getName() == "int") { llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 64); llvm::ConstantInt *res = llvm::ConstantInt::get(itype, 0, true); gVar->setInitializer(res); - } else if (variableType->name == "double") { + } else if (variableType->getName() == "double") { llvm::Type * ftype = llvm::Type::getDoubleTy(*unit->context); llvm::Constant *res = llvm::ConstantFP::get(ftype, 0); gVar->setInitializer(res); - } else if (variableType->name == "bool") { + } else if (variableType->getName() == "bool") { llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 1); llvm::ConstantInt *res = llvm::ConstantInt::get(itype, 0, true); @@ -127,6 +127,6 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, std::cout << std::left << std::setw(35) << "Variable definition found:" << idName - << " with type:" << typeAST->name << std::endl; + << " with type:" << typeAST->baseClass << std::endl; return new VariableDefExprAST(unit, codeblock, idName, typeAST, initValue); } -- Gitee From b9dcef73a13100158a238a4baa4bebb7083e717c Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 09:26:58 +0800 Subject: [PATCH 16/95] Fix "%import" --- src/Makefile.am | 2 +- src/preprocessor.cpp | 40 +++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index fcfebdd..40e15c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,4 +17,4 @@ includeLLVM := $(shell llvm-config --includedir) aloc_CPPFLAGS = $(cxxflagsLLVM) -I$(includeLLVM) -I$(srcdir) -fexceptions aloc_LDFLAGS = $(ldflagsLLVM) #$(libLLVM) -lboost_program_options -aloc_LDADD = -lLLVM-11 -lboost_program_options \ No newline at end of file +aloc_LDADD = -lLLVM-11 -lboost_program_options -lboost_filesystem -lboost_system \ No newline at end of file diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 2e5be87..084c13b 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -1,7 +1,9 @@ #include "preprocessor.h" +#include "boost/filesystem.hpp" #include "utils.h" #include #include + std::ifstream t_fin__; std::map variable; @@ -32,20 +34,24 @@ std::pair genFactor(const std::string &line) } } -std::vector processPreInstruction(const std::string &line, int cnt, int lineno) +std::vector processPreInstruction(const std::string &line, int cnt, + int lineno, const std::string &FN) { + boost::filesystem::path curFile(FN); std::pair instruction = genFactor(line); //解析后的预编译指令 if (instruction.first == "import") { - t_fin__.open(instruction.second); + std::string realPath = + curFile.parent_path().string() + "/" + instruction.second; + t_fin__.open(realPath); if (!t_fin__.is_open()) { - CompileError e("import file " + instruction.second + " not found"); + CompileError e("import file " + realPath + " not found"); throw e; } std::string importFileContent; std::getline(t_fin__, importFileContent, char(EOF)); t_fin__.close(); - return preProcess(importFileContent, cnt + 1, instruction.second); + return preProcess(importFileContent, cnt + 1, realPath); } else if (instruction.first == "def") { //解析宏定义 std::string var, data; @@ -68,7 +74,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l data = instruction.second.substr(i + 1, len - i - 1); } variable[var] = data; - return std::vector{Tline(std::pair("",lineno),"")}; + return std::vector{ + Tline(std::pair("", lineno), "")}; } else if (instruction.first == "rmdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -80,7 +87,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l throw e; //找不到宏定义 } - return std::vector{Tline(std::pair("",lineno),"")}; + return std::vector{ + Tline(std::pair("", lineno), "")}; } else if (instruction.first == "ifdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -93,7 +101,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l closeifstack++; } currentifstack++; - return std::vector{Tline(std::pair("",lineno),"")}; + return std::vector{ + Tline(std::pair("", lineno), "")}; } else if (instruction.first == "ifndef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -106,7 +115,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l closeifstack++; } currentifstack++; - return std::vector{Tline(std::pair("",lineno),"")}; + return std::vector{ + Tline(std::pair("", lineno), "")}; } else if (instruction.first == "endif") { if (currentifstack == 0) { CompileError e("no second instruction"); @@ -116,7 +126,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, int l closeifstack--; } currentifstack--; - return std::vector{Tline(std::pair("",lineno),"")}; + return std::vector{ + Tline(std::pair("", lineno), "")}; } else { CompileError e("Unrecognized preprocessor command"); throw e; @@ -169,7 +180,7 @@ std::vector preProcess(const std::string &code, int cnt, std::string FN) std::vector processedLines; std::string temp; bool isCommented = false; - int lineno = 0; + int lineno = 0; while (std::getline(buft_fin__, temp)) { lineno++; if (closeifstack > 0 && temp.substr(0, 6) != "%endif" && @@ -178,9 +189,11 @@ std::vector preProcess(const std::string &code, int cnt, std::string FN) } if (temp[0] == '%') { auto processedPreInstruction = - processPreInstruction(temp, cnt, lineno); + processPreInstruction(temp, cnt, lineno, FN); if (processedPreInstruction.size() > 0) - std::move(processedPreInstruction.begin(), processedPreInstruction.end(), std::back_inserter(processedLines)); + std::move(processedPreInstruction.begin(), + processedPreInstruction.end(), + std::back_inserter(processedLines)); } else { std::string replaced = doReplace(temp); //处理块注释 @@ -219,7 +232,8 @@ std::vector preProcess(const std::string &code, int cnt, std::string FN) } int plen = result.length(); if (plen > 0) { - processedLines.push_back(Tline(std::pair(FN,lineno),result)); + processedLines.push_back( + Tline(std::pair(FN, lineno), result)); } } temp.erase(); -- Gitee From 3a53bad89511b72233513f319fb1a64e3ebd954f Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 18:41:54 +0800 Subject: [PATCH 17/95] Fix lots of bugs --- src/CompileUnit.cpp | 2 +- src/ast/ClassAST.cpp | 31 ++++++++----------------------- src/ast/ClassAST.h | 5 +++-- src/ast/CodeBlockAST.cpp | 1 + src/ast/ExprAST.cpp | 14 +++++--------- src/ast/FunctionAST.cpp | 2 +- src/ast/PrototypeAST.cpp | 4 ++-- src/ast/VariableDefExprAST.cpp | 3 ++- src/ast/VariableExprAST.cpp | 10 ++-------- src/ast/VariableExprAST.h | 3 --- 10 files changed, 25 insertions(+), 50 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index ac5e1b7..64c1ba6 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 << tokenmbn.dump() << std::endl; if (token.type == tok_eof) break; unit->tokenList.push_back(token); diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index bc12b77..759da2e 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -83,15 +83,16 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) return classAST; } -TypeAST *ClassAST::getRealType(TypeAST * type, +TypeAST *ClassAST::getRealType(const TypeAST * type, std::vector igenericTypes) { + TypeAST *realType = new TypeAST(unit, type->baseClass); if (type->pointee != nullptr) { - type->pointee = getRealType(type->pointee, igenericTypes); + realType->pointee = getRealType(type->pointee, igenericTypes); } for (unsigned int i = 0; i < type->genericTypes.size(); i++) { - type->genericTypes[i] = - getRealType(type->genericTypes[i], igenericTypes); + realType->genericTypes.push_back( + getRealType(type->genericTypes[i], igenericTypes)); } auto it = find(genericTypes.begin(), genericTypes.end(), type->baseClass); @@ -100,29 +101,13 @@ TypeAST *ClassAST::getRealType(TypeAST * type, int index = it - genericTypes.begin(); return igenericTypes[index]; } else { - return type; + return realType; } } -TypeAST *ClassAST::getRealType(TypeAST *type) +TypeAST *ClassAST::getRealType(const TypeAST *type) { - std::vector igenericTypes = this->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->baseClass); - - if (it != genericTypes.end()) { - //泛型 - int index = it - genericTypes.begin(); - return igenericTypes[index]; - } else { - return type; - } + return getRealType(type, this->igenericTypes); } std::string ClassAST::getRealName(std::vector igenericTypes) diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 8a4e3d6..ecdffce 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -20,8 +20,9 @@ class ClassAST : public BaseAST std::vector genericTypes); virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); - TypeAST *getRealType(TypeAST *type, std::vector igenericTypes); - TypeAST *getRealType(TypeAST *type); + TypeAST * getRealType(const TypeAST * type, + std::vector igenericTypes); + TypeAST * getRealType(const TypeAST *type); std::string getRealName(std::vector igenericTypes); std::string getRealNameForMangle(std::vector igenericTypes); diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp index 8c4183e..68e5ba7 100644 --- a/src/ast/CodeBlockAST.cpp +++ b/src/ast/CodeBlockAST.cpp @@ -72,6 +72,7 @@ CodeBlockAST::ParseCodeBlock(CompileUnit *unit, std::string name, llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) { + namedValues.clear(); llvm::BasicBlock *bb = llvm::BasicBlock::Create(*unit->context, name, function); endBB = bb; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 4b5c815..7ae4b34 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -7,6 +7,7 @@ #include "CodeBlockAST.h" #include "DoubleExprAST.h" #include "EmptyExprAST.h" +#include "FunctionAST.h" #include "IfExprAST.h" #include "IntExprAST.h" #include "MemberExprAST.h" @@ -175,7 +176,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, //函数调用 token = unit->next_tok(); ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); - result = new CallExprAST(unit, idName, args); + result = new CallExprAST(unit, idName, args, nullptr); } else { //变量或变量定义 int i = 1, ci = 1; @@ -213,7 +214,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, case tok_key_sizeof: { unit->next_tok(); // sizeof unit->next_tok(); //( - TypeAST *type = TypeAST::ParseType(unit); + TypeAST *type = + TypeAST::ParseType(unit, codeblock->baseFunction->parentClass); unit->next_tok(); //) result = new SizeofExprAST(unit, type); break; @@ -300,13 +302,7 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, bool root) { ExprAST *result = ParsePrimary(unit, codeblock, root); - - /*while (unit->icurTok->type == tok_syntax && - unit->icurTok->tokenValue == ".") { - LHS = MemberExprAST::ParseMemberExprAST(unit, codeblock, LHS); - }*/ - - result = ParseBinOpRHS(unit, codeblock, 0, result); + result = ParseBinOpRHS(unit, codeblock, 0, result); if (IfExprAST *v = dynamic_cast(result)) { return result; //跳过分号 diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index bb2d931..8cef957 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -60,7 +60,7 @@ FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit, protoType->args.begin(), std::pair( new TypeAST(unit, new TypeAST(unit, parentClass->className, - genericTypes)), + genericTypes, parentClass)), "this")); } std::cout << std::left << std::setw(35) diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 7816512..8037132 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -142,8 +142,8 @@ llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) } std::vector llvmArgs; - for (int i = 0; i < args.size(); i++) { - llvmArgs.push_back(args[i].first->Codegen()); + for (int i = 0; i < argStr.size(); i++) { + llvmArgs.push_back(argStr[i]->Codegen()); } llvm::Type *returnType; if (returnDirectly) { diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index 7dc37bc..ca44b98 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -41,7 +41,8 @@ static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, { llvm::IRBuilder<> builder(&function->getEntryBlock(), function->getEntryBlock().begin()); - return builder.CreateAlloca(typeAST->Codegen(), 0, VarName.c_str()); + llvm::Type * varType = typeAST->Codegen(); + return builder.CreateAlloca(varType, 0, VarName.c_str()); } std::vector diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp index 1c98edb..3bdb2b8 100644 --- a/src/ast/VariableExprAST.cpp +++ b/src/ast/VariableExprAST.cpp @@ -19,7 +19,6 @@ VariableExprAST::VariableExprAST(CompileUnit *unit, CodeBlockAST *codeblock, { this->idName = idName; this->codeblock = codeblock; - this->alloca = nullptr; } VariableExprAST::~VariableExprAST() @@ -29,10 +28,6 @@ VariableExprAST::~VariableExprAST() llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) { - - if (alloca != nullptr) { - return alloca; - } type.clear(); //找局部变量 CodeBlockAST *curCodeBlock = codeblock; @@ -41,7 +36,7 @@ llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) if (varAST == curCodeBlock->namedValues.end()) { curCodeBlock = curCodeBlock->parent; } else { - alloca = varAST->second.second; + llvm::Value *alloca = varAST->second.second; type.push_back(varAST->second.first); return alloca; } @@ -53,8 +48,7 @@ llvm::Value *VariableExprAST::getAlloca(llvm::IRBuilder<> *builder) throw e; } else { type.push_back(gVar->second.first); - alloca = gVar->second.second; - return alloca; + return gVar->second.second; } } diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h index 7189545..082db1c 100644 --- a/src/ast/VariableExprAST.h +++ b/src/ast/VariableExprAST.h @@ -19,9 +19,6 @@ class VariableExprAST : public ExprAST std::vector Codegen(llvm::IRBuilder<> *builder); std::string idName; CodeBlockAST * codeblock; - - private: - llvm::Value *alloca; }; #endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ -- Gitee From e988e5791c0d5be10b15d70b8e39d1df86ff65e4 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 18:45:38 +0800 Subject: [PATCH 18/95] Fix the multi-value issue of "sizeof" --- src/ast/SizeofExprAST.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ast/SizeofExprAST.cpp b/src/ast/SizeofExprAST.cpp index e243144..3f1927b 100644 --- a/src/ast/SizeofExprAST.cpp +++ b/src/ast/SizeofExprAST.cpp @@ -21,6 +21,7 @@ SizeofExprAST::~SizeofExprAST() std::vector SizeofExprAST::Codegen(llvm::IRBuilder<> *builder) { + this->type.clear(); std::vector result; this->type.push_back(new TypeAST(unit, "int")); llvm::DataLayout *TD = new llvm::DataLayout(unit->module); -- Gitee From 50669a486e1a281e8f6b02bc2cdc3958dfef66f9 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 22:43:27 +0800 Subject: [PATCH 19/95] Implement Unsafe package --- src/ast/CallExprAST.cpp | 36 ++++++++++++++----- src/ast/CallExprAST.h | 1 + src/ast/ExprAST.cpp | 6 +++- src/ast/FunctionAST.cpp | 74 ++++++++++++++++++++++++++++++++++++++-- src/ast/FunctionAST.h | 2 ++ src/ast/UnaryExprAST.cpp | 2 ++ src/lib/unsafe.alo | 30 ++++++++++++++++ 7 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 src/lib/unsafe.alo diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 36eba27..5e24ae9 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -38,7 +38,12 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) std::vector argStr; std::vector argsV = args->CodegenChain(builder); if (LHS != nullptr) { - llvm::Value *thisV = LHS->getAlloca(builder); + llvm::Value *thisV = nullptr; + if (Lpointer) { + thisV = LHS->Codegen(builder)[0]; + } else { + thisV = LHS->getAlloca(builder); + } if (thisV == nullptr) { CompileError e("No memory allocaed"); throw e; @@ -48,21 +53,34 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Multi/void value detected"); throw e; } - argStr.push_back(new TypeAST(unit, LHS->type[0])); + if (Lpointer) { + argStr.push_back(new TypeAST(unit, LHS->type[0]->pointee)); + } else { + argStr.push_back(new TypeAST(unit, LHS->type[0])); + } } for (TypeAST *ast : args->type) { argStr.push_back(ast); } - std::string dname; - llvm::Value *LHSv; //新构造 + std::string dname; if (LHS == nullptr) { dname = demangle(callee, argStr); } else { - LHSv = LHS->Codegen(builder)[0]; - ClassAST * baseClass = unit->classes[LHS->type[0]->baseClass]; - std::string typeMangledName = - baseClass->getRealNameForMangle(LHS->type[0]->genericTypes); - dname = demangle(callee, argStr, typeMangledName); + if (Lpointer) { + ClassAST *baseClass = + unit->classes[LHS->type[0]->pointee->baseClass]; + std::string typeMangledName = + baseClass->getRealNameForMangle(LHS->type[0]->genericTypes); + + dname = demangle(callee, argStr, typeMangledName); + + } else { + ClassAST * baseClass = unit->classes[LHS->type[0]->baseClass]; + std::string typeMangledName = + baseClass->getRealNameForMangle(LHS->type[0]->genericTypes); + + dname = demangle(callee, argStr, typeMangledName); + } } if (callee == "main") { dname = "main"; diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index ffab9de..41adb08 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -19,6 +19,7 @@ class CallExprAST : public ExprAST std::vector Codegen(llvm::IRBuilder<> *builder); std::string callee; + bool Lpointer = false; ExprAST * args; ExprAST * LHS; }; diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 7ae4b34..aad285d 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -280,8 +280,12 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, } else if (token.tokenValue == "->") { if (VariableExprAST *v = dynamic_cast(RHS)) { LHS = new MemberExprAST(unit, LHS, v->idName, true); + } else if (CallExprAST *v = dynamic_cast(RHS)) { + v->LHS = LHS; + v->Lpointer = true; + LHS = v; } else { - CompileError e("成员方法调用未实现"); + CompileError e("未知的操作"); throw e; } } else if (dynamic_cast(LHS) != nullptr && diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp index 8cef957..694f441 100644 --- a/src/ast/FunctionAST.cpp +++ b/src/ast/FunctionAST.cpp @@ -31,6 +31,73 @@ FunctionAST::~FunctionAST() // TODO Auto-generated destructor stub } +void FunctionAST::processInnerFunction(llvm::Function *func) +{ + llvm::IRBuilder<> *builder = new llvm::IRBuilder<>(*unit->context); + llvm::BasicBlock * bb = + llvm::BasicBlock::Create(*unit->context, "entry", func); + builder->SetInsertPoint(bb); + std::vector returnValue = std::vector(); + llvm::IRBuilder<> sBuilder(&func->getEntryBlock(), + func->getEntryBlock().begin()); + + llvm::StructType *sType = (llvm::StructType *)func->getReturnType(); + llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); + + if (proto->name == "__alolang_inner_load") { + llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); + llvm::Type * classType = + ((llvm::PointerType *)func->getArg(0)->getType())->getElementType(); + llvm::Type * realType = parentClass->igenericTypes[0]->Codegen(); + llvm::Value *thisValue = func->getArg(0); + llvm::Value *pointer = builder->CreateGEP( + classType, thisValue, + std::vector{llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 0, true)}); + pointer = builder->CreateLoad(pointer); + pointer = builder->CreateIntToPtr(pointer, + llvm::PointerType::get(realType, 0)); + returnValue.push_back(pointer); + } else if (proto->name == "__alolang_inner_toObj") { + llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); + llvm::Type * classType = + ((llvm::PointerType *)func->getArg(0)->getType())->getElementType(); + + llvm::Type * realType = parentClass->igenericTypes[0]->Codegen(); + llvm::Value *pointer = builder->CreateGEP( + classType, func->getArg(0), + std::vector{llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 0, true)}); + llvm::Value *addr = builder->CreatePtrToInt( + func->getArg(1), llvm::IntegerType::get(*unit->context, 64)); + builder->CreateStore(addr, pointer); + + } else { + CompileError e("No inner function:" + proto->name); + throw e; + } + 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); + } + + 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)); +} + llvm::Function *FunctionAST::Codegen(std::vector igenericTypes) { this->igenericTypes = igenericTypes; @@ -39,8 +106,11 @@ llvm::Function *FunctionAST::Codegen(std::vector igenericTypes) std::pair>( func->getName(), std::pair(proto, func))); - - llvm::BasicBlock *bb = body->Codegen(func); + if (proto->name.substr(0, 16) == "__alolang_inner_") { + processInnerFunction(func); + } else { + llvm::BasicBlock *bb = body->Codegen(func); + } // func->getBasicBlockList().push_back(bb); return func; diff --git a/src/ast/FunctionAST.h b/src/ast/FunctionAST.h index db7eb82..f08a246 100644 --- a/src/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -22,6 +22,8 @@ class FunctionAST : public BaseAST virtual ~FunctionAST(); llvm::Function * Codegen(std::vector igenericTypes = std::vector()); + void processInnerFunction(llvm::Function *func); + PrototypeAST *proto; ClassAST * parentClass; diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 9ff6f48..958fd66 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -48,6 +48,7 @@ llvm::Value *UnaryExprAST::getAlloca(llvm::IRBuilder<> *builder) std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) { + type.clear(); std::vector result; if (op == "&") { llvm::Value *pointer = operand->getAlloca(builder); @@ -55,6 +56,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("No memory allocaed"); throw e; } + type.push_back(new TypeAST(unit, operand->type[0])); result.push_back(pointer); } else { //值操作 diff --git a/src/lib/unsafe.alo b/src/lib/unsafe.alo new file mode 100644 index 0000000..f77223f --- /dev/null +++ b/src/lib/unsafe.alo @@ -0,0 +1,30 @@ +class UnsafePointer +{ + int addr; + func __alolang_inner_load()->A* + { + //编译器实现 + } + /*func __alolang_inner_set(A data){ + //编译器实现 + }*/ + func __alolang_inner_toObj(A* pointer) + { + //编译器实现 + } + func load()->A* + { + return this->__alolang_inner_load(); + } + func set(A data) + { + //__alolang_inner_set(data); + return; + } + func toObj(A* pointer) + { + this->__alolang_inner_toObj(pointer); + return; + } +} + -- Gitee From 02f0e9eec40ac27561315c269d7693a8c16d91f7 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 23:07:50 +0800 Subject: [PATCH 20/95] Implement malloc --- src/ast/ExprAST.cpp | 2 +- src/lib/Makefile.am | 2 +- src/lib/unsafe.alo | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index aad285d..8da8ed9 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -244,7 +244,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, while (1) { Token token = *unit->icurTok; int TokPrec; - if (LHS == nullptr) { + if (EmptyExprAST *v = dynamic_cast(LHS)) { TokPrec = GetLUnaryTokPrecedence(token); } else { TokPrec = GetBinTokPrecedence(token); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 5b01633..3286924 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = testPuts.c +libalolangcore_a_SOURCES = unsafe.c testPuts.c alolanglibdir=$(libdir) alolanglib_PROGRAMS = libalolangcore.so diff --git a/src/lib/unsafe.alo b/src/lib/unsafe.alo index f77223f..fb18c16 100644 --- a/src/lib/unsafe.alo +++ b/src/lib/unsafe.alo @@ -1,3 +1,5 @@ +extern func __cfree(int addr); +extern func __cmalloc(int size)->int; class UnsafePointer { int addr; @@ -16,15 +18,19 @@ class UnsafePointer { return this->__alolang_inner_load(); } - func set(A data) + func toObj(A* pointer) { - //__alolang_inner_set(data); + this->__alolang_inner_toObj(pointer); return; } - func toObj(A* pointer) + func malloc(int count) { - this->__alolang_inner_toObj(pointer); + this->addr=__cmalloc(count*sizeof(A)); + return; + } + func free() + { + __cfree(this->addr); return; } -} - +} \ No newline at end of file -- Gitee From e648fcd59076cf36106d17defdeed79d17e36886 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 7 Mar 2021 23:12:29 +0800 Subject: [PATCH 21/95] Add some lib files --- src/lib/testio.alo | 5 +++++ src/lib/unsafe.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/lib/testio.alo create mode 100644 src/lib/unsafe.c diff --git a/src/lib/testio.alo b/src/lib/testio.alo new file mode 100644 index 0000000..ed7b6d1 --- /dev/null +++ b/src/lib/testio.alo @@ -0,0 +1,5 @@ +extern func testPrintInt(int i); +extern func testPrintDouble(double f); +extern func testPrintBool(bool b); +extern "S" func testGetInt() -> int; +extern "S" func testGetDouble() -> double; \ No newline at end of file diff --git a/src/lib/unsafe.c b/src/lib/unsafe.c new file mode 100644 index 0000000..44ed4d3 --- /dev/null +++ b/src/lib/unsafe.c @@ -0,0 +1,19 @@ +/* + * unsafe.c + * + * Created on: Mar 7, 2021 + * Author: zbc + */ +#include + +extern void _alolang_7__cfree3inte(long long addr) { free((void *)addr); } + +struct addr { + long long addr; +}; +extern struct addr _alolang_9__cmalloc3inte(long long size) +{ + struct addr retValue; + retValue.addr = (long long)malloc(size); + return retValue; +} -- Gitee From f0a24358467e8c251b93367df74df37e4bc6f3a5 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 8 Mar 2021 01:00:33 +0800 Subject: [PATCH 22/95] some test code, compiler segv --- test/unsafetest.alo | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/unsafetest.alo diff --git a/test/unsafetest.alo b/test/unsafetest.alo new file mode 100644 index 0000000..75ac863 --- /dev/null +++ b/test/unsafetest.alo @@ -0,0 +1,46 @@ +%import ../src/lib/testio.alo +%import ../src/lib/unsafe.alo + +class node { + UnsafePointer> pred; + UnsafePointer> succ; + A data; +} + +func main() { + int i = 0; + UnsafePointer> init; + init.malloc(1); + init.load()->data = 0; + UnsafePointer> curs; + curs = init; + while (i < 20){ + i = i + 1; + UnsafePointer> next; + next.malloc(1); + next.load()->data = i; + curs.load()->succ = next; + next.load()->pred = curs; + curs = next; + } + + curs = init; + i = 0; + while (i < 20){ + testPrintInt(*(curs.load()).data); + curs = *(curs.load()).succ; + i = i + 1; + } + + while (i > 0){ + testPrintInt(*(curs.load()).data); + curs = *(curs.load()).pred; + i = i - 1; + } + + curs = *(init.load()).succ; + i = 0; + + while (i < 19) + *(curs.load()).pred.free(); +} \ No newline at end of file -- Gitee From a8f6b8ad5e2f76348ce4073ab0df042af3f9f8c5 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 8 Mar 2021 08:41:00 +0800 Subject: [PATCH 23/95] Add error handler --- src/ast/MemberExprAST.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index d10a644..e34a3f0 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -106,7 +106,11 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) MemberExprAST *v = dynamic_cast(chain[i]); std::string member = v->member; ClassAST * baseClass = unit->classes[curType]; - auto memberAST = baseClass->members.find(member); + if (baseClass == nullptr) { + CompileError e("Class " + curType + " not found."); + throw e; + } + auto memberAST = baseClass->members.find(member); if (memberAST == baseClass->members.end()) { CompileError e("Member" + member + " not found."); throw e; -- Gitee From e9ab351507acce77f77351060460c2a771cc13ab Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 8 Mar 2021 09:24:06 +0800 Subject: [PATCH 24/95] Fix bugs --- src/ast/CallExprAST.cpp | 47 +++++++++++++++++++++++++++++++-------- src/ast/CallExprAST.h | 12 +++++----- src/ast/ExprAST.cpp | 3 ++- src/ast/MemberExprAST.cpp | 11 +++++++++ 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 5e24ae9..49f173c 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -16,13 +16,14 @@ #include "../utils.h" -CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, - ExprAST *args, ExprAST *LHS) +CallExprAST::CallExprAST(CompileUnit *unit, FunctionAST *parentFunction, + const std::string &callee, ExprAST *args, ExprAST *LHS) : ExprAST(unit) { - this->callee = callee; - this->args = args; - this->LHS = LHS; + this->callee = callee; + this->args = args; + this->LHS = LHS; + this->parentFunction = parentFunction; std::cout << std::left << std::setw(35) << "Function call found:" << this->callee << std::endl; } @@ -34,6 +35,7 @@ CallExprAST::~CallExprAST() std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) { + type.clear(); std::vector result; std::vector argStr; std::vector argsV = args->CodegenChain(builder); @@ -54,13 +56,28 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } if (Lpointer) { - argStr.push_back(new TypeAST(unit, LHS->type[0]->pointee)); + if (parentFunction->parentClass == nullptr) { + argStr.push_back(new TypeAST(unit, LHS->type[0]->pointee)); + } else { + argStr.push_back(parentFunction->parentClass->getRealType( + new TypeAST(unit, LHS->type[0]->pointee))); + } + } else { - argStr.push_back(new TypeAST(unit, LHS->type[0])); + if (parentFunction->parentClass == nullptr) { + argStr.push_back(new TypeAST(unit, LHS->type[0])); + } else { + argStr.push_back(parentFunction->parentClass->getRealType( + new TypeAST(unit, LHS->type[0]))); + } } } for (TypeAST *ast : args->type) { - argStr.push_back(ast); + if (parentFunction->parentClass == nullptr) { + argStr.push_back(ast); + } else { + argStr.push_back(parentFunction->parentClass->getRealType(ast)); + } } std::string dname; if (LHS == nullptr) { @@ -96,7 +113,19 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) CompileError e("Function " + dname + " not found."); throw e; } - type = proto->returnTypes; + for (TypeAST *tAST : proto->returnTypes) { + if (LHS == nullptr) { + type.push_back(tAST); + } else { + ClassAST *baseClass; + if (Lpointer) { + baseClass = unit->classes[LHS->type[0]->pointee->baseClass]; + } else { + baseClass = unit->classes[LHS->type[0]->baseClass]; + } + type.push_back(baseClass->getRealType(tAST)); + } + } llvm::Function *CalleeF = unit->module->getFunction(dname); if (CalleeF == 0) { diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index 41adb08..d708432 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -13,15 +13,17 @@ class CallExprAST : public ExprAST { public: - CallExprAST(CompileUnit *unit, const std::string &callee, ExprAST *args, + CallExprAST(CompileUnit *unit, FunctionAST *parentFunction, + const std::string &callee, ExprAST *args, ExprAST *LHS = nullptr); virtual ~CallExprAST(); std::vector Codegen(llvm::IRBuilder<> *builder); - std::string callee; - bool Lpointer = false; - ExprAST * args; - ExprAST * LHS; + FunctionAST *parentFunction; + std::string callee; + bool Lpointer = false; + ExprAST * args; + ExprAST * LHS; }; #endif /* COMPILER_AST_CALLEXPRAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 8da8ed9..57f3df9 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -176,7 +176,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, //函数调用 token = unit->next_tok(); ExprAST *args = ExprAST::ParseExpression(unit, codeblock, false); - result = new CallExprAST(unit, idName, args, nullptr); + result = new CallExprAST(unit, codeblock->baseFunction, idName, + args, nullptr); } else { //变量或变量定义 int i = 1, ci = 1; diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index e34a3f0..daae350 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -9,6 +9,7 @@ #include "../CompileError.hpp" #include "ClassAST.h" #include "TypeAST.h" +#include "UnaryExprAST.h" #include "VariableExprAST.h" MemberExprAST::MemberExprAST(CompileUnit *unit, ExprAST *LHS, @@ -79,6 +80,16 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) dynamic_cast(curAST)) { pointerFlag = false; break; + } else if (UnaryExprAST *v = dynamic_cast(curAST)) { + if (v->op == "*") { + pointerFlag = true; + chain.push_back(v->operand); + break; + } else { + CompileError e("Unknown AST."); + throw e; + } + break; } else { CompileError e("Unknown AST."); throw e; -- Gitee From bde1a764ab7c8832695dbc3a9bd54e34d7e5bd50 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 8 Mar 2021 12:54:06 +0800 Subject: [PATCH 25/95] fixed token for 0.x --- src/yacc_stuff/tokenizer.lpp | 1 + test/unsafetest.alo | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 50fe167..90f2cb2 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -38,6 +38,7 @@ func token = tok_fun; return token extern token = tok_extern; return token; return token = tok_return; return token; [a-zA-Z_][a-zA-Z_0-9]* token = tok_identifier; return token; +0\.[0-9]+ token = tok_number; 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; diff --git a/test/unsafetest.alo b/test/unsafetest.alo index 75ac863..a45732e 100644 --- a/test/unsafetest.alo +++ b/test/unsafetest.alo @@ -27,20 +27,20 @@ func main() { curs = init; i = 0; while (i < 20){ - testPrintInt(*(curs.load()).data); - curs = *(curs.load()).succ; + testPrintInt(curs.load()->data); + curs = curs.load()->succ; i = i + 1; } while (i > 0){ - testPrintInt(*(curs.load()).data); - curs = *(curs.load()).pred; + testPrintInt(curs.load()->data); + curs = curs.load()->pred; i = i - 1; } - curs = *(init.load()).succ; + curs = init.load()->succ; i = 0; while (i < 19) - *(curs.load()).pred.free(); + curs.load()->pred.free(); } \ No newline at end of file -- Gitee From 25421891da02aa7f8cfb837d09576bc8d7bb5763 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 8 Mar 2021 13:31:42 +0800 Subject: [PATCH 26/95] Fix bugs --- src/ast/BinaryExprAST.cpp | 1 + src/ast/MemberExprAST.cpp | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 289f004..9a5c143 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -86,6 +86,7 @@ BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, } std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) { + type.clear(); std::vector result; if (binOP == "=") { diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index daae350..b1b95cc 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -95,12 +95,12 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) throw e; } } - std::string curType, startType; + TypeAST *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->getName(); + curType = start->type[0]->pointee; + startType = start->type[0]->pointee; } else { VariableExprAST *start = dynamic_cast(chain[chain.size() - 1]); @@ -109,16 +109,16 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) CompileError e("No memory allocaed"); throw e; } - curType = start->type[0]->baseClass; - startType = start->type[0]->getName(); + curType = start->type[0]; + startType = start->type[0]; } std::vector idx; for (int i = chain.size() - 2; i >= 0; i--) { MemberExprAST *v = dynamic_cast(chain[i]); std::string member = v->member; - ClassAST * baseClass = unit->classes[curType]; + ClassAST * baseClass = unit->classes[curType->baseClass]; if (baseClass == nullptr) { - CompileError e("Class " + curType + " not found."); + CompileError e("Class " + curType->baseClass + " not found."); throw e; } auto memberAST = baseClass->members.find(member); @@ -129,7 +129,8 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) unsigned int index = std::distance(std::begin(baseClass->members), memberAST); idx.push_back(index); - curType = baseClass->members[member]->variableType->getName(); + curType = baseClass->members[member]->variableType; + curType = baseClass->getRealType(curType); } std::vector idxl; llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); @@ -139,11 +140,11 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) idxl.push_back(llvm::ConstantInt::get(itype, pid, true)); } if (idx.size() != 0) { - auto typeAST = unit->types.find(startType); + auto typeAST = unit->types.find(startType->getName()); pointer = builder->CreateGEP(typeAST->second, pointer, idxl); } - type.push_back(new TypeAST(unit, curType)); + type.push_back(curType); return pointer; } -- Gitee From 4a89e23532f18a7915b11fcbd19a255e4ac94fbb Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 8 Mar 2021 13:50:05 +0800 Subject: [PATCH 27/95] fixed test code bug --- test/unsafetest.alo | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/unsafetest.alo b/test/unsafetest.alo index a45732e..6e5d4ef 100644 --- a/test/unsafetest.alo +++ b/test/unsafetest.alo @@ -41,6 +41,10 @@ func main() { curs = init.load()->succ; i = 0; - while (i < 19) + while (i < 20){ + testPrintInt(i); curs.load()->pred.free(); + curs = curs.load()->succ; + i = i + 1; + } } \ No newline at end of file -- Gitee From c4fbd979ba0d3ca1f79fb1433931adc24b15cc03 Mon Sep 17 00:00:00 2001 From: qaqwqaqwq_0 Date: Mon, 8 Mar 2021 22:33:51 +0800 Subject: [PATCH 28/95] Array library for compiler test --- src/lib/array.alo | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/lib/array.alo diff --git a/src/lib/array.alo b/src/lib/array.alo new file mode 100644 index 0000000..561c90c --- /dev/null +++ b/src/lib/array.alo @@ -0,0 +1,36 @@ +%import unsafe.alo + +class array +{ + UnsafePointer ptr; + int sz; // current size + int cap; // current capacity + func _Desired_size_to_capacity() + { + // this->cap = (int(this->sz / 16) + 1) * 16; + this->cap = this->sz; + } + func init(int _sz) + { + this->ptr.malloc(_sz); + this->sz = _sz; + this->_Desired_size_to_capacity(); + } + func destroy() + { + this->ptr.free(); + this->sz = this->cap = 0; + } + func size() -> int + { + return this->sz; + } + func capacity() -> int + { + return this->cap; + } + func data() -> A* + { + return this->ptr.load(); + } +} \ No newline at end of file -- Gitee From b6c3ee96625b903eda9bb9d21f7583ee17f44bd4 Mon Sep 17 00:00:00 2001 From: uebian Date: Mon, 8 Mar 2021 22:49:13 +0800 Subject: [PATCH 29/95] Implement floor --- src/CompileUnit.cpp | 5 +++++ src/aloc.cpp | 8 ++++---- src/ast/BinaryExprAST.cpp | 2 ++ src/ast/IfExprAST.cpp | 2 +- src/lib/Makefile.am | 2 +- src/lib/types.alo | 14 ++++++++++++++ src/lib/types.c | 8 ++++++++ 7 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/lib/types.alo create mode 100644 src/lib/types.c diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 64c1ba6..448943a 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -109,6 +109,11 @@ void initInnerOperations(CompileUnit *unit) {"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( diff --git a/src/aloc.cpp b/src/aloc.cpp index b8ee59e..d423169 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -126,10 +126,10 @@ int main(int argc, char *argv[]) for (std::string input_file_name : input_file_names) { objs += "./" + input_file_name + ".s "; } - std::string cmdline = "gcc -O0" + objs + - (vm.count("static") ? "-static " : "") + - " -fPIE -L " + alolanglibdir + - " -l alolangcore" + " -o " + output_file_name; + std::string cmdline = + "gcc -O0" + objs + (vm.count("static") ? "-static " : "") + + " -fPIE -L " + alolanglibdir + " -l m -l alolangcore" + " -o " + + output_file_name; std::cout << "debug info:" << cmdline << std::endl; system(cmdline.c_str()); return 0; diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 9a5c143..3949ff2 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -68,6 +68,8 @@ BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, return builder->CreateFMul(L, R); } else if (binOP == "/") { return builder->CreateFDiv(L, R); + } else if (binOP == "%") { + return builder->CreateFRem(L, R); } else if (binOP == "==") { return builder->CreateFCmpOEQ(L, R); } else if (binOP == "!=") { diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index 4265545..a879070 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -33,7 +33,7 @@ IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) CodeBlockAST::ParseCodeBlock(unit, "", parent->baseFunction, parent); CodeBlockAST *elseBlock = nullptr; - if ((unit->icurTok + 1)->type == tok_key_else) { + if (unit->icurTok->type == tok_key_else) { unit->next_tok(); elseBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent->baseFunction, parent); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 3286924..9b18ba6 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = unsafe.c testPuts.c +libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c alolanglibdir=$(libdir) alolanglib_PROGRAMS = libalolangcore.so diff --git a/src/lib/types.alo b/src/lib/types.alo new file mode 100644 index 0000000..980737f --- /dev/null +++ b/src/lib/types.alo @@ -0,0 +1,14 @@ +extern "S" func _cdouble2int(double v)->int; + +//返回一个小于传入参数的最大整数 +func floor(double v)->int{ + double v1=0.0; + if(v % 1.0 >= 0.0) + { + v1=v%1.0; + }else{ + v1=1.0 + v % 1.0; + } + double t=v - v1; + return _cdouble2int(t); +} \ No newline at end of file diff --git a/src/lib/types.c b/src/lib/types.c new file mode 100644 index 0000000..780ca50 --- /dev/null +++ b/src/lib/types.c @@ -0,0 +1,8 @@ +/* + * types.c + * + * Created on: Mar 8, 2021 + * Author: zbc + */ + +extern long long _alolang_12_cdouble2int6doublee(double v) { return (int)v; } -- Gitee From e77d4c0dff3fcae2e98c3412e99e6fe910b22148 Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 9 Mar 2021 13:10:49 +0800 Subject: [PATCH 30/95] Fix a bug in parsing sub expr --- src/ast/ExprAST.cpp | 2 +- src/lib/array.alo | 6 +++++- src/lib/types.alo | 2 +- src/lib/unsafe.alo | 8 ++++++++ src/lib/unsafe.c | 1 + 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 57f3df9..996e8cb 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -233,7 +233,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, void ExprAST::appendSubExpr(ExprAST *expr) { ExprAST *curAST = this; - while (curAST->subExpr == nullptr) { + while (curAST->subExpr != nullptr) { curAST = curAST->subExpr; } curAST->subExpr = expr; diff --git a/src/lib/array.alo b/src/lib/array.alo index 561c90c..186fc69 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -9,17 +9,21 @@ class array { // this->cap = (int(this->sz / 16) + 1) * 16; this->cap = this->sz; + return; } func init(int _sz) { this->ptr.malloc(_sz); this->sz = _sz; this->_Desired_size_to_capacity(); + return; } func destroy() { this->ptr.free(); - this->sz = this->cap = 0; + this->sz = 0; + this->cap = 0; + return; } func size() -> int { diff --git a/src/lib/types.alo b/src/lib/types.alo index 980737f..39fd0f8 100644 --- a/src/lib/types.alo +++ b/src/lib/types.alo @@ -9,6 +9,6 @@ func floor(double v)->int{ }else{ v1=1.0 + v % 1.0; } - double t=v - v1; + double t= v - v1; return _cdouble2int(t); } \ No newline at end of file diff --git a/src/lib/unsafe.alo b/src/lib/unsafe.alo index fb18c16..e309012 100644 --- a/src/lib/unsafe.alo +++ b/src/lib/unsafe.alo @@ -1,5 +1,13 @@ extern func __cfree(int addr); extern func __cmalloc(int size)->int; +extern func __cmemcpy(int src,int dst,int size); + +func memcpy(int src,int dst,int size) +{ + __cmemcpy(src,dst,size); + return; +} + class UnsafePointer { int addr; diff --git a/src/lib/unsafe.c b/src/lib/unsafe.c index 44ed4d3..2285cc8 100644 --- a/src/lib/unsafe.c +++ b/src/lib/unsafe.c @@ -11,6 +11,7 @@ extern void _alolang_7__cfree3inte(long long addr) { free((void *)addr); } struct addr { long long addr; }; + extern struct addr _alolang_9__cmalloc3inte(long long size) { struct addr retValue; -- Gitee From 3c1bbfa6e2d74116b8821e37b107010e7727de1c Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 9 Mar 2021 13:22:42 +0800 Subject: [PATCH 31/95] Implement memcpy --- src/ast/ExprAST.cpp | 3 ++- src/ast/IntExprAST.cpp | 3 ++- src/lib/unsafe.c | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 996e8cb..2e4e146 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -329,9 +329,10 @@ ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, std::vector ExprAST::CodegenChain(llvm::IRBuilder<> *builder) { + type.clear(); std::vector result = this->Codegen(builder); if (subExpr != nullptr) { - std::vector subResult = subExpr->Codegen(builder); + std::vector subResult = subExpr->CodegenChain(builder); std::vector subType = subExpr->type; result.insert(result.end(), subResult.begin(), subResult.end()); type.insert(type.end(), subType.begin(), subType.end()); diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp index 7353b5f..fed6ac7 100644 --- a/src/ast/IntExprAST.cpp +++ b/src/ast/IntExprAST.cpp @@ -11,7 +11,6 @@ IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) { this->val = val; - this->type.push_back(new TypeAST(unit, "int")); } IntExprAST::~IntExprAST() @@ -21,6 +20,8 @@ IntExprAST::~IntExprAST() std::vector IntExprAST::Codegen(llvm::IRBuilder<> *builder) { + type.clear(); + this->type.push_back(new TypeAST(unit, "int")); std::vector result; llvm::IntegerType *rtype = llvm::IntegerType::get(*unit->context, 64); llvm::ConstantInt *res = llvm::ConstantInt::get(rtype, val, true); diff --git a/src/lib/unsafe.c b/src/lib/unsafe.c index 2285cc8..018dde4 100644 --- a/src/lib/unsafe.c +++ b/src/lib/unsafe.c @@ -5,6 +5,13 @@ * Author: zbc */ #include +#include + +extern void _alolang_9__cmemcpy3inte3inte3inte(long long src, long long dst, + long long size) +{ + memcpy((void *)dst, (void *)src, size); +} extern void _alolang_7__cfree3inte(long long addr) { free((void *)addr); } -- Gitee From 29657aa9996afeb833265d823acfdd3d62ae6e26 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 19:17:20 +0800 Subject: [PATCH 32/95] Upload array.alo --- src/lib/array.alo | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index 186fc69..c97643a 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -5,17 +5,17 @@ class array UnsafePointer ptr; int sz; // current size int cap; // current capacity - func _Desired_size_to_capacity() + func _Desired_size_to_capacity(int _size) -> int { - // this->cap = (int(this->sz / 16) + 1) * 16; - this->cap = this->sz; - return; + // return (int(_size / 16) + 1) * 16; + // return (_size >> 4) + 1 << 4; + return _size; } func init(int _sz) { - this->ptr.malloc(_sz); this->sz = _sz; - this->_Desired_size_to_capacity(); + this->cap = this->_Desired_size_to_capacity(_sz); + this->ptr.malloc(this->cap); return; } func destroy() @@ -37,4 +37,27 @@ class array { return this->ptr.load(); } + func _Reallocate(int _Newsz) + { + this->cap = this->_Desired_size_to_capacity(_Newsz); + UnsafePointer newptr; + newptr.malloc(this->cap); + memcpy(this->ptr.load(), newptr.load(), this->sz * sizeof(A)); + this->ptr.free(); + this->ptr = newptr; + return; + } + func concat(A* _ptr, int _sz) + { + int newsz = this->sz + _sz; + if(newsz > this->cap) this->_Reallocate(newsz); + memcpy(_ptr, this->ptr.load() + /*this->sz * */sizeof(A), _sz * sizeof(A)); + this->sz = newsz; + return; + } + func append(A obj) + { + this->concat(&obj, 1); + return; + } } \ No newline at end of file -- Gitee From b66094483b2091b5deb3af161f41f29382a78517 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 19:23:46 +0800 Subject: [PATCH 33/95] Upload array.alo for testing "array.concat" --- src/lib/array.alo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index c97643a..1ba04fb 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -42,7 +42,7 @@ class array this->cap = this->_Desired_size_to_capacity(_Newsz); UnsafePointer newptr; newptr.malloc(this->cap); - memcpy(this->ptr.load(), newptr.load(), this->sz * sizeof(A)); + memcpy(this->ptr.addr, newptr.addr, this->sz * sizeof(A)); this->ptr.free(); this->ptr = newptr; return; @@ -51,7 +51,7 @@ class array { int newsz = this->sz + _sz; if(newsz > this->cap) this->_Reallocate(newsz); - memcpy(_ptr, this->ptr.load() + /*this->sz * */sizeof(A), _sz * sizeof(A)); + memcpy(_ptr.addr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); this->sz = newsz; return; } -- Gitee From dcc16c4f46ccf71ba68e9df936cb12585ed21135 Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 9 Mar 2021 19:47:05 +0800 Subject: [PATCH 34/95] Fix a order problem in ClassAST --- src/ast/ClassAST.cpp | 12 +++++------- src/ast/ClassAST.h | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 759da2e..668b9b0 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -12,7 +12,7 @@ ClassAST::ClassAST(CompileUnit *unit, const std::string &className, std::map members, - std::map functions, + std::vector functions, std::vector genericTypes) : BaseAST(unit) { @@ -57,7 +57,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) ClassAST *classAST = new ClassAST( unit, className, std::map(), - std::map(), genericTypes); + std::vector(), genericTypes); unit->next_tok(); while (true) { //解析成员方法,成员变量 @@ -67,8 +67,7 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) } if (token.type == tok_fun) { FunctionAST *funDef = FunctionAST::ParseFunction(unit, classAST); - classAST->functions.insert(std::pair( - funDef->proto->name, funDef)); + classAST->functions.push_back(funDef); } else { VariableDefExprAST *memberDef = @@ -159,9 +158,8 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) } llvm_S->setBody(sMembers); std::map::iterator function_iter; - for (function_iter = functions.begin(); function_iter != functions.end(); - function_iter++) { - function_iter->second->Codegen(igenericTypes); + for (FunctionAST *function : functions) { + function->Codegen(igenericTypes); } return llvm_S; diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index ecdffce..9c6f06b 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -16,7 +16,7 @@ class ClassAST : public BaseAST public: ClassAST(CompileUnit *unit, const std::string &className, std::map members, - std::map functions, + std::vector functions, std::vector genericTypes); virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); @@ -29,7 +29,7 @@ class ClassAST : public BaseAST static ClassAST * ParseClass(CompileUnit *unit); std::map members; - std::map functions; + std::vector functions; std::vector genericTypes; std::string className; std::vector igenericTypes; // todo:注意多线程的情形 -- Gitee From 0a92b3b3f2cc20b14a13417a1bd72b37642af6e7 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 20:04:02 +0800 Subject: [PATCH 35/95] Update array.alo for compiler testing --- src/lib/array.alo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index 1ba04fb..a56ea36 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -51,7 +51,7 @@ class array { int newsz = this->sz + _sz; if(newsz > this->cap) this->_Reallocate(newsz); - memcpy(_ptr.addr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); + memcpy(_ptr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); this->sz = newsz; return; } -- Gitee From 53b9ad5d48612eecfa6791f0bd05c4e719a4a4bf Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 9 Mar 2021 20:18:21 +0800 Subject: [PATCH 36/95] Fix the member order issue of Class --- src/ast/ClassAST.cpp | 32 +++++++++++++++++--------------- src/ast/ClassAST.h | 9 +++++---- src/ast/MemberExprAST.cpp | 16 +++++++++++----- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 668b9b0..39b7636 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -11,15 +11,19 @@ #include "TypeAST.h" ClassAST::ClassAST(CompileUnit *unit, const std::string &className, - std::map members, - std::vector functions, - std::vector genericTypes) + std::vector members, + std::vector functions, + std::vector genericTypes) : BaseAST(unit) { this->className = className; - this->members = members; + this->omembers = members; this->functions = functions; this->genericTypes = genericTypes; + for (VariableDefExprAST *member : members) { + this->members.insert(std::pair( + member->idName, member)); + } } ClassAST::~ClassAST() @@ -55,9 +59,9 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) throw e; } - ClassAST *classAST = new ClassAST( - unit, className, std::map(), - std::vector(), genericTypes); + ClassAST *classAST = + new ClassAST(unit, className, std::vector(), + std::vector(), genericTypes); unit->next_tok(); while (true) { //解析成员方法,成员变量 @@ -72,12 +76,15 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) } else { VariableDefExprAST *memberDef = VariableDefExprAST::ParseVar(unit, nullptr); + classAST->omembers.push_back(memberDef); classAST->members.insert( std::pair(memberDef->idName, memberDef)); + unit->next_tok(); } } + token = unit->next_tok(); return classAST; } @@ -147,17 +154,12 @@ llvm::Type *ClassAST::Codegen(std::vector igenericTypes) llvm::StructType *llvm_S = llvm::StructType::create(*unit->context, className); unit->types.insert(std::pair(name, llvm_S)); - std::vector sMembers; - std::map::iterator member_iter; - for (member_iter = members.begin(); member_iter != members.end(); - member_iter++) { - VariableDefExprAST *memberVariable = member_iter->second; - TypeAST * mType = - getRealType(memberVariable->variableType, igenericTypes); + std::vector sMembers; + for (VariableDefExprAST *member : this->omembers) { + TypeAST *mType = getRealType(member->variableType, igenericTypes); sMembers.push_back(mType->Codegen()); } llvm_S->setBody(sMembers); - std::map::iterator function_iter; for (FunctionAST *function : functions) { function->Codegen(igenericTypes); } diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index 9c6f06b..cfea558 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -15,9 +15,9 @@ class ClassAST : public BaseAST { public: ClassAST(CompileUnit *unit, const std::string &className, - std::map members, - std::vector functions, - std::vector genericTypes); + std::vector members, + std::vector functions, + std::vector genericTypes); virtual ~ClassAST(); llvm::Type *Codegen(std::vector genericTypes); TypeAST * getRealType(const TypeAST * type, @@ -28,7 +28,8 @@ class ClassAST : public BaseAST std::string getRealNameForMangle(std::vector igenericTypes); static ClassAST * ParseClass(CompileUnit *unit); - std::map members; + std::map members; //查找用 + std::vector omembers; //记录顺序用 std::vector functions; std::vector genericTypes; std::string className; diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index b1b95cc..d9e3b86 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -45,13 +45,19 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) base = builder->CreateLoad(base); genericTypes = LHS->type[0]->pointee->genericTypes; } - auto memberAST = baseClass->members.find(member); - if (memberAST == baseClass->members.end()) { - CompileError e("Member " + member + " not found."); + //查找变量位置 + unsigned int index = 0; + bool foundFlag = false; + for (; index < baseClass->omembers.size(); index++) { + if (baseClass->omembers[index]->idName == this->member) { + foundFlag = true; + break; + } + } + if (!foundFlag) { + CompileError e("Member " + this->member + " not found."); throw e; } - unsigned int index = - std::distance(std::begin(baseClass->members), memberAST); type.push_back(baseClass->getRealType( baseClass->members[member]->variableType, genericTypes)); -- Gitee From 94f314d3a7d5e8f0c5bfb736fba5f8ad2d54c5a3 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 20:56:58 +0800 Subject: [PATCH 37/95] Upload array.alo for debug --- .vscode/settings.json | 63 ++++++++++++++++++++++++++++++++++++++++++- src/lib/array.alo | 3 ++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6d68035..b20dbbb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,67 @@ "*.inc": "cpp", "deque": "cpp", "string": "cpp", - "vector": "cpp" + "vector": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "strstream": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "cuchar": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string_view": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "scoped_allocator": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "valarray": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/src/lib/array.alo b/src/lib/array.alo index a56ea36..c49e687 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -51,7 +51,8 @@ class array { int newsz = this->sz + _sz; if(newsz > this->cap) this->_Reallocate(newsz); - memcpy(_ptr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); + UnsafePointer _ptr_wrapper = _ptr; + memcpy(_ptr_wrapper.addr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); this->sz = newsz; return; } -- Gitee From 66858a84c641a8f0dd90e6f30d3e5e5ae6f2d7b7 Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 9 Mar 2021 21:08:00 +0800 Subject: [PATCH 38/95] Fix the alloc issue of member order --- src/ast/MemberExprAST.cpp | 15 ++++++++++----- src/lib/array.alo | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index d9e3b86..d1f85b2 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -127,13 +127,18 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) CompileError e("Class " + curType->baseClass + " not found."); throw e; } - auto memberAST = baseClass->members.find(member); - if (memberAST == baseClass->members.end()) { - CompileError e("Member" + member + " not found."); + unsigned int index = 0; + bool foundFlag = false; + for (; index < baseClass->omembers.size(); index++) { + if (baseClass->omembers[index]->idName == this->member) { + foundFlag = true; + break; + } + } + if (!foundFlag) { + CompileError e("Member " + this->member + " not found."); throw e; } - unsigned int index = - std::distance(std::begin(baseClass->members), memberAST); idx.push_back(index); curType = baseClass->members[member]->variableType; curType = baseClass->getRealType(curType); diff --git a/src/lib/array.alo b/src/lib/array.alo index c49e687..d02c06f 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -56,9 +56,9 @@ class array this->sz = newsz; return; } - func append(A obj) + /*func append(A obj) { this->concat(&obj, 1); return; - } + }*/ } \ No newline at end of file -- Gitee From cfcf0854130c48d1a489eba1dbe0e157771771df Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 22:09:55 +0800 Subject: [PATCH 39/95] Update of array.alo --- src/lib/array.alo | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index d02c06f..d13b30d 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -7,9 +7,10 @@ class array int cap; // current capacity func _Desired_size_to_capacity(int _size) -> int { - // return (int(_size / 16) + 1) * 16; + return (floor(_size / 16.0) + 1) * 16; + // This is to be replcaced by the code below + // since the binary operators are implemented: // return (_size >> 4) + 1 << 4; - return _size; } func init(int _sz) { @@ -37,6 +38,10 @@ class array { return this->ptr.load(); } + func udata() -> UnsafePointer + { + return this->ptr; + } func _Reallocate(int _Newsz) { this->cap = this->_Desired_size_to_capacity(_Newsz); @@ -51,14 +56,27 @@ class array { int newsz = this->sz + _sz; if(newsz > this->cap) this->_Reallocate(newsz); - UnsafePointer _ptr_wrapper = _ptr; + UnsafePointer _ptr_wrapper; + _ptr_wrapper.toObj(_ptr); memcpy(_ptr_wrapper.addr, this->ptr.addr + this->sz * sizeof(A), _sz * sizeof(A)); this->sz = newsz; return; } - /*func append(A obj) + func append(A obj) { this->concat(&obj, 1); return; - }*/ + } + func push_back(A obj) + { + this->concat(&obj, 1); + return; + } + func get(int _Index) -> A* + { + UnsafePointer _ptr; + _ptr.toObj(this->ptr.load()); + _ptr.addr = _ptr.addr + _Index * sizeof(int); + return _ptr.load(); + } } \ No newline at end of file -- Gitee From aeacc8f2b33b10a34320e301105d8133b9295578 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 22:17:33 +0800 Subject: [PATCH 40/95] detecting bugs in types.alo --- src/lib/array.alo | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index d13b30d..9c2a505 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -1,4 +1,5 @@ %import unsafe.alo +%import types.alo class array { @@ -7,7 +8,8 @@ class array int cap; // current capacity func _Desired_size_to_capacity(int _size) -> int { - return (floor(_size / 16.0) + 1) * 16; + int u = floor(_size / 16); + return (u + 1) * 16; // This is to be replcaced by the code below // since the binary operators are implemented: // return (_size >> 4) + 1 << 4; -- Gitee From cfd979cadfc36c6090b322fcaf8851a31c4f7246 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 22:39:04 +0800 Subject: [PATCH 41/95] The final commit of array.alo in the current phase --- src/lib/array.alo | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/lib/array.alo b/src/lib/array.alo index 9c2a505..b846c7a 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -81,4 +81,30 @@ class array _ptr.addr = _ptr.addr + _Index * sizeof(int); return _ptr.load(); } + func pop_back() -> A + { + // TODO: + // if(this->sz < 1) throw some error; + UnsafePointer p; + p.addr = this->ptr.addr; + p.addr = p.addr + this->sz * sizeof(A) - sizeof(A); + this->sz = this->sz - 1; + return *(p.load()); + } + func erase_back(int _Size_to_erase) + { + // array = [0, 1, 2, 3, 4, 5, 6] + // array.erase_back(3) + // array = [0, 1, 2, 3] + this->sz = this->sz - _Size_to_erase; + return; + } + func back() -> A + { + // if(this->sz < 1) throw some error; + UnsafePointer p; + p.addr = this->ptr.addr; + p.addr = p.addr + this->sz * sizeof(A) - sizeof(A); + return *(p.load()); + } } \ No newline at end of file -- Gitee From 4e312971a19f4a020b0edb83554488179c0e2251 Mon Sep 17 00:00:00 2001 From: zry Date: Tue, 9 Mar 2021 23:19:18 +0800 Subject: [PATCH 42/95] Add array.init overload function --- src/lib/array.alo | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/array.alo b/src/lib/array.alo index b846c7a..0974236 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -21,6 +21,13 @@ class array this->ptr.malloc(this->cap); return; } + func init() + { + this->sz = 0; + this->cap = 16; + this->ptr.malloc(this->cap); + return; + } func destroy() { this->ptr.free(); -- Gitee From 8c5fb527b0fbcf70d90b6cd6120cb50eb6ea6148 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 14:12:06 +0800 Subject: [PATCH 43/95] Implement ">>" --- src/CompileUnit.cpp | 11 +++++++++++ src/ast/BinaryExprAST.cpp | 4 ++++ src/yacc_stuff/tokenizer.lpp | 1 + 3 files changed, 16 insertions(+) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 448943a..a79837a 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -89,6 +89,17 @@ void initInnerOperations(CompileUnit *unit) 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, "int")))); + + unit->binOperators.insert(std::pair, + std::pair>( + {"int", "int", "<<"}, std::pair( + nullptr, new TypeAST(unit, "int")))); + // double unit->binOperators.insert(std::pair, std::pair>( diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 3949ff2..67be1e2 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -57,6 +57,10 @@ BinaryExprAST::processInnerBinaryOperator(llvm::Value *L, llvm::Value *R, return builder->CreateICmpSGE(L, R); } else if (binOP == "<=") { return builder->CreateICmpSLE(L, R); + } else if (binOP == "<<") { + return builder->CreateShl(L, R); + } else if (binOP == ">>") { + return builder->CreateLShr(L, R); } } else if (LHS->type[0]->getName() == "double" && RHS->type[0]->getName() == "double") { diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index 90f2cb2..a525f1f 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -48,6 +48,7 @@ return token = tok_return; 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; \>= token = tok_syntax; return token; -- Gitee From 786d1261baf38d96b25eca11c607427544e142e6 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 10 Mar 2021 14:18:30 +0800 Subject: [PATCH 44/95] fixed parser for << --- src/yacc_stuff/tokenizer.lpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp index a525f1f..7b4c5e6 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -49,6 +49,7 @@ return token = tok_return; return token -> token = tok_syntax; return token; >> token = tok_syntax; return token; +<< token = tok_syntax; return token; == token = tok_syntax; return token; != token = tok_syntax; return token; \>= token = tok_syntax; return token; -- Gitee From ead9fc02873daa0f000928cb3de456f5e5e3422c Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 10 Mar 2021 15:08:29 +0800 Subject: [PATCH 45/95] 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 7b4c5e6..b12145b 100644 --- a/src/yacc_stuff/tokenizer.lpp +++ b/src/yacc_stuff/tokenizer.lpp @@ -48,8 +48,8 @@ return token = tok_return; 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; == token = tok_syntax; return token; != token = tok_syntax; return token; \>= token = tok_syntax; return token; -- Gitee From 18e27eb4c3e775c139bc66650862889a72defde9 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 15:18:16 +0800 Subject: [PATCH 46/95] Add jumped flag to Codeblock --- src/ast/CodeBlockAST.h | 5 +++-- src/ast/ExprAST.cpp | 3 ++- src/ast/IfExprAST.cpp | 12 ++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 789a0d0..14f0985 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -22,8 +22,8 @@ class CodeBlockAST : public BaseAST CodeBlockAST *parent = nullptr); virtual ~CodeBlockAST(); static CodeBlockAST * - ParseCodeBlock(CompileUnit *unit, std::string name,FunctionAST *baseFunction, - CodeBlockAST * parent = nullptr, + ParseCodeBlock(CompileUnit *unit, std::string name, + FunctionAST *baseFunction, CodeBlockAST *parent = nullptr, const std::vector args = std::vector()); llvm::BasicBlock *Codegen(llvm::Function *function); @@ -36,6 +36,7 @@ class CodeBlockAST : public BaseAST CodeBlockAST * parent; llvm::BasicBlock *endBB; FunctionAST * baseFunction; + bool jumped = false; //是否有跳出语句 }; #endif /* COMPILER_AST_CODEBLOCKAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 2e4e146..e6a7d22 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -209,7 +209,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, break; } case tok_return: { - result = ReturnExprAST::ParseReturnExprAST(unit, codeblock); + result = ReturnExprAST::ParseReturnExprAST(unit, codeblock); + codeblock->jumped = true; break; } case tok_key_sizeof: { diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp index a879070..76a98d2 100644 --- a/src/ast/IfExprAST.cpp +++ b/src/ast/IfExprAST.cpp @@ -56,13 +56,17 @@ std::vector IfExprAST::Codegen(llvm::IRBuilder<> *builder) if (elseBlock != nullptr) { llvm::BasicBlock *elseBB = elseBlock->Codegen(function); builder->CreateCondBr(conditionValue, thenBB, elseBB); - builder->SetInsertPoint(elseBlock->endBB); - builder->CreateBr(MergeBB); + if (!elseBlock->jumped) { + builder->SetInsertPoint(elseBlock->endBB); + builder->CreateBr(MergeBB); + } } else { builder->CreateCondBr(conditionValue, thenBB, MergeBB); } - builder->SetInsertPoint(thenBlock->endBB); - builder->CreateBr(MergeBB); + if (!thenBlock->jumped) { + builder->SetInsertPoint(thenBlock->endBB); + builder->CreateBr(MergeBB); + } builder->SetInsertPoint(MergeBB); parent->endBB = MergeBB; return std::vector(); -- Gitee From f6df32df4fdb56ba057a9a093ca55a40242ba026 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 10 Mar 2021 16:30:45 +0800 Subject: [PATCH 47/95] added rand and time --- src/lib/Makefile.am | 4 ++-- src/lib/testPuts.c | 4 ++-- src/lib/testrand.alo | 2 ++ src/lib/testrand.c | 12 ++++++++++++ tools/demangle | Bin 51416 -> 52960 bytes 5 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 src/lib/testrand.alo create mode 100644 src/lib/testrand.c diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 9b18ba6..bcae18a 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,8 +1,8 @@ AUTOMAKE_OPTIONS = foreign lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c +libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c alolanglibdir=$(libdir) alolanglib_PROGRAMS = libalolangcore.so -libalolangcore_so_SOURCES = testPuts.c +libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c libalolangcore_so_LDFLAGS = -shared -fpic diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 630226b..a6917ba 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -13,9 +13,9 @@ extern void _alolang_13testPrintBool4boole(int a) } } -extern int _alolang_10testGetInte() +extern long long _alolang_10testGetInte() { - int a; + long long a; scanf("%d", &a); return a; } diff --git a/src/lib/testrand.alo b/src/lib/testrand.alo new file mode 100644 index 0000000..ce98be4 --- /dev/null +++ b/src/lib/testrand.alo @@ -0,0 +1,2 @@ +extern "S" func testRanInt() -> int; +extern "S" func testRand() -> int; \ No newline at end of file diff --git a/src/lib/testrand.c b/src/lib/testrand.c new file mode 100644 index 0000000..236af1a --- /dev/null +++ b/src/lib/testrand.c @@ -0,0 +1,12 @@ +#include +#include + +extern long long _alolang_10testRanInte(void) +{ + return rand(); +} + +extern long long _alolang_8testTimee(void) +{ + return time(0); +} \ No newline at end of file diff --git a/tools/demangle b/tools/demangle index 8a6a8ce9de531187bdfae7913f40c6b8754ed464..5aea898bd347d8654a8b2d4f090d43910f68e995 100755 GIT binary patch literal 52960 zcmeIbeSB2K^*??$$pR`S(SoMp!=k9*L(JxJqauN@u#o^U35Zs_Y&J`>l4N7D!C=Kk z1IiYo)M~|t{yx-N%cr$3X=`oTT8*FvZELZ$iqF()-5Bf#t1|XU?2CbLPyMxp#NJ;jf&R=5nQL@=Dh(&|J8$Iz=GLB!16R@&=$x^Jz!o zUypW@HV)+s#tC|v0HBI%cUmf(Ao0{7)yt7BTjBANPeIa&E`n6g=}O273ToMclj^zY z)Ltc751u5j2C!SkIY5&dS$&{ zSx>=iX-@@}JxLt>`J_FqunaW1%J^SRv)1dB^{jBN zt(x*1*JHoB@s?|dhx$P>nFo+?^rtSWKNEk%L-xtmwrNu#nQ#~2Zx;SeZJt;@`MGDO zeCN|p!{p5q%Ykyd4u_DVZK$i@r*`-m4)~d{s~!J5$hN}|qf>VH-=c$d_$4sB9sWlS z`X7I|rk!lluXh~up8$S4`PVu0>wO1(h8_AF!GPJxFLUT`923@#f54%?cO7QWzt%y% z%Yi@3!46M2=zpby9Zq%7f4KvGx`Unn$H7nX9QaRg(DPpo{f#?}*Fz5d+Toyo4)~9< z@wcGEc+GR@*L;V5echqm#~kzzIq*{evh%A)9NOLOV7E$#e*M#-U;pbc?uQMI|c@6x;ZoGiD)#oe+yxXC_+Z^!UL<4sAztMref&FTV=IItj$|ePI zEr5Ma)-ts>Dd^)mRpOTcPSuXlI%OU)U68fe;6F;6qG{I)gp#A_dP8%xMQ@J<+hV$| z=@qpL_4;sIxFOOW3%AuSEN_aoglmI!O<_T^r(C*dK~1bg*F&A1UavR5F4!IkL1tT| zrJ*8J6Z3jQjlniO))tJ!+ABi-njrr1mxQ9tt--diziL59(=V-wHMLianrS0E%t zAu=3nt_aoY{+c44YK^Ah;-+v*L#)xinp@4!)Ad+mTl6Yjp!INDTeMB+G#crVPJc55 z*DkGzm4-V*;nr9r+CrLgugksu>IF40^rf}vtcBr_O(@%9(>dDN#(=eYZ5~WmqE|0i z(%{!s9WDuwVL`Rx-r+w)>~8)ZEEN4I*W1C3#JewP#A8hZ?f|fyRnz5 z7n2D`(P(j`r9Iph^EYD@3P&lUq%8~?tHWQQ({lgP1$gcBAo6Z$U#i zrU#pvqM=|c+9t>GkX^4h*xHJ5laqH8BY`epl3^GM zCR(GDAC96WrK%iqM5&;d@el_CBW{WLUl*(wb|JT{UAoAN$bg6ztc$GnQj}mFZwL$3y`vea93_0AReGp#mA*0< zY0?l`kp0NW6^w;DBj^x^ij@(X%vVz#oRQFUqD-+l7-`W^ZjaT6&ODRONs6i1Y}_@3 zz)B@A;X?vHzr0*8$j#H{S60j^*Yk4=jl2BZBCUMcve|PgbZ>4!ZmA$FTL$*R-27q_ z%}g=h=jMBn+NSY;>G+raGVtf-zjWNEGfr@flN91h*TzfQ1j#}5=s$uahwkVDGKsQ#Mg9)!H{+D#I-dgu-)HBP%zmjC?VD(o0Cw5_rnn{g|4g6Z1NW%)|x zPtzVlnJ#rs2`0YErb#IG4+@`6#>Ew|;P;&(@XIXtEwa4Af`53C;BU0xvlk0|s|BCP z7x=9f{Jx6>zV|u-m7c1s+NW(1b&1A7*MwL5KsW`T4H_i54uot!Gtd~;WwG^r6&Al6aHKiev1izo(ccu?Uxq#(gGtb@XxFhKMr*7oecT2DO?Y`q z_WcKlQ|qWqOZUJYE?-JzTCxXrak-kxv{VoDarr_j(-J+fjmvYWJc-I%xO^^^X-OW~ z#N~V{(^5Rp#pN@oOiS=UE0<5EGA+FWE4X|dm1)TxsN(X`RHmhNpp46hQ<;|7fjlm! zQJI$30S}iyz8qy*QU|iR`~j6|DIL(b{4SMGqVm4asQ+(L*+b<$Tz;9#Q>na*%YULW zEtLa(Tz-biv_uYU%+o((_^MJ=Bp-l71`(8!-xyu9bHv`>o?W?M->~YUSdx4%K z{|Ge#Ju`m?ZycUncbTSrxCzAw1O$5Abp%R>Vv{iyF940E;$g#kvQFxPY;A{x;4fwV zqI?1~{u7Ar3q1ahS%Jrg(gUui0?+*?HVFbIO92yx_pHo1X>PJU>DM*0Xaz)e6f6mJ z&)ohs+y>%r$BqnaoO%Cp(rg=0i4gkwlzSo=UCVc@%*{G!9rz$;W%8cl0m&O^0PhmW zh!1V>zlyFjKujR+--p}F#BBn%E#h`4u+g6goaY~kO{Kf6hqVp{(w$ z*q)*rY5d~-iDLy(VAr>T_$$;#^`e!M<2MK>kj5OS@bD*8-w@saM|rFjH4@8-5Z?hB zNeRTC3dG+?yo=}&=$U*hoEjoOz8C=5lc`bFKkAX_#|xy;wTKU3{TJMxinpM+uCK#A zuop9U)20B-Tpu`77%H}8aFJ+HDfdv7B3gsN192w)1jIxy zF>hQx^t3Thn-TvpP>rN={1-G&tpnAweiIWRAH98Q{Wnn30{!bZ5F}e}Tu;?VftN^p zDO0j;<*^z^;y2z-yapfJ;Y6^)p|T$BL%l0Nrjfmghh}}36n8lF$FA~UKbDnu1$ugz zyJtOx*hk4FNf8YU@Cm|Uz=ZzX>NrZ@c%oY_w}) zTiSH3{PVP{<5q37`vw*h=*wzDyE9U?dj&aU%peu+A4W+zL%Fk~`O zf8sY-?l2)OR{JXH72j^C2H$@%agWeWDZ5q(QX1tFwVPeRHSiJ*XtH0|3s$b#-ItB& z@Ge#j8joJ0^s@tClF<;#(KQX>ox<)T3GG;#A#1CYRfw*b!o{`HseZv~-_FIJ^}ATJ zqGhs9f;GEcVAt;hQH6`8lH(@iFX#$$K;awz#XVEPeW)+OMJ^FIT#ytQE`Eb#1>qur zH5H2ft_A?%;-8|?ksW$ajOs{2oJI+)N2q3UT*#JjcJsXbqVSpG6$-&PBdy`;}0aq^aj-joMk`0_1z(>yb?lBR!-J{U2t(t@lkK z_puZ75iJGi-e1`C##~8`$vqzmZS5-ea%CQq+o@A_e*ZluH`zc0JE?UfwWsK(TX{1sGPi>NYXuPLego zbE9&~{X!5;GY@+IShxd|P@F_|OnQe~6qR-lqbR)Nfq#O}Is;3Q&|wCyoJydmqKcGy zBXK3P#@f4{S3$XKh>3J8#BD-rD$2b`Le+}WpZF$Bl)7kVt)usZ2D-?`+_d=I*Ci-A@W?y`|Ej}&My+qpk60o4a<1Wt|G<)*qy-i0Qd(r7>7j!l)OgiF1{tjGKqV)}I}%5;RL(j}aGRI|Hk?zmer@(;VuyeM z$d0f5G~O}Pz4lXANB(t`JYbtM1GbxoRWY%JYV=HgoDA1fR6q;mM)yA#iB>~Uc9Y0p zAEj!KVOD5~`_TCE9h+za5{R!ILhYJLs^%XG#IrZac8L)0*az&sq$bSHeEo@r{~I0_ zqJiBV?|8o7zn8>s^go~VU>`P0xY@X5U)F=$Hjc}QTGp_fSXeP?soS^|K7m` zXo5=tNg1kj;)!_Q#j^;nw-a{%IC|2hWDX0K({n~`;sY2ioTU^>IzL;2>LJWW?v}59m zy-E2SZzp{N@v27EV$U*?yev@=H!tB?~);fD`U)FramQI=yzNc z-t(BaXUF-uxM!dFA?^>-Bd-B#ibt+8Az1LGCIm~bFc7I8=>=YON_ympDJb^HBTOjt zZZCCKc;w@_P5hq8>a2&ODJ^|Hlh5;$$(+_jvF_vO4<~Nh+sA=%-(Uu@TNX^QjDl~; zJ{gT}=ZG=+p}B^5ZiQ1QFm-Q-)|@QONl^Eo0QHUPcW;LSGwJjs2@c65I5Lwa3KAA? zij1UwRU^`Xk?RF)u>tPnM4Nj6+V9Z?nOey8KM-HC6H9w{!WH-L4Ro*F8OplhClrk~ zF5DT2?+iSiNDKUW$4ApIyJh=F(*yr{Gw}GkX@U5zz~g(;0xlf7Oj-|Sjcy4uc*^ArV0T(uv?qhI(mGy9jYeO3470?O^rlcMD zF&)!TCD%?mt4-@}-kUZMpizO|hpnCs+RlIro(JQR0U?_!(*bOc`w`R@lHnr{3Q+*og+9{gPhGV*Zr>4T>qqOR&qqMt@yjY#eZ|!LKoP z!P-Yms;8RCZ|rCx}aXUv}?=3*(PbcC1_QpF@Qcla(jB&Lr; zgd$dQ?~Rm#5u891at7wwklVaNFd~=`_xK(+yxlI!Aq;W6VY{Az z__!Nw;(inEonp|vPPC0xq)e*LV)PitYVaPk$<)%vIIVMP>1yKR;fH{LGzc&(WR*$C zm8Q_AdL_3?)SJzG^gwQ;#(9~!4>rSdkoLU&ufxOZ`?7B9Q_mz0JlCN>AL%oT_n4Sk zG&PemyaCdHdIJeB!T}Fh1$DA#$s4GtX27@pCb=MJ{hNHx!D9{G%bEEHl0<; z(=<1wx#cFv*z;m=EdI;G)t|T(qi1-CnjihNGSPxD6zDHQVsG5zPz&r*61Z`zR@u~$ z(7kq_7NcD&e2b#PLPQ6)2Tc-ddxmDIGH8)!EqSm`78S)~#O}R0#P86}L_!BB~5%%RFw2ip1DVvAwdbr44 zB)8Zi^CV3%A|=zXzO7qWj8EO{PyC5;ggE>>rLplQF|x~c-KBj+kFhQsC%O!!7gD#y z*%cO;3*Inx?}#oIISFJNFw_#NF^NyRP-CJ|BXzIey|)owu@%FrEh9$BPT%#zxSvYKYtlw{VI$&NK)OD?~{3xPKdh1^)by&Mrym0MNTdZ6k5m zA<%n(-UBjC{mmrh20AS#TcQSqz&JS*q6h&r!^23ghXnflyw)cYC}6?AQqb{CQa!~b z4f+$0vqAGj(4h$S5@9<<>%DmT-s@2{Z%(aAA55k0a$eA}OV+$V)*OtgY8R(gtFmn{ zVAtRYsWp$WZBXPZ{@%nePAm9PYV2gy^sBU8Bx5b4Q9$R|JkRqclE!KY{;IPBXD-3w z{jnQtilsTp0_$h9JYEHO&F>SIr$LbM8YB1$+1h7!0vD>oN3VLz!akc z_!FpX&c2*x_lGYNqu(*V!jxveBi#{?S?MlxPDO;&#eE1Tko#g&NFb^5GN%hT@FLjl zAMy;oqT;wsnh!If&TVW1O6AefryldbpoyD#Gs^2;E%b%uX(O6EomH6yr*deS_7Y5` zRssje_0bA^pg(abD@u)WF`dreXY8PuO$kEjc7FdLHW8&>Vt?=@HX8H3NYAK}tM5)O zqAPqxMqOf)-9Tu}9wUS2x_1*68GPH(s^#Zs#h{!%Q(@>lnzzh*F!sp7hOu`OgSklC3+kuzoxfnXjJ+WS91|QwL35aJIo^c=;E`0I%&Wc!1eGt0jhb;rIuiht|Rh;-Mc2feP}FLiiiJ zsXy@~1knRDIaeNLe>2V|=mZ*EpzgwIUWu0l;d)yL+5LovpJ}P=Shx~R37)?Fi9zB@ z#yDe0$byC@Px*&&4nyZ7G=IoQJS4wGU891KEc%q&(iA3Rw{fWQwAdnKK+n6Dd^{D-xG&<IWsfT3KI3_|U#es|VmBiIk(@_c zSx>y5g^Ew(joi5!zyCV>;>wi%q z_JqVOyCCTC&(dQjd0&z5^H#<`sEq$(Zv36u!;{_!bnkElN?+@Em)^hs+Va_#&0aqH z^4Yriom+a}b_diTNHUXe>H|57i#~tK*SXrc9^A+hf2NP_k$m&#=4kis!Cx8vy6~66 zU@6kBe+2&l>LB;!cJR=JKhrlJkYwPcIR1FU~K?_vM!s{KA65 z!os4$;=+=!W@GyO1qXKSThC%rOU>D#b%#jIr z$Xkw`MIK=P>%+sH80hRbhKDx;o(8xT^=1L?1iT0^0k{fq0vzd6K-%#oa9Gg_I1VRN zn*fgi+y=N6$5guk&&BaAKJu*5F|G&jdcYNcIqyI|U?Jd6z$(B5;3~jn(C2oX@pl65 z2iyX<3fqMz0DlJf7T~`DGvHj)@X&P{U;uC~U?X5X;3mLzfW3hC0X`4-1mMYd-kAVg z2{;jsxf$>*z+S*gz&8P#0LSBD{B3~80X_sc9q@U;xqu%6wgFCpQ(p^M2>1|SE#P** z7~o#O+W^<&)rDTbKLOJBZM_CK1b77AYskS{GG0I*;4HvpfSrJyfKLE!2HX$W3z&xY zU3LQwAVSlJS&zmF;sGoNECaj-a0TEKfL(xZ0&W3(_9OHg@EB}=-U3_-n1P@i2b>1@ z2;f}6X8`K~Pr%cW4S?l?}>Y9BZTxuoG|@;2!}y0fzuL1Lhzf=mnesxErtua0u`|z#RDZ!+<{WcN{q^11tmV z1*Esp)R%|hO;)~KS66GU&TQ9|iQ^}1LUKWP`q0guKMW6_LmYF*qo(*QdLiKEXE3KQ zSG3IRd6_vEW*u?Wgf4B?ap#>;FzsaGqq_J^hqn5a;bA<(##)n^eM4ILk>hI70E$Gv z27gh|@$O@izA#C@2k0Q^$C>F%lJrM_{~GAuGSky;Vg`~=m+R`PO77YCyMJ<~rcF`( zn+6*FJ%IXyfEkZr;FXU4?)0?3CflKXQ|qh4!zY5z;JGA8p9^{m=rDbfexaaK8#m$a za?o$Z0+n%vshvP~diwe_W+c9c@V65&iuoe;eAKUp&|W@b&lEJeysmC>-*B^j>59li#=wz?A(EbI_4iA3>hswCtqDNwaq3=YoCg!Px`8)ZRmSz{|D>GeDE7>rOh#Hw;A-O4nXe({XNjnG}kwc@ovzEKtIJyzdULC zA<#bs-D9SIElJPG5cKJ0dMHWvfu4bflc$^MbxHa%&?ka!H}=%#7PLPB^o6+3*odI7 zd?+ozLWt)H@Z^JMF7d1~@q8oMP9NH-1`mCp&5+TQr0)Tpp2d31bW=ZR-6r}OW_noE zp9UPQ|1F@?_Y-CeVo_6i(s)iuj%R?@bv!=Ci}XpJMM*sxLBAYyg!d%9B1zu>dL`&~ z_9EZh3VHzaTyyNMe`N3rS zdqIC6bf-Q}M9%aE=$w42agHVHp9T65=uY}qf<6toU%t8h=4AaQ(2GI0>mT{rL(uPJ z(BDCv$@n&yl@8=tCAG?=sN;40_m1Pg}tZ+<(w>uxGIw1ESvp`Z&<% znCp`hqU^!nBcM+QJ!Gcynl4sjlCcLov|pNG<}u9`4U_Ro(4G3|0sVT=opR7J(60fV z^Jq0+7bk770`ykU?fU3}PF^ktxX%yiRQ+a&2n zndy~D{cZxi0`<$ybo5~jSg8F6K&SVqQ{oorH0_E0d(hW`?j(ON=&M1$#4JBeY)Gj7 zMC{$Rfqtf$Zpx|70)0O6%?dL;ZLVRTO3+(D$0sn8V^AgfHy5ZT(7Pa?=fk|r>|4?* zGIMTD_h))~GW?m-Z*tGg%)4P+Ak)`9etu?IOQvsjX5Q?~>2oqYb24-0WM<$fzo`>D&lD@|LM=DsdndoV4^r1h@XT<(8mYWrR8 zzh!Elq`B|S(r!z4-<+l0nBo3ImiBmt`&U`oCmHUij?!*-U-UElJI;;m>MzH+-^$Xy zIo^Fsw)Xw;KXifc?+NZ-XKQyK=Dt5$`^RDKXS22M9R95|5MG$*{^n8Ih9lkkv$Y=` z>3%a?yD8KC{~e{>pXmnm^`nGEhVP!?I%%H!|6J*pxLtmlpWa0$*C-OACBy zfiErar3L=W7Es@dtG)+UeebPmR(;>B`hHvWeYOeSJSwh(hx;x{>GWO0bRl&Ymq!4kzBlUxhY)|tvxGmu(jeVM?&5M$a?~^8a4m|i6b7q=s6-? zynh75(F|YsfD>OnDNy0F=_O%YN^knzA-b@Y=S#K!$*|}Tkj#pgIJkc+q+-Letn|Vo zIHtcY6~Ut_E-SfG{QvKucdfk&#U6p5C*e{FS4y~A!W$&~j)eD1_^^aeN%(?td@g&)eJAC8%xt{6xHMtocZ(eRb zzI*+^mkZbcTO_3E=xbpkoavD{7i|r z##=g9bm8}m^48&o?*-KPezFm#1Xj~-zzwyl;<&=!%KVdzxTo+x#f_c*k1~I@Hla#z zlD+7934bm`%S;RY9}=Hs!GFT|DVo=!|KSiwa=cE%*wFud?8;l=xZ;{!WQsX2Cxq@t0Zf zZ%h0N3qBi;LHg8N@aIWra zlk$&U9J?6&{0n&1DXiLQIJ`}xY|)d7zk=l-t6B4hc9t_~M7*W*_`*_wQ2Y-_{M<5uS9(rD!b@_dOT6N*1>R22 zD}c{N7QXK~AxHgtrIfQt>Up{(JkN46wMC~11ij-y*D)AcJNb>klRo<|6nt|8(2kr= zu5g^T&C>4ElK%;5H}XrmF2Kg(C}^r#{C^?vBtOSupKZX~=|dmABmPglLhhgd+W$#> zcBMe5yuTU`i0tJ2FYqMik$~Vwk*^c8?D@}gz{i0t_pYX(sI{iT|lYJRpTt;bD)R-L3|n zm{Yo~Y zT_f>Ue|sNzJNYy5A_>X4XMxaUhE(Vl;O+Q#JMfCOsUTaz}v~W!U6v)DQCtaA)s8!$wDGd@=v}%Am&Q^83mA^mZhnE zzC>%wCI7{8e3d@!z}xAwUGiJ~;bnhCq!I;FW^Oj2lyY@|qFPHpkzP}{#jWSLmtnqak9GK+i%ebfXzaMxS z$32#Dd{pv3Ap>N-lrsefBqV2?)F0EIuh|m6wMdjzzcxv{b-j37;`g5``1u_;+*kZd+v%A#)gFHa@D!h|`9m@Ar04hLx}fZT5Aaj5j;nJ><COjwd1m?=60wfWityxs2<{}y<=ejNrsAUW1NrwRD)K~K*`LhjR2{(X}FU1@)* zmUbe>kK|b6%qoe$woC|+(^Y#;;;nJ!9pLSLPx&+8?exF!RMGD3a$X0eo_7L&l)N{C zKS=)VWdf`G=akcgoFO^kJc6vXOT0R7hI{kXBk}v?yik617!pOYL(U?>r*ybf;{ScV zz^iqk6?nUT{l)=*1m-X0tJb{n8{-K-Mf0r_^3}gNJl|C*34_3sp4N5kL5Z)D6J6yG zpRt@wtpejf*JT1|htIIre-89H3VQZkCm0c4_&UXbzYTcO=V#JB^Cf?u#CxTk)jT>K z14sP56@oEe@;?AP*}*y=dnNz$GQp_&H3Yn!{g1~0QJgGWEcnAx{#n3NyJ_VD@lKk6 zk1@YwGJ(vq1ph3#0IIf*0bbpk*tLk{@4irARl83~{4)W8uaT8zoh{@~s}u-jpPMEA z2x&LCD_<{3{3@x>wxo1Bk#?i9C(s*xr{%m-Ftzz^OIjW;Qu7$ zSm&*R2dO40*Uio@g;+v$MW%{C(7YaGnb@ncapC;ES zEFXOBmG~3n{8j#0iv@!8*?fWE^9Z2b3%s2jwmabWNIB!ngn+L|Iqyq+r?m6M5`S^A zXm_vVzf*vDid-u1<<}P z@m4?oSmJx-I3mpQH6QD=ojw|V4E*etXe^u?!Vlu2pvQs@S_HpW4n(Le)*kD?FXn`_ z`fwY5{<}REZqsAU_|@=eOSl~s>Z5u?Q?xGFq}SsEsO@^Nqf^7@Qd^tC_+Tp@&e(G3 z_zB*K9&Bq1uF=CSv9>kZ%C=y0Sg-GBZeD{brV>8J8o_V7n^^0^&G?XP6ZCCu<)0|7 z^p>_p!lCe0k@m12inidFe>+0r*NZE?1;)?9Lr8<*FOD>{MBDKDzxaLQN}sMrqSOeA zi%NC9p{0XY*<>DQFa=R0#*2RFv8Wl97p#xA zis~dCzsz0)BZfPLmcf=-du351gx`lJskY?emS}rNUArUQ2lOuQxksw z*pb1T=PzG4yC&2YX^lBD72#LxBOyn!FWec!Pcw(>9XSeuSFLg+7B;knTOFxI;RBMr z`8tiwnwDsDB-rFA#aqx!KU}ZI^mF+zCG@)J=gT9$@Ims`MXx%jcEbnYD;3=cwy-PO zI*qqb@Q`XP9Zd)5L$P4Qq=`jZI-(uUj^>rDt!?4edT=#z9uIsk70f3h9|KWA=uC0}e!>j7p^zTgVChk^%U zla1ElcgowsE1m5p8?9>tP{pT=B)!Gn&4HoDIrw;sBr!uRS@Cp!!dX)77D!v3(9Kz{Chq9?0YP% zM>u2^BG^+oLSLH@i6M?eu0|=^q6hI4^Yvk|q)<6864CVem5b-hu0)lNI=w<~U(*r` zc4FC@S3P^7U-vJXtK-M+b-bdW`vVdgm|Lysb1zvmdtpU6XeoY8G`s-{S9hSKOMqJCQ#%P$RLu%c=-4L~4NgGj%>HczkBYv3L}y}H)RhCXzSi}`yx z>ityWm;m*@8*Mc?FMUb)T^}$%s zXlInBEElF+R1k-WW zn+cH2uDt~<;j8d{H#~o%ZKLuGzt0E_%~cD?e@*E-Mpj3T-;8}p1Y4FM_9mm7UNx~| z@!dKVGFlYF&Hb=4B47#JykarJZ+)ai??4jsUmn}JVh&&mpm(vxw&+!uSM|b-DUn_1 zp#p9xHYH+-@Kfwuv|x*5a@IZ{hcf17+VQlo2OV}<|X3hV*16)V} zi~53%CR#?7Vi5A*I?CWe-1uV!hZ-K}_q7WJmHdpXU z;Kxic&wgn{HCy#?XDEzaYqZ5;OOsm`;v|B<#44FVg!~~t{JutS4>w^=L4Gf`1DJwHBRejb-fUOSX;^c=C&?IN;x`XK-=aJhPohSVvtGZUYv`4 zcP`HOIy?2&a9ewnVr^`Vz8dG0*2y?GZ`4a!p;!oQN5pVEpLy>l!>40HhCW#axELBE zhUMwy>cDeUll?;8{a8(|Ql3#v6xwpKOk+<`&>U&0XvXBjHYK0_w+!nc8N$KSEpgPF zjH6@GmD1LZ_C};yI8j(E_clmy#zHc3_l0_>F^uD7tQ3Cau{eZBd>ZBELnesUWyMSR z_-Mvbq>E$IRbOg`m^xyHvmlq$gZ1@o;r90E%29c=AK``22xsu0xkNvZFCy=NW%zt$YG$(3RShaad)XJ$rG7eK;M@ zw(D57>8u8;BC?&(6`XEkr$zgbit5qK9RFg}@)oy+c}s&N2M=poLSgL3{Du7Jf)3^= zSeQ5FhqUk(*zZ~SspS}+_?k1qB4mVgHtS!_N57`5kmuRRX=b-04Z#GEGIHB-C#>8itq(dh(o% z>?m5N?V~l9qL#-v!I#08oOA3VdQuckA~pZao_&zdMIxQ4C$zk6!r=@OJxtV9`bs=A zG9r8-0)Oqoa`kuzv0l#CQ9XJ%hzUze&84+9scS1xhwl6-XR*@1#&9_3_)i_~$P>n~ znJF|rWP_#VFg|jw7+b1?9Ckdua^B02peqRqiWN zy{ho4Mm+!LM+ajQI`~OH-hbhTBu0XWUN~-MsFzqnM$Cp$b+ewI9l#&((oyGu4nGb) zWLYv8+73KL^*V&Uq<@a`m`n~m`s|BD+xgvu z!V0|hL-^G6LT`%Hh4fH+2fwj1hDIpC%9Z*Mfi#nQOv0#`yyx6P-Qa-~lhQ zan!>@UYqCJHV;ZHadB)$w1^+D%gli7IaaR?ArDxn(~AYQt!j@F#j|%9r*>&-3Nm(+ zy8y;ixs2)fNj;Q6|1cIR{OLj6JIXgx4*2%kn58nQZ$j9ujiY*+YM+3N^>I@2p@Rw& zmc0SCGY2|)bv(f`qo-&56x6?{Mz?#3NxWgKl!tu0 z6`&o7U#|)9f{@f{Oy08+c~?a(?X}crKyVU5p8%;1)`|BK%x~t5#gpOWz+tW~X}Kzb z_*5Nk?`X!0G3DiY0e!Lr&LZD}u&mnTMPsqhh|{ZN4nUt;5n&>E1jP{_?H%e`nS4$v z&x*%*&`Q)xrR+}fm5!QN_{z~asUJ_v5V$Ny1$4H`ue_LZma!Oqm7$@{u^34CKwggB z7#>$AtxN~i>YRG)mJ)da2LDPfBy`|um!)!AjJzn4`feBPHo{k8^k}Y#SEVqJ@HS%w ziq>60FI0^#nWk)1KJh0ftHOanwebS=Sd5)FKa5jeoWJt}cq2QK<1{?KA6+*6IpONi zjcfa?fYTM@nD+}W1({iP z2?1kmg0dPfdcjXq3OZH;S}wgis^#L*KK|v^KDRB(FYV`s8|9}`8|zV5 zl^`?}k}tI4bF-8Tu?+EnRUt#&lN@RkB3Z#;b0mcNQ8a~ra=Crc77jVIT)ax(jL*i( zPw$Q%(DyCSN0sH*C1^S6LY9KZTSUu`H5*v^+&I2c!l>_)^%X2LIK|BbOBo-_PO0B1 z>nkX~*21WjVcdxu`k1=8ef52<3VJO3*7_HNj-UCAs{X6*b5;-^hv#dYgjW57z|(gK zsQN=ve+6@7MbeRMr|Re6o~{V~sEVquzCT()^?lLAOPAIDR{}@h&8+IH?_*Z*dafmY zcbIM!pMuu{N8k0V%If=`72GE4lm4Wq(qE#r9^8;kRekk+(+aBZo3`3d_5Ti8e~uKW zzQ0;Q^?lb=|Eu^@?W_9V1CDH>Q_q!3F)_!&6lL*wJyotDxlT=s-A*VE%nv+A8n(+gsY7IP5z_wR+!UKpJb{2Yu5|PK3U&qIHtgt z31IwtmTW)Iz=#`F-};>vVCTyWEln_eLYv_8QP9Cf-!C-}f2!Xq{u~CJp*!x?Rkl&w dt-|+em@n0?!X1ShyZS$VQg9SmDp-oz{{vFaW7Plv delta 13188 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 WWyRvre*jx^a)9o&|FDlv_WVCdIRT~s -- Gitee From aa27c18bf0d2a8d93ba96e19157b896a54df32d2 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 17:09:26 +0800 Subject: [PATCH 48/95] Fix names --- src/lib/testrand.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/lib/testrand.c b/src/lib/testrand.c index 236af1a..de9c1c9 100644 --- a/src/lib/testrand.c +++ b/src/lib/testrand.c @@ -1,12 +1,6 @@ #include #include -extern long long _alolang_10testRanInte(void) -{ - return rand(); -} +extern long long _alolang_8testRand(void) { return rand(); } -extern long long _alolang_8testTimee(void) -{ - return time(0); -} \ No newline at end of file +extern long long _alolang_8testTime(void) { return time(0); } -- Gitee From 32fdb8c218551237d2247a7aa2884bad060ab165 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 17:34:44 +0800 Subject: [PATCH 49/95] Fix a bug in locating member --- src/ast/MemberExprAST.cpp | 8 ++++---- src/lib/array.alo | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index d1f85b2..57b6c90 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -121,7 +121,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) std::vector idx; for (int i = chain.size() - 2; i >= 0; i--) { MemberExprAST *v = dynamic_cast(chain[i]); - std::string member = v->member; + std::string cmember = v->member; ClassAST * baseClass = unit->classes[curType->baseClass]; if (baseClass == nullptr) { CompileError e("Class " + curType->baseClass + " not found."); @@ -130,17 +130,17 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) unsigned int index = 0; bool foundFlag = false; for (; index < baseClass->omembers.size(); index++) { - if (baseClass->omembers[index]->idName == this->member) { + if (baseClass->omembers[index]->idName == cmember) { foundFlag = true; break; } } if (!foundFlag) { - CompileError e("Member " + this->member + " not found."); + CompileError e("Member " + cmember + " not found."); throw e; } idx.push_back(index); - curType = baseClass->members[member]->variableType; + curType = baseClass->members[cmember]->variableType; curType = baseClass->getRealType(curType); } std::vector idxl; diff --git a/src/lib/array.alo b/src/lib/array.alo index 0974236..22c1ddf 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -3,7 +3,7 @@ class array { - UnsafePointer ptr; + UnsafePointer ptr; // start int sz; // current size int cap; // current capacity func _Desired_size_to_capacity(int _size) -> int @@ -83,10 +83,10 @@ class array } func get(int _Index) -> A* { - UnsafePointer _ptr; - _ptr.toObj(this->ptr.load()); - _ptr.addr = _ptr.addr + _Index * sizeof(int); - return _ptr.load(); + /*UnsafePointer cur; + cur.addr=this->ptr.addr+_Index * sizeof(int); + return cur.load();*/ + return this->ptr.load(); } func pop_back() -> A { -- Gitee From bd9c0b7fc1f84ab05a2621f01dc985bcb1f82010 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 17:38:23 +0800 Subject: [PATCH 50/95] Optimization --- src/lib/array.alo | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib/array.alo b/src/lib/array.alo index 22c1ddf..f140e2c 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -83,10 +83,9 @@ class array } func get(int _Index) -> A* { - /*UnsafePointer cur; + UnsafePointer cur; cur.addr=this->ptr.addr+_Index * sizeof(int); - return cur.load();*/ - return this->ptr.load(); + return cur.load(); } func pop_back() -> A { -- Gitee From 2f31ec34e950f8fdff629e833c53b7b609806fde Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 17:41:17 +0800 Subject: [PATCH 51/95] Fix time --- src/lib/testrand.alo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/testrand.alo b/src/lib/testrand.alo index ce98be4..54002be 100644 --- a/src/lib/testrand.alo +++ b/src/lib/testrand.alo @@ -1,2 +1,2 @@ -extern "S" func testRanInt() -> int; +extern "S" func testTime() -> int; extern "S" func testRand() -> int; \ No newline at end of file -- Gitee From fde5ef60c071566c6ec03da5518ff79f735633d3 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 10 Mar 2021 17:47:36 +0800 Subject: [PATCH 52/95] change the get time function to return ns --- src/lib/testrand.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lib/testrand.c b/src/lib/testrand.c index 236af1a..5519b8d 100644 --- a/src/lib/testrand.c +++ b/src/lib/testrand.c @@ -1,12 +1,14 @@ +#include +#include #include #include -extern long long _alolang_10testRanInte(void) -{ - return rand(); -} +extern long long _alolang_10testRanInte(void) { return rand(); } extern long long _alolang_8testTimee(void) { - return time(0); + struct timespec spec; + clock_gettime(0, &spec); + long long ns = spec.tv_sec * 1000000 + spec.tv_nsec; + return ns; } \ No newline at end of file -- Gitee From 8eaa207c5c0faaefd1206ee76fee107084512f1a Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 17:51:42 +0800 Subject: [PATCH 53/95] Fix names --- src/lib/testrand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/testrand.c b/src/lib/testrand.c index 45051e2..0377f4e 100644 --- a/src/lib/testrand.c +++ b/src/lib/testrand.c @@ -3,9 +3,9 @@ #include #include -extern long long _alolang_10testRanInte(void) { return rand(); } +extern long long _alolang_8testRand(void) { return rand(); } -extern long long _alolang_8testTimee(void) +extern long long _alolang_8testTime(void) { struct timespec spec; clock_gettime(0, &spec); -- Gitee From 0b3f6a69934a980fcd67ca43a232376246ff9849 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 20:29:25 +0800 Subject: [PATCH 54/95] Add source in BaseAST --- src/ast/BaseAST.h | 1 + src/lib/testPuts.c | 2 +- src/lib/testrand.c | 16 +++++++++------- src/preprocessor.h | 7 +++---- src/utils.h | 4 ---- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/ast/BaseAST.h b/src/ast/BaseAST.h index 33d4f13..be45186 100644 --- a/src/ast/BaseAST.h +++ b/src/ast/BaseAST.h @@ -15,6 +15,7 @@ class BaseAST BaseAST(CompileUnit *unit); virtual ~BaseAST(); CompileUnit *unit; + Tline source; }; #endif /* COMPILER_AST_ASTBASE_H_ */ diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index a6917ba..fc6f802 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -16,7 +16,7 @@ extern void _alolang_13testPrintBool4boole(int a) extern long long _alolang_10testGetInte() { long long a; - scanf("%d", &a); + scanf("%lld", &a); return a; } diff --git a/src/lib/testrand.c b/src/lib/testrand.c index 0377f4e..29a04f7 100644 --- a/src/lib/testrand.c +++ b/src/lib/testrand.c @@ -1,14 +1,16 @@ #include #include #include -#include - +#include extern long long _alolang_8testRand(void) { return rand(); } -extern long long _alolang_8testTime(void) +int64_t currentTimeMillis() { - struct timespec spec; - clock_gettime(0, &spec); - long long ns = spec.tv_sec * 1000000 + spec.tv_nsec; - return ns; + struct timeval time; + gettimeofday(&time, NULL); + int64_t s1 = (int64_t)(time.tv_sec) * 1000; + int64_t s2 = (time.tv_usec / 1000); + return s1 + s2; } + +extern long long _alolang_8testTime(void) { return currentTimeMillis(); } diff --git a/src/preprocessor.h b/src/preprocessor.h index 6d56b80..35d15e0 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -4,14 +4,13 @@ #include #include #include -#include -#include #include #include +#include +#include -typedef std::pair,std::string> Tline; +typedef std::pair, std::string> Tline; std::vector preProcess(const std::string &code, int cnt, std::string FN); - #endif diff --git a/src/utils.h b/src/utils.h index bc2b521..789b988 100644 --- a/src/utils.h +++ b/src/utils.h @@ -20,8 +20,4 @@ bool isSyntax(char c); void skipSpace(const std::vector &words, long unsigned int &i); void skipSpace(std::istream &in); -template inline bool instanceof (const T *) -{ - return std::is_base_of::value; -} #endif /* COMPILER_UTILS_H_ */ -- Gitee From a9373ed2fc265ce35c3e76cf169fcbb5b9dbd962 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 10 Mar 2021 20:40:11 +0800 Subject: [PATCH 55/95] Added comment --- src/preprocessor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/preprocessor.h b/src/preprocessor.h index 6d56b80..9956130 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -10,6 +10,7 @@ #include typedef std::pair,std::string> Tline; +//外层:first是行所在文件名和行号,second是行内容 std::vector preProcess(const std::string &code, int cnt, std::string FN); -- Gitee From caed9ba859ac98aff41777d0119dd5f2eb5410a0 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:01:05 +0800 Subject: [PATCH 56/95] Rebuild TokenSource --- src/CompileError.hpp | 29 +++++++++++++++-------------- src/CompileUnit.cpp | 3 +-- src/Token.cpp | 5 ++--- src/Token.h | 4 ++-- src/TokenSource.h | 22 ++++++++++++++++++++++ src/ast/ClassAST.cpp | 4 ++-- src/ast/ExprAST.cpp | 7 +++---- src/ast/ExternAST.cpp | 6 ++---- src/ast/PrototypeAST.cpp | 9 +++++---- src/ast/TypeAST.cpp | 7 +++---- src/ast/VariableDefExprAST.cpp | 3 +-- src/preprocessor.cpp | 17 ++++++----------- src/preprocessor.h | 3 ++- 13 files changed, 66 insertions(+), 53 deletions(-) create mode 100644 src/TokenSource.h diff --git a/src/CompileError.hpp b/src/CompileError.hpp index 5e3da65..1444486 100644 --- a/src/CompileError.hpp +++ b/src/CompileError.hpp @@ -1,6 +1,7 @@ // compileerror.hpp header for CompileError exeption class #ifndef _COMPILE_ERROR_ #define _COMPILE_ERROR_ +#include "TokenSource.h" #include #include @@ -9,26 +10,26 @@ class CompileError : public std::exception private: std::string error; std::string message; - std::string file; - uint64_t line; + TokenSource source; public: const char *what() const throw() { return message.c_str(); } - CompileError(const char *whatError, std::string whatFile = "", - uint64_t whatLine = 0) + CompileError(const char *whatError, + TokenSource source = TokenSource("", 0)) { - error = whatError; - file = whatFile; - line = whatLine; - message = file + ":" + std::to_string(line) + ": " + error; + error = whatError; + this->source = source; + message = + source.file + ":" + std::to_string(source.lineno) + ": " + error; } - CompileError(const std::string &whatError, std::string whatFile = "", - uint64_t whatLine = 0) + + CompileError(const std::string &whatError, + TokenSource source = TokenSource("", 0)) { - error = whatError; - file = whatFile; - line = whatLine; - message = file + ":" + std::to_string(line) + ": " + error; + error = whatError; + this->source = source; + message = + source.file + ":" + std::to_string(source.lineno) + ": " + error; } }; #endif diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index a79837a..55397fb 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -165,8 +165,7 @@ void scanToken(CompileUnit *unit) while (1) { int tokenid = lexer->yylex(); token.type = TokenType(tokenid); - token.file = line.first.first; - token.lineno = line.first.second; + token.source = line.first; token.tokenValue = lexer->YYText(); // Deal with numbers if (token.type == tok_number) { diff --git a/src/Token.cpp b/src/Token.cpp index bc963b8..6433a85 100644 --- a/src/Token.cpp +++ b/src/Token.cpp @@ -13,7 +13,6 @@ Token::Token() { tokenValue = ""; type = tok_err; - lineno = 0; } Token::~Token() @@ -99,8 +98,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 + ss << std::right << std::setw(25) << source.file << ":" << std::left + << std::setw(6) << source.lineno << " type:" << std::setw(16) << typeStr << " data:" << tokenValue; return ss.str(); } diff --git a/src/Token.h b/src/Token.h index 2958942..55d720a 100644 --- a/src/Token.h +++ b/src/Token.h @@ -8,6 +8,7 @@ #ifndef COMPILER_TOKEN_H_ #define COMPILER_TOKEN_H_ +#include "TokenSource.h" #include enum TokenType { @@ -45,8 +46,7 @@ class Token std::string dump(); TokenType type; std::string tokenValue; - uint64_t lineno; - std::string file; + TokenSource source; }; #endif /* COMPILER_TOKEN_H_ */ diff --git a/src/TokenSource.h b/src/TokenSource.h new file mode 100644 index 0000000..af8d81a --- /dev/null +++ b/src/TokenSource.h @@ -0,0 +1,22 @@ +/* + * TokenSource.h + * + * Created on: Mar 10, 2021 + * Author: zbc + */ + +#ifndef SRC_TOKENSOURCE_H_ +#define SRC_TOKENSOURCE_H_ + +#include + +struct TokenSource { + std::string file; + uint64_t lineno; + TokenSource(std::string file, uint64_t lineno) : file(file), lineno(lineno) + { + } + TokenSource() : file(""), lineno(0) {} +}; + +#endif /* SRC_TOKENSOURCE_H_ */ diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index 39b7636..d3ded02 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -35,7 +35,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.source); throw e; } std::string className = token.tokenValue; @@ -55,7 +55,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.source); throw e; } diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index e6a7d22..371bf5d 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -223,8 +223,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, break; } default: { - CompileError e("不期待的token:" + token.dump(), token.file, - token.lineno); + CompileError e("不期待的token:" + token.dump(), token.source); throw e; } } @@ -319,8 +318,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() + "\" 前", token.file, - token.lineno); + CompileError e("丟失分号: \"" + token.dump() + "\" 前", + token.source); throw e; } unit->next_tok(); diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp index b0fe708..0985aa4 100644 --- a/src/ast/ExternAST.cpp +++ b/src/ast/ExternAST.cpp @@ -30,8 +30,7 @@ ExternAST *ExternAST::ParseExtern(CompileUnit *unit) } else if (flag.tokenValue == "C") { C = true; } else { - CompileError e("Unknown flag:" + flag.tokenValue, flag.file, - flag.lineno); + CompileError e("Unknown flag:" + flag.tokenValue, flag.source); throw e; } } @@ -45,8 +44,7 @@ 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() + "\" 前", token.file, - token.lineno); + CompileError e("丟失分号: \"" + token.dump() + "\" 前", token.source); throw e; } token = unit->next_tok(); diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index 8037132..fcb3c30 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -103,19 +103,20 @@ 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.source); throw e; } } if (token.tokenValue == ";") { if (hasBody) { - CompileError e("Unexpected ;", token.file, token.lineno); + CompileError e("Unexpected ;", token.source); throw e; } } } - return new PrototypeAST(unit, FnName, args, returnTypes, parentClass); + PrototypeAST *retV = + new PrototypeAST(unit, FnName, args, returnTypes, parentClass); + return retV; } llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index 71ab241..c794e6e 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -63,8 +63,7 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit, ClassAST *inClass) { 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.source); throw e; } std::string baseClass = token.tokenValue; @@ -83,8 +82,8 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit, ClassAST *inClass) } else if (token.tokenValue == ">") { break; } else { - CompileError e("Unknown token " + token.dump(), token.file, - token.lineno); + CompileError e("Unknown token " + token.dump(), + token.source); throw e; } } diff --git a/src/ast/VariableDefExprAST.cpp b/src/ast/VariableDefExprAST.cpp index ca44b98..dce4a5b 100644 --- a/src/ast/VariableDefExprAST.cpp +++ b/src/ast/VariableDefExprAST.cpp @@ -120,8 +120,7 @@ VariableDefExprAST *VariableDefExprAST::ParseVar(CompileUnit * unit, unit->next_tok(); initValue = ExprAST::ParseExpression(unit, codeblock, false); } else { - CompileError e("Unknown token:" + nexToken.dump(), nexToken.file, - nexToken.lineno); + CompileError e("Unknown token:" + nexToken.dump(), nexToken.source); throw e; } } diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 084c13b..7c767ba 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -74,8 +74,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, data = instruction.second.substr(i + 1, len - i - 1); } variable[var] = data; - return std::vector{ - Tline(std::pair("", lineno), "")}; + return std::vector{Tline(TokenSource("", lineno), "")}; } else if (instruction.first == "rmdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -87,8 +86,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, throw e; //找不到宏定义 } - return std::vector{ - Tline(std::pair("", lineno), "")}; + return std::vector{Tline(TokenSource("", lineno), "")}; } else if (instruction.first == "ifdef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -101,8 +99,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, closeifstack++; } currentifstack++; - return std::vector{ - Tline(std::pair("", lineno), "")}; + return std::vector{Tline(TokenSource("", lineno), "")}; } else if (instruction.first == "ifndef") { if (instruction.second.length() == 0) { CompileError e("no second instruction"); @@ -115,8 +112,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, closeifstack++; } currentifstack++; - return std::vector{ - Tline(std::pair("", lineno), "")}; + return std::vector{Tline(TokenSource("", lineno), "")}; } else if (instruction.first == "endif") { if (currentifstack == 0) { CompileError e("no second instruction"); @@ -126,8 +122,7 @@ std::vector processPreInstruction(const std::string &line, int cnt, closeifstack--; } currentifstack--; - return std::vector{ - Tline(std::pair("", lineno), "")}; + return std::vector{Tline(TokenSource("", lineno), "")}; } else { CompileError e("Unrecognized preprocessor command"); throw e; @@ -233,7 +228,7 @@ std::vector preProcess(const std::string &code, int cnt, std::string FN) int plen = result.length(); if (plen > 0) { processedLines.push_back( - Tline(std::pair(FN, lineno), result)); + Tline(TokenSource(FN, lineno), result)); } } temp.erase(); diff --git a/src/preprocessor.h b/src/preprocessor.h index 35d15e0..2e6fcdb 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -1,6 +1,7 @@ #ifndef _PREPROCESSOR_ #define _PREPROCESSOR_ +#include "TokenSource.h" #include #include #include @@ -9,7 +10,7 @@ #include #include -typedef std::pair, std::string> Tline; +typedef std::pair Tline; std::vector preProcess(const std::string &code, int cnt, std::string FN); -- Gitee From 6de7f030ddc698e2c5015fb88fa5ee53e1099260 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:27:49 +0800 Subject: [PATCH 57/95] Add TokenSource --- src/CompileUnit.cpp | 2 +- src/ast/BaseAST.h | 2 +- src/ast/PrototypeAST.cpp | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 55397fb..c91d379 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -192,7 +192,7 @@ void scanToken(CompileUnit *unit) } // Debug token dump - // std::cout << tokenmbn.dump() << std::endl; + // std::cout << token.dump() << std::endl; if (token.type == tok_eof) break; unit->tokenList.push_back(token); diff --git a/src/ast/BaseAST.h b/src/ast/BaseAST.h index be45186..a333ab1 100644 --- a/src/ast/BaseAST.h +++ b/src/ast/BaseAST.h @@ -15,7 +15,7 @@ class BaseAST BaseAST(CompileUnit *unit); virtual ~BaseAST(); CompileUnit *unit; - Tline source; + TokenSource source; }; #endif /* COMPILER_AST_ASTBASE_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp index fcb3c30..d93bdf9 100644 --- a/src/ast/PrototypeAST.cpp +++ b/src/ast/PrototypeAST.cpp @@ -34,7 +34,8 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, ClassAST *parentClass) { std::vector> args; - Token token = unit->next_tok(); + Token token = unit->next_tok(); + TokenSource source = token.source; if (token.type != tok_identifier) { std::cerr << "error1" << std::endl; // TODO:异常处理 @@ -116,6 +117,7 @@ PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody, } PrototypeAST *retV = new PrototypeAST(unit, FnName, args, returnTypes, parentClass); + retV->source = source; return retV; } @@ -149,7 +151,9 @@ llvm::Function *PrototypeAST::Codegen(std::vector igenericTypes) llvm::Type *returnType; if (returnDirectly) { if (returnTypes.size() > 1) { - CompileError e("return more than one type:"); + CompileError e( + "Prototype with \"S\" flag returned more than one values.", + source); throw e; } else if (returnTypes.size() == 0) { returnType = llvm::Type::getVoidTy(*unit->context); -- Gitee From 4e5f2c66896c8acc8ade8e9735e02784cdd2ee70 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:36:04 +0800 Subject: [PATCH 58/95] Add source in TypeAST --- src/ast/TypeAST.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp index c794e6e..8cd2c26 100644 --- a/src/ast/TypeAST.cpp +++ b/src/ast/TypeAST.cpp @@ -43,7 +43,8 @@ llvm::Type *TypeAST::Codegen() //没有找到实例化过的泛型 auto classAST = unit->classes.find(realType->baseClass); if (classAST == unit->classes.end()) { - CompileError e("can't find class:" + realType->baseClass); + CompileError e("can't find class:" + realType->baseClass, + source); throw e; } else { llvm::Type *classType = @@ -61,7 +62,8 @@ llvm::Type *TypeAST::Codegen() TypeAST *TypeAST::ParseType(CompileUnit *unit, ClassAST *inClass) { - Token token = *unit->icurTok; + Token token = *unit->icurTok; + TokenSource source = token.source; if (token.type != tok_identifier) { CompileError e("Expected type but got " + token.dump(), token.source); throw e; @@ -91,6 +93,7 @@ TypeAST *TypeAST::ParseType(CompileUnit *unit, ClassAST *inClass) token = unit->next_tok(); } TypeAST *result = new TypeAST(unit, baseClass, genericTypes, inClass); + result->source = source; while (token.type == tok_syntax && token.tokenValue == "*") { result = new TypeAST(unit, result); token = unit->next_tok(); -- Gitee From 522ca6b18955645e6352726b31ccac7d26c82559 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:39:17 +0800 Subject: [PATCH 59/95] Add source in ClassAST --- src/ast/ClassAST.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ast/ClassAST.cpp b/src/ast/ClassAST.cpp index d3ded02..a76be9e 100644 --- a/src/ast/ClassAST.cpp +++ b/src/ast/ClassAST.cpp @@ -33,9 +33,10 @@ ClassAST::~ClassAST() ClassAST *ClassAST::ParseClass(CompileUnit *unit) { - Token token = unit->next_tok(); + Token token = unit->next_tok(); + TokenSource source = token.source; if (token.type != tok_identifier) { - CompileError e("Expected identifier", token.source); + CompileError e("Expected identifier", source); throw e; } std::string className = token.tokenValue; @@ -55,13 +56,14 @@ ClassAST *ClassAST::ParseClass(CompileUnit *unit) token = unit->next_tok(); } if (token.type != tok_syntax || token.tokenValue != "{") { - CompileError e("Expected {", token.source); + CompileError e("Expected {", source); throw e; } ClassAST *classAST = new ClassAST(unit, className, std::vector(), std::vector(), genericTypes); + classAST->source = source; unit->next_tok(); while (true) { //解析成员方法,成员变量 @@ -146,7 +148,7 @@ std::string ClassAST::getRealNameForMangle(std::vector igenericTypes) llvm::Type *ClassAST::Codegen(std::vector igenericTypes) { if (igenericTypes.size() != genericTypes.size()) { - CompileError e("generic isn't equal"); + CompileError e("generic isn't equal", source); throw e; } this->igenericTypes = igenericTypes; -- Gitee From 41eaf9416fce61d1fd8da9e8a9a38d484acf2d41 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:42:49 +0800 Subject: [PATCH 60/95] Make error handler more friendly --- src/ast/ExprAST.cpp | 8 +++++--- src/ast/WhileExprAST.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 371bf5d..66b3fb3 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -123,7 +123,8 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, { ExprAST *result; // todo:除了函数调用之外的语句解析 - Token token = *unit->icurTok; + Token token = *unit->icurTok; + TokenSource source = token.source; switch (token.type) { case tok_number: { unit->next_tok(); @@ -159,7 +160,7 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, result = ParseExpression(unit, codeblock, false); token = *unit->icurTok; if (token.type != tok_syntax || token.tokenValue != ")") { - CompileError e("missing ')'"); + CompileError e("missing ')'", source); throw e; } unit->next_tok(); @@ -223,10 +224,11 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, break; } default: { - CompileError e("不期待的token:" + token.dump(), token.source); + CompileError e("不期待的token:" + token.dump(), source); throw e; } } + result->source = source; return result; } diff --git a/src/ast/WhileExprAST.cpp b/src/ast/WhileExprAST.cpp index 5ca4440..263a22c 100644 --- a/src/ast/WhileExprAST.cpp +++ b/src/ast/WhileExprAST.cpp @@ -39,7 +39,7 @@ std::vector WhileExprAST::Codegen(llvm::IRBuilder<> *builder) std::vector conditionValues = condition->CodegenChain(builder); if (conditionValues.size() != 1) { - CompileError e("Multi/Void type in condition found."); + CompileError e("Multi/Void type in condition found.", source); throw e; } builder->CreateCondBr(conditionValues[0], bodyBB, MergeBB); -- Gitee From 0188109659141ff01456ea9fc904b05c7aa6b402 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 21:54:55 +0800 Subject: [PATCH 61/95] Add sources for CompileError in MemberExprAST --- src/ast/ExprAST.cpp | 10 ++++++---- src/ast/MemberExprAST.cpp | 15 ++++++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 66b3fb3..410c89f 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -272,12 +272,14 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, LHS->appendSubExpr(RHS); } else if (token.tokenValue == ".") { if (VariableExprAST *v = dynamic_cast(RHS)) { - LHS = new MemberExprAST(unit, LHS, v->idName, false); + LHS = new MemberExprAST(unit, LHS, v->idName, false); + LHS->source = token.source; } else if (CallExprAST *v = dynamic_cast(RHS)) { - v->LHS = LHS; - LHS = v; + v->LHS = LHS; + LHS = v; + LHS->source = token.source; } else { - CompileError e("未知的操作"); + CompileError e("未知的操作", token.source); throw e; } } else if (token.tokenValue == "->") { diff --git a/src/ast/MemberExprAST.cpp b/src/ast/MemberExprAST.cpp index 57b6c90..3727380 100644 --- a/src/ast/MemberExprAST.cpp +++ b/src/ast/MemberExprAST.cpp @@ -33,7 +33,7 @@ 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."); + CompileError e("Multi/Void type found.", source); throw e; } @@ -55,7 +55,7 @@ std::vector MemberExprAST::Codegen(llvm::IRBuilder<> *builder) } } if (!foundFlag) { - CompileError e("Member " + this->member + " not found."); + CompileError e("Member " + this->member + " not found.", source); throw e; } @@ -92,12 +92,12 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) chain.push_back(v->operand); break; } else { - CompileError e("Unknown AST."); + CompileError e("Unknown AST.", source); throw e; } break; } else { - CompileError e("Unknown AST."); + CompileError e("Unknown AST.", source); throw e; } } @@ -112,7 +112,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) dynamic_cast(chain[chain.size() - 1]); pointer = start->getAlloca(builder); if (pointer == nullptr) { - CompileError e("No memory allocaed"); + CompileError e("No memory allocaed", source); throw e; } curType = start->type[0]; @@ -124,7 +124,8 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) std::string cmember = v->member; ClassAST * baseClass = unit->classes[curType->baseClass]; if (baseClass == nullptr) { - CompileError e("Class " + curType->baseClass + " not found."); + CompileError e("Class " + curType->baseClass + " not found.", + source); throw e; } unsigned int index = 0; @@ -136,7 +137,7 @@ llvm::Value *MemberExprAST::getAlloca(llvm::IRBuilder<> *builder) } } if (!foundFlag) { - CompileError e("Member " + cmember + " not found."); + CompileError e("Member " + cmember + " not found.", source); throw e; } idx.push_back(index); -- Gitee From 6250f46b5efa1f9e0ceb9d2bfead41fa3b534fd8 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 10 Mar 2021 22:00:20 +0800 Subject: [PATCH 62/95] Add sources --- src/ast/BinaryExprAST.cpp | 9 +++++---- src/ast/ExprAST.cpp | 12 ++++++------ src/ast/UnaryExprAST.cpp | 11 ++++++----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp index 67be1e2..a0a55c2 100644 --- a/src/ast/BinaryExprAST.cpp +++ b/src/ast/BinaryExprAST.cpp @@ -104,7 +104,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) curExpr = curExpr->subExpr; } if (RHSV.size() != LHS.size()) { - CompileError e("the length of expression isn't equal."); + CompileError e("the length of expression isn't equal.", source); throw e; } for (unsigned int i = 0; i < LHS.size(); i++) { @@ -116,7 +116,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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"); + CompileError e("Bin Expr length != 1", source); throw e; } std::string LHStype = LHS->type[0]->getName(); @@ -124,7 +124,8 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) auto operate = unit->binOperators.find({LHStype, RHStype, binOP}); if (operate == unit->binOperators.end()) { CompileError e("Unknown operator " + binOP + "with type " + - LHStype + " and " + RHStype); + LHStype + " and " + RHStype, + source); throw e; } this->type.push_back(operate->second.second); @@ -133,7 +134,7 @@ std::vector BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) result.push_back(processInnerBinaryOperator(L[0], R[0], builder)); } else { //用户定义运算符 - CompileError e("User-def operator not implemented"); + CompileError e("User-def operator not implemented", source); throw e; } } diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp index 410c89f..f8d50a8 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -272,12 +272,10 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, LHS->appendSubExpr(RHS); } else if (token.tokenValue == ".") { if (VariableExprAST *v = dynamic_cast(RHS)) { - LHS = new MemberExprAST(unit, LHS, v->idName, false); - LHS->source = token.source; + LHS = new MemberExprAST(unit, LHS, v->idName, false); } else if (CallExprAST *v = dynamic_cast(RHS)) { - v->LHS = LHS; - LHS = v; - LHS->source = token.source; + v->LHS = LHS; + LHS = v; } else { CompileError e("未知的操作", token.source); throw e; @@ -290,7 +288,7 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, v->Lpointer = true; LHS = v; } else { - CompileError e("未知的操作"); + CompileError e("未知的操作", token.source); throw e; } } else if (dynamic_cast(LHS) != nullptr && @@ -301,9 +299,11 @@ static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, GetRUnaryTokPrecedence(token) != -1) { //右一元运算符 LHS = new UnaryExprAST(unit, token.tokenValue, LHS, false); + } else { LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); } + LHS->source = token.source; } } diff --git a/src/ast/UnaryExprAST.cpp b/src/ast/UnaryExprAST.cpp index 958fd66..8285c43 100644 --- a/src/ast/UnaryExprAST.cpp +++ b/src/ast/UnaryExprAST.cpp @@ -41,7 +41,8 @@ llvm::Value *UnaryExprAST::getAlloca(llvm::IRBuilder<> *builder) type.push_back(operand->type[0]->pointee); return ret; } else { - CompileError e("Operator " + op + " can not be used as assignment"); + CompileError e("Operator " + op + " can not be used as assignment", + source); throw e; } } @@ -53,7 +54,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) if (op == "&") { llvm::Value *pointer = operand->getAlloca(builder); if (pointer == nullptr) { - CompileError e("No memory allocaed"); + CompileError e("No memory allocaed", source); throw e; } type.push_back(new TypeAST(unit, operand->type[0])); @@ -62,7 +63,7 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) //值操作 std::vector Rs = operand->CodegenChain(builder); if (Rs.size() != 1) { - CompileError e("Unary Expr length != 1"); + CompileError e("Unary Expr length != 1", source); throw e; } @@ -71,13 +72,13 @@ std::vector UnaryExprAST::Codegen(llvm::IRBuilder<> *builder) 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"); + CompileError e("operator * must be used on pointer", source); throw e; } this->type.push_back(operand->type[0]->pointee); result.push_back(builder->CreateLoad(Rs[0])); } else { - CompileError e("一元运算符:" + op + "未实现"); + CompileError e("一元运算符:" + op + "未实现", source); throw e; } } -- Gitee From 502f30f47a58a98fe918ea55edf0a4a68fd99e26 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 14 Mar 2021 09:42:20 +0800 Subject: [PATCH 63/95] Implement char --- src/CompileUnit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index c91d379..4369141 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -33,6 +33,8 @@ void initInnerType(CompileUnit *unit) "double", llvm::Type::getDoubleTy(*unit->context))); unit->types.insert(std::pair( "bool", llvm::Type::getInt1Ty(*unit->context))); + unit->types.insert(std::pair( + "char", llvm::Type::getInt32Ty(*unit->context))); } void initInnerOperations(CompileUnit *unit) -- Gitee From 61e49a1e5060e5139b3c2c904db8d924c090e2bc Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sun, 14 Mar 2021 14:54:23 +0800 Subject: [PATCH 64/95] added ucs4-utf8 support --- src/lib/usc4support.cpp | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/lib/usc4support.cpp diff --git a/src/lib/usc4support.cpp b/src/lib/usc4support.cpp new file mode 100644 index 0000000..ad5f139 --- /dev/null +++ b/src/lib/usc4support.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +typedef char32_t mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 +typedef std::basic_string mfstring; // 自定义的UCS-4字符串 + +// 把utf-8编码的字符串转换成UCS-4编码的字符串 +void UTF8ToUCS4(const std::string &src, mfstring &dest) +{ + mfchar_t w = 0; + mfchar_t err = '?'; // 表转码错误 + int bytes = 0; // 表剩余要处理的字节数 + + for (size_t i = 0; i < src.length(); i++) { + unsigned char c = (unsigned char)src[i]; + + if (c <= 0x7f) // <= 0x0111 1111(即127)的说明是ascii码 + { + // 若bytes不为0,说明出错,因为ascii码的utf-8编码只占一个字节 + if (bytes) { + dest.push_back(err); + bytes = 0; + } + + // 将字符压入队列 + dest.push_back((mfchar_t)c); + } else if (c <= 0xbf) // <= 0x1011 + // 1111,说明是多字节的utf-8编码的第2,3,4,5,6字节 + { + // 既然是2,3,4,5,6字节,bytes必不为0,否则出错 + if (bytes) { + // 取出c的后六位,将w左移6位,做或预算,赋值给w,这样w就融合了c的后6位 + w = ((w << 6) | (c & 0x3f)); + + // 字节数减1,因为本字节已经融合完毕 + bytes--; + + // 若后面没有字节数了,说明字节数融合完毕,成为一个完整的ucs-4的字符了,压入队列 + if (bytes == 0) { + dest.push_back(w); + } + } else { + dest.push_back(err); // 出错 + } + } else if (c <= + 0xdf) // <= 0x1101 1111,说明是2字节的utf-8编码的第一个字节 + { + bytes = 1; // 标记后面还有1个字节,下面类似 + w = c & + 0x1f; // 取出后5位,注意是赋值操作,所以w的高位都将赋值为0。然后将 + // w 与后面字节的后六位融合即可,下面类似 + } else if (c <= + 0xef) // <= 0x1110 1111,说明是3字节的utf-8编码的第一个字节 + { + bytes = 2; + w = c & 0x0f; // 取出后4位 + } else if (c <= + 0xf7) // <= 0x1111 0111,说明是4字节的utf-8编码的第一个字节 + { + bytes = 3; + w = c & 0x07; // 取出后3位 + } else if (c <= + 0xfb) // <= 0x1111 1011,说明是5字节的utf-8编码的第一个字节 + { + bytes = 4; + w = c & 0x03; // 取出后2位 + } else if (c <= + 0xfd) // <= 0x1111 1101,说明是6字节的utf-8编码的第一个字节 + { + bytes = 5; + w = c & 0x01; // 取出后1位 + } else // > 0x1111 1101的是出错,因utf-8最多6个字节 + { + dest.push_back(err); + bytes = 0; + } + } + + if (bytes) { + dest.push_back(err); + } +} + +void UCS4ToUTF8(const mfstring &src, std::string &dest) +{ + char out[MB_LEN_MAX]; + std::mbstate_t state{}; + for (char32_t c : src) { + std::size_t rc = std::c32rtomb(out, c, &state); + if (rc != (std::size_t)-1) + for (char c8 : std::string_view{out, rc}) + dest.push_back(c8); + } +} \ No newline at end of file -- Gitee From d563fefeaa5941422fd76c1dfca535cfe78cef54 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Sun, 14 Mar 2021 14:55:06 +0800 Subject: [PATCH 65/95] . --- src/lib/usc4support.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/usc4support.cpp b/src/lib/usc4support.cpp index ad5f139..ee98df9 100644 --- a/src/lib/usc4support.cpp +++ b/src/lib/usc4support.cpp @@ -94,4 +94,6 @@ void UCS4ToUTF8(const mfstring &src, std::string &dest) for (char c8 : std::string_view{out, rc}) dest.push_back(c8); } -} \ No newline at end of file +} + +//TODO: Support for other chatsets \ No newline at end of file -- Gitee From 92dc9d168628412020d179d6e7b3018b0c2f3709 Mon Sep 17 00:00:00 2001 From: zyb Date: Sun, 14 Mar 2021 15:09:50 +0800 Subject: [PATCH 66/95] string --- src/lib/string.alo | 8 ++++++++ test/perfcheck/demo.py | 10 +++++----- tools/demangle | Bin 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 src/lib/string.alo mode change 100755 => 100644 test/perfcheck/demo.py mode change 100755 => 100644 tools/demangle diff --git a/src/lib/string.alo b/src/lib/string.alo new file mode 100644 index 0000000..c4090ac --- /dev/null +++ b/src/lib/string.alo @@ -0,0 +1,8 @@ +%import array.alo + +class string +{ + //private: + array data; +}; + diff --git a/test/perfcheck/demo.py b/test/perfcheck/demo.py old mode 100755 new mode 100644 index 05a4589..819afe8 --- a/test/perfcheck/demo.py +++ b/test/perfcheck/demo.py @@ -1,6 +1,6 @@ -#!/usr/bin/python - -a = 0 -while a < 100000000: - a = a + 1 +#!/usr/bin/python + +a = 0 +while a < 100000000: + a = a + 1 print(a) \ No newline at end of file diff --git a/tools/demangle b/tools/demangle old mode 100755 new mode 100644 -- Gitee From f4b24d1be2ac7bac91153a72b276c91d6ed77363 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 14 Mar 2021 16:56:59 +0800 Subject: [PATCH 67/95] Fix the format issue of string --- src/CompileUnit.cpp | 3 ++- src/lib/string.alo | 15 +++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 4369141..0ed23a1 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -268,7 +268,8 @@ void CompileUnit::compile() break; } default: { - CompileError e("unexpected token:" + icurTok->dump()); + CompileError e("unexpected token:" + icurTok->dump(), + icurTok->source); throw e; } } diff --git a/src/lib/string.alo b/src/lib/string.alo index c4090ac..14057a6 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -1,8 +1,7 @@ -%import array.alo - -class string -{ - //private: - array data; -}; - +%import array.alo + +class string +{ + //private: + array data; +} \ No newline at end of file -- Gitee From 0780974b14cdab76f9466bf58c2b153bd39f8404 Mon Sep 17 00:00:00 2001 From: uebian Date: Sun, 14 Mar 2021 17:03:51 +0800 Subject: [PATCH 68/95] Add StringExprAST --- src/Makefile.am | 2 +- src/ast/ExprAST.cpp | 8 ++++++++ src/ast/StringExprAST.cpp | 32 ++++++++++++++++++++++++++++++++ src/ast/StringExprAST.h | 21 +++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/ast/StringExprAST.cpp create mode 100644 src/ast/StringExprAST.h diff --git a/src/Makefile.am b/src/Makefile.am index 40e15c2..7205c36 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ aloc_SOURCES = aloc.cpp CompileUnit.cpp preprocessor.cpp Token.cpp utils.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/SizeofExprAST.cpp ast/TypeAST.cpp ast/VariableDefExprAST.cpp ast/VariableExprAST.cpp\ + ast/ReturnExprAST.cpp ast/SizeofExprAST.cpp ast/StringExprAST.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/ExprAST.cpp b/src/ast/ExprAST.cpp index f8d50a8..6dd3a50 100644 --- a/src/ast/ExprAST.cpp +++ b/src/ast/ExprAST.cpp @@ -13,6 +13,7 @@ #include "MemberExprAST.h" #include "ReturnExprAST.h" #include "SizeofExprAST.h" +#include "StringExprAST.h" #include "UnaryExprAST.h" #include "VariableDefExprAST.h" #include "VariableExprAST.h" @@ -223,6 +224,13 @@ ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock, result = new SizeofExprAST(unit, type); break; } + case tok_str: { + //字符串字面值 + result = new StringExprAST(unit, token.tokenValue); + result->source = token.source; + unit->next_tok(); + break; + } default: { CompileError e("不期待的token:" + token.dump(), source); throw e; diff --git a/src/ast/StringExprAST.cpp b/src/ast/StringExprAST.cpp new file mode 100644 index 0000000..99c8563 --- /dev/null +++ b/src/ast/StringExprAST.cpp @@ -0,0 +1,32 @@ +/* + * StringExprAST.cpp + * + * Created on: Mar 14, 2021 + * Author: zbc + */ + +#include "StringExprAST.h" +#include "../CompileError.hpp" +#include "TypeAST.h" + +StringExprAST::StringExprAST(CompileUnit *unit, const std::string &str) + : ExprAST(unit) +{ + // TODO Auto-generated constructor stub +} + +StringExprAST::~StringExprAST() +{ + // TODO Auto-generated destructor stub +} + +std::vector StringExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + type.clear(); + this->type.push_back(new TypeAST(unit, "string")); + std::vector result; + CompileError e("字符串字面值未实现", source); + throw e; + // result.push_back(res); + return result; +} diff --git a/src/ast/StringExprAST.h b/src/ast/StringExprAST.h new file mode 100644 index 0000000..cca9a12 --- /dev/null +++ b/src/ast/StringExprAST.h @@ -0,0 +1,21 @@ +/* + * StringExprAST.h + * + * Created on: Mar 14, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_STRINGEXPRAST_H_ +#define SRC_AST_STRINGEXPRAST_H_ + +#include "ExprAST.h" + +class StringExprAST : public ExprAST +{ + public: + StringExprAST(CompileUnit *unit, const std::string &str); + virtual ~StringExprAST(); + std::vector Codegen(llvm::IRBuilder<> *builder); +}; + +#endif /* SRC_AST_STRINGEXPRAST_H_ */ -- Gitee From 767a3cd4612c194216ffc77de0c744b15aefa1a5 Mon Sep 17 00:00:00 2001 From: zyb Date: Mon, 15 Mar 2021 11:35:22 +0800 Subject: [PATCH 69/95] proto --- src/lib/1.proto | 12 ++++++++++++ src/lib/string.alo | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/lib/1.proto diff --git a/src/lib/1.proto b/src/lib/1.proto new file mode 100644 index 0000000..88d00da --- /dev/null +++ b/src/lib/1.proto @@ -0,0 +1,12 @@ +message msg +{ + required int version=1; + required int length=2; + required int command=3; + message Data + { + int id=1; + bytes dat=2; + } + optional Data data=4; +} \ No newline at end of file diff --git a/src/lib/string.alo b/src/lib/string.alo index c4090ac..cc103ca 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -2,7 +2,11 @@ class string { - //private: array data; }; +//要重构成+ +func strcat(string str1,string str2) ->string +{ + string +} \ No newline at end of file -- Gitee From 9d9e4fbdeb3579a5ce7a8a32bba9ca30f2e8fa15 Mon Sep 17 00:00:00 2001 From: zyb Date: Mon, 15 Mar 2021 11:36:07 +0800 Subject: [PATCH 70/95] =?UTF-8?q?=E5=86=99=E9=94=99=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/string.alo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/string.alo b/src/lib/string.alo index cc103ca..6902a47 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -8,5 +8,5 @@ class string //要重构成+ func strcat(string str1,string str2) ->string { - string +// string } \ No newline at end of file -- Gitee From c742d0675694927d5e148b989a50eda413e00bd4 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Mon, 15 Mar 2021 13:00:50 +0800 Subject: [PATCH 71/95] bumped C++ std to C++17 --- .gitignore | 2 + config.h.in~ | 6 + configure.ac | 3 + m4/ax_cxx_compile_stdcxx.m4 | 962 ++++++++++++++++++++++++++++++++++++ 4 files changed, 973 insertions(+) create mode 100644 m4/ax_cxx_compile_stdcxx.m4 diff --git a/.gitignore b/.gitignore index 69e119b..98b4e68 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,5 @@ Makefile *.bc *.s src/yacc_stuff/tokenizer.cpp +config.guess~ +config.sub~ diff --git a/config.h.in~ b/config.h.in~ index e2993a5..29f179e 100644 --- a/config.h.in~ +++ b/config.h.in~ @@ -51,6 +51,9 @@ /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL +/* Name of package */ +#undef PACKAGE + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -74,6 +77,9 @@ backward compatibility; new code need not use it. */ #undef STDC_HEADERS +/* Version number of package */ +#undef VERSION + /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER diff --git a/configure.ac b/configure.ac index 3b4eb5d..f64a4ee 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. +AC_CONFIG_MACRO_DIR([m4]) AC_PREREQ([2.69]) AC_INIT([AloLang Compiler], [Dev Beta], [https://github.com/XJTU-Youth/AloLang-Dev/issues]) @@ -49,5 +50,7 @@ AC_CONFIG_FILES([ src/lib/Makefile ]) +AX_CXX_COMPILE_STDCXX(17, [noext], [mandatory]) + AM_INIT_AUTOMAKE AC_OUTPUT diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..db7638c --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,962 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) \ No newline at end of file -- Gitee From bdaeecd86a972a54b0b8d3c24c9b8c61ed76821b Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 16 Mar 2021 12:47:14 +0800 Subject: [PATCH 72/95] Fix bugs in string.alo --- src/lib/Makefile.am | 4 ++-- src/lib/string.alo | 24 ++++++++++++------------ src/preprocessor.cpp | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index bcae18a..102516d 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,8 +1,8 @@ AUTOMAKE_OPTIONS = foreign lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c +libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c usc4support.cpp alolanglibdir=$(libdir) alolanglib_PROGRAMS = libalolangcore.so -libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c +libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c usc4support.cpp libalolangcore_so_LDFLAGS = -shared -fpic diff --git a/src/lib/string.alo b/src/lib/string.alo index 269d2ee..7f4a58f 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -1,13 +1,13 @@ -%import array.alo - -class string -{ - //private: - array data; -}; - -//要重构成+ -func strcat(string str1,string str2) ->string -{ -// string +%import array.alo + +class string +{ + //private: + array data; +} + +//要重构成+ +func strcat(string str1,string str2) ->string +{ +// string } \ No newline at end of file diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 7c767ba..b6b2355 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -45,7 +45,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, curFile.parent_path().string() + "/" + instruction.second; t_fin__.open(realPath); if (!t_fin__.is_open()) { - CompileError e("import file " + realPath + " not found"); + CompileError e("import file " + realPath + " not found", + TokenSource(FN, lineno)); throw e; } std::string importFileContent; -- Gitee From 3dd19c90525055c5a8ec68e8b494ed6f078fe170 Mon Sep 17 00:00:00 2001 From: uebian Date: Tue, 16 Mar 2021 20:08:25 +0800 Subject: [PATCH 73/95] Rebuild usc4support --- src/lib/usc4support.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/lib/usc4support.cpp b/src/lib/usc4support.cpp index ee98df9..b744f61 100644 --- a/src/lib/usc4support.cpp +++ b/src/lib/usc4support.cpp @@ -4,15 +4,16 @@ #include #include -typedef char32_t mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 +typedef int mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 typedef std::basic_string mfstring; // 自定义的UCS-4字符串 // 把utf-8编码的字符串转换成UCS-4编码的字符串 -void UTF8ToUCS4(const std::string &src, mfstring &dest) +unsigned int UTF8ToUCS4(const std::string &src, mfchar_t *dest) { - mfchar_t w = 0; - mfchar_t err = '?'; // 表转码错误 - int bytes = 0; // 表剩余要处理的字节数 + mfchar_t w = 0; + mfchar_t err = '?'; // 表转码错误 + int bytes = 0; // 表剩余要处理的字节数 + unsigned int curIndex = 0; for (size_t i = 0; i < src.length(); i++) { unsigned char c = (unsigned char)src[i]; @@ -21,12 +22,12 @@ void UTF8ToUCS4(const std::string &src, mfstring &dest) { // 若bytes不为0,说明出错,因为ascii码的utf-8编码只占一个字节 if (bytes) { - dest.push_back(err); - bytes = 0; + dest[curIndex++] = err; + bytes = 0; } // 将字符压入队列 - dest.push_back((mfchar_t)c); + dest[curIndex++] = c; } else if (c <= 0xbf) // <= 0x1011 // 1111,说明是多字节的utf-8编码的第2,3,4,5,6字节 { @@ -40,10 +41,10 @@ void UTF8ToUCS4(const std::string &src, mfstring &dest) // 若后面没有字节数了,说明字节数融合完毕,成为一个完整的ucs-4的字符了,压入队列 if (bytes == 0) { - dest.push_back(w); + dest[curIndex++] = w; } } else { - dest.push_back(err); // 出错 + dest[curIndex++] = err; // 出错 } } else if (c <= 0xdf) // <= 0x1101 1111,说明是2字节的utf-8编码的第一个字节 @@ -74,14 +75,15 @@ void UTF8ToUCS4(const std::string &src, mfstring &dest) w = c & 0x01; // 取出后1位 } else // > 0x1111 1101的是出错,因utf-8最多6个字节 { - dest.push_back(err); - bytes = 0; + dest[curIndex++] = err; + bytes = 0; } } if (bytes) { - dest.push_back(err); + dest[curIndex++] = err; } + return curIndex; } void UCS4ToUTF8(const mfstring &src, std::string &dest) @@ -96,4 +98,4 @@ void UCS4ToUTF8(const mfstring &src, std::string &dest) } } -//TODO: Support for other chatsets \ No newline at end of file +// TODO: Support for other chatsets -- Gitee From 9244b45e076f40e5d5810cdb02e61f915acdaef0 Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 17 Mar 2021 00:29:21 +0800 Subject: [PATCH 74/95] Add some code related to the implementation of string --- src/ast/StringExprAST.cpp | 41 ++++++++++++++++++++++++++++++++++++--- src/ast/StringExprAST.h | 1 + src/lib/string.alo | 10 ++++------ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/ast/StringExprAST.cpp b/src/ast/StringExprAST.cpp index 99c8563..5ef3f6b 100644 --- a/src/ast/StringExprAST.cpp +++ b/src/ast/StringExprAST.cpp @@ -7,12 +7,14 @@ #include "StringExprAST.h" #include "../CompileError.hpp" +#include "CallExprAST.h" +#include "IntExprAST.h" #include "TypeAST.h" StringExprAST::StringExprAST(CompileUnit *unit, const std::string &str) : ExprAST(unit) { - // TODO Auto-generated constructor stub + this->str = str; } StringExprAST::~StringExprAST() @@ -25,8 +27,41 @@ std::vector StringExprAST::Codegen(llvm::IRBuilder<> *builder) type.clear(); this->type.push_back(new TypeAST(unit, "string")); std::vector result; - CompileError e("字符串字面值未实现", source); + llvm::Constant * const_array_4 = + llvm::ConstantDataArray::getString(unit->module->getContext(), str); + llvm::Function *function = builder->GetInsertBlock()->getParent(); + + llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + + llvm::StructType *sType = + (llvm::StructType *)(new TypeAST(unit, "array"))->Codegen(); + llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); + std::string dname = + "_alolang_C5arrayE4initP5array4chare3inte"; // todo:硬编码 + llvm::Function *CalleeF = unit->module->getFunction(dname); + if (CalleeF == 0) { + CompileError e("Function " + dname + + " not found in LLVM IR when building string"); + throw e; + } + std::vector args; + args.push_back(alloca); + args.push_back((new IntExprAST(unit, str.length()))->Codegen(builder)[0]); + builder->CreateCall(CalleeF, args); + + dname = "_alolang_C5arrayE4initP5array4chare3inte"; // todo:硬编码 + CalleeF = unit->module->getFunction(dname); + if (CalleeF == 0) { + CompileError e("Function " + dname + + " not found in LLVM IR when building string"); + throw e; + } + args.clear(); + args.push_back(alloca); + args.push_back((new IntExprAST(unit, str.length()))->Codegen(builder)[0]); + llvm::Value *ret = builder->CreateCall(CalleeF, args); + CompileError e("字符串字面值未实现"); throw e; - // result.push_back(res); return result; } diff --git a/src/ast/StringExprAST.h b/src/ast/StringExprAST.h index cca9a12..cd6c295 100644 --- a/src/ast/StringExprAST.h +++ b/src/ast/StringExprAST.h @@ -16,6 +16,7 @@ class StringExprAST : public ExprAST StringExprAST(CompileUnit *unit, const std::string &str); virtual ~StringExprAST(); std::vector Codegen(llvm::IRBuilder<> *builder); + std::string str; }; #endif /* SRC_AST_STRINGEXPRAST_H_ */ diff --git a/src/lib/string.alo b/src/lib/string.alo index 7f4a58f..3a972c1 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -4,10 +4,8 @@ class string { //private: array data; -} - -//要重构成+ -func strcat(string str1,string str2) ->string -{ -// string + func length()->int + { + return this->data.size(); + } } \ No newline at end of file -- Gitee From 56412809d26f007b3cd972c59aa83c0277eded8b Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 17 Mar 2021 18:55:26 +0800 Subject: [PATCH 75/95] =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.h.in~ | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.h.in~ b/config.h.in~ index 29f179e..06b7023 100644 --- a/config.h.in~ +++ b/config.h.in~ @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* define if the compiler supports basic C++17 syntax */ +#undef HAVE_CXX17 + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -- Gitee From c18a1dae8222991158231514ddc861c6c89e2498 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 17 Mar 2021 19:48:21 +0800 Subject: [PATCH 76/95] Changed location and name for ipc code --- src/lib/{1.proto => ipc/ipc.proto} | 10 ++- src/lib/ipc/ipcpy/ipc_pb2.py | 139 +++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 4 deletions(-) rename src/lib/{1.proto => ipc/ipc.proto} (44%) create mode 100644 src/lib/ipc/ipcpy/ipc_pb2.py diff --git a/src/lib/1.proto b/src/lib/ipc/ipc.proto similarity index 44% rename from src/lib/1.proto rename to src/lib/ipc/ipc.proto index 404efd3..a2c46ed 100644 --- a/src/lib/1.proto +++ b/src/lib/ipc/ipc.proto @@ -1,11 +1,13 @@ +syntax = "proto3"; + message msg { - required int version=1; - required int length=2; - required int command=3; + int64 version=1; + int64 length=2; + int64 command=3; message Data { - int id=1; + int64 id=1; bytes dat=2; } repeated Data data=4; diff --git a/src/lib/ipc/ipcpy/ipc_pb2.py b/src/lib/ipc/ipcpy/ipc_pb2.py new file mode 100644 index 0000000..d4155c5 --- /dev/null +++ b/src/lib/ipc/ipcpy/ipc_pb2.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: ipc.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='ipc.proto', + package='', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\tipc.proto\"q\n\x03msg\x12\x0f\n\x07version\x18\x01 \x01(\x03\x12\x0e\n\x06length\x18\x02 \x01(\x03\x12\x0f\n\x07\x63ommand\x18\x03 \x01(\x03\x12\x17\n\x04\x64\x61ta\x18\x04 \x03(\x0b\x32\t.msg.Data\x1a\x1f\n\x04\x44\x61ta\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0b\n\x03\x64\x61t\x18\x02 \x01(\x0c\x62\x06proto3' +) + + + + +_MSG_DATA = _descriptor.Descriptor( + name='Data', + full_name='msg.Data', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='msg.Data.id', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='dat', full_name='msg.Data.dat', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=95, + serialized_end=126, +) + +_MSG = _descriptor.Descriptor( + name='msg', + full_name='msg', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='version', full_name='msg.version', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='length', full_name='msg.length', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='command', full_name='msg.command', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='data', full_name='msg.data', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_MSG_DATA, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=13, + serialized_end=126, +) + +_MSG_DATA.containing_type = _MSG +_MSG.fields_by_name['data'].message_type = _MSG_DATA +DESCRIPTOR.message_types_by_name['msg'] = _MSG +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +msg = _reflection.GeneratedProtocolMessageType('msg', (_message.Message,), { + + 'Data' : _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), { + 'DESCRIPTOR' : _MSG_DATA, + '__module__' : 'ipc_pb2' + # @@protoc_insertion_point(class_scope:msg.Data) + }) + , + 'DESCRIPTOR' : _MSG, + '__module__' : 'ipc_pb2' + # @@protoc_insertion_point(class_scope:msg) + }) +_sym_db.RegisterMessage(msg) +_sym_db.RegisterMessage(msg.Data) + + +# @@protoc_insertion_point(module_scope) -- Gitee From f26f072daa6b4477352ea0137c0f6e9f62bba682 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 17 Mar 2021 19:53:43 +0800 Subject: [PATCH 77/95] somethi g --- src/lib/ipc/ipc.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/ipc/ipc.proto b/src/lib/ipc/ipc.proto index a2c46ed..c3eaf32 100644 --- a/src/lib/ipc/ipc.proto +++ b/src/lib/ipc/ipc.proto @@ -3,7 +3,7 @@ syntax = "proto3"; message msg { int64 version=1; - int64 length=2; + int64 length=2; int64 command=3; message Data { -- Gitee From 767674c3b5a389a5a7cb6c3ec2168eaf8d24d3f4 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 17 Mar 2021 20:16:52 +0800 Subject: [PATCH 78/95] changed code format for ipc.proto --- src/lib/ipc/ipc.proto | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/ipc/ipc.proto b/src/lib/ipc/ipc.proto index c3eaf32..ed47844 100644 --- a/src/lib/ipc/ipc.proto +++ b/src/lib/ipc/ipc.proto @@ -2,13 +2,13 @@ syntax = "proto3"; message msg { - int64 version=1; - int64 length=2; - int64 command=3; + int64 version = 1; + int64 length = 2; + int64 command = 3; message Data { - int64 id=1; - bytes dat=2; + int64 id = 1; + bytes dat = 2; } - repeated Data data=4; + repeated Data data = 4; } \ No newline at end of file -- Gitee From 767d06411f4154849517afa6c2c4e29db8b4ab0d Mon Sep 17 00:00:00 2001 From: uebian Date: Wed, 17 Mar 2021 21:46:47 +0800 Subject: [PATCH 79/95] Implement string --- src/aloc.cpp | 9 +++-- src/ast/StringExprAST.cpp | 84 +++++++++++++++++++++++++++++---------- src/lib/usc4support.cpp | 9 +++++ 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/aloc.cpp b/src/aloc.cpp index d423169..478ce8a 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -126,10 +126,11 @@ int main(int argc, char *argv[]) for (std::string input_file_name : input_file_names) { objs += "./" + input_file_name + ".s "; } - std::string cmdline = - "gcc -O0" + objs + (vm.count("static") ? "-static " : "") + - " -fPIE -L " + alolanglibdir + " -l m -l alolangcore" + " -o " + - output_file_name; + std::string cmdline = "g++ -O0" + objs + + (vm.count("static") ? "-static " : "") + + " -fPIE -L " + alolanglibdir + + " -l m -l stdc++ -l alolangcore -std=c++17" + + " -o " + output_file_name; std::cout << "debug info:" << cmdline << std::endl; system(cmdline.c_str()); return 0; diff --git a/src/ast/StringExprAST.cpp b/src/ast/StringExprAST.cpp index 5ef3f6b..3ebd21e 100644 --- a/src/ast/StringExprAST.cpp +++ b/src/ast/StringExprAST.cpp @@ -25,19 +25,24 @@ StringExprAST::~StringExprAST() std::vector StringExprAST::Codegen(llvm::IRBuilder<> *builder) { type.clear(); - this->type.push_back(new TypeAST(unit, "string")); - std::vector result; - llvm::Constant * const_array_4 = - llvm::ConstantDataArray::getString(unit->module->getContext(), str); + + /*llvm::Constant * strArray = + llvm::ConstantDataArray::getString(unit->module->getContext(), str);*/ + llvm::Value *strArray = builder->CreateGlobalString(str); + llvm::Function *function = builder->GetInsertBlock()->getParent(); llvm::IRBuilder<> sBuilder(&function->getEntryBlock(), function->getEntryBlock().begin()); llvm::StructType *sType = - (llvm::StructType *)(new TypeAST(unit, "array"))->Codegen(); - llvm::AllocaInst *alloca = sBuilder.CreateAlloca(sType); - std::string dname = + (llvm::StructType *)TypeAST( + unit, "array", std::vector{new TypeAST(unit, "char")}) + .Codegen(); + llvm::AllocaInst *array_alloca = sBuilder.CreateAlloca(sType); + llvm::AllocaInst *result_alloca = + sBuilder.CreateAlloca(TypeAST(unit, "string").Codegen()); + std::string dname = "_alolang_C5arrayE4initP5array4chare3inte"; // todo:硬编码 llvm::Function *CalleeF = unit->module->getFunction(dname); if (CalleeF == 0) { @@ -46,22 +51,61 @@ std::vector StringExprAST::Codegen(llvm::IRBuilder<> *builder) throw e; } std::vector args; - args.push_back(alloca); + args.push_back(array_alloca); args.push_back((new IntExprAST(unit, str.length()))->Codegen(builder)[0]); builder->CreateCall(CalleeF, args); + llvm::IntegerType *itype = llvm::IntegerType::get(*unit->context, 32); + llvm::IntegerType *itype64 = llvm::IntegerType::get(*unit->context, 64); - dname = "_alolang_C5arrayE4initP5array4chare3inte"; // todo:硬编码 - CalleeF = unit->module->getFunction(dname); - if (CalleeF == 0) { - CompileError e("Function " + dname + - " not found in LLVM IR when building string"); - throw e; + std::vector genericTypes = std::vector(); + genericTypes.push_back(new TypeAST(unit, "char")); + llvm::Value *startPointer = builder->CreateLoad(builder->CreateGEP( + sType, array_alloca, + std::vector{llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 0, true)})); + llvm::Value *strValue = builder->CreateGEP( + llvm::ArrayType::get(llvm::IntegerType::get(*unit->context, 8), + str.length() + 1), + strArray, + std::vector{llvm::ConstantInt::get(itype64, 0, true), + llvm::ConstantInt::get(itype64, 0, true)}); + // llvm::Value *strValue = builder->CreateGlobalString(str); + dname = "__alolang_inner_load_string"; // todo:硬编码 + llvm::Function *CalleeF2 = unit->module->getFunction(dname); + if (CalleeF2 == nullptr) { + llvm::FunctionType *FT = llvm::FunctionType::get( + TypeAST(unit, "int").Codegen(), + std::vector{ + llvm::PointerType::get( + llvm::IntegerType::get(*unit->context, 8), 0), + llvm::IntegerType::get(*unit->context, 64)}, + false); + CalleeF2 = + llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, + "__alolang_inner_load_string", unit->module); } - args.clear(); - args.push_back(alloca); - args.push_back((new IntExprAST(unit, str.length()))->Codegen(builder)[0]); - llvm::Value *ret = builder->CreateCall(CalleeF, args); - CompileError e("字符串字面值未实现"); - throw e; + std::vector args2; + args2.push_back(strValue); + // args2.push_back(llvm::ConstantInt::get(itype64, 0, true)); + args2.push_back(startPointer); + llvm::Value *ret = builder->CreateCall(CalleeF2, args2); + builder->CreateStore( + ret, builder->CreateGEP(sType, array_alloca, + std::vector{ + llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 1, true)})); + //制作结果 + this->type.push_back(new TypeAST(unit, "string")); + // todo:待优化 + std::vector result; + builder->CreateStore( + builder->CreateLoad(array_alloca), + builder->CreateGEP(TypeAST(unit, "string").Codegen(), result_alloca, + std::vector{ + llvm::ConstantInt::get(itype, 0, true), + llvm::ConstantInt::get(itype, 0, true)})); + llvm::Value *resultValue = builder->CreateLoad(result_alloca); + result.push_back(resultValue); return result; } diff --git a/src/lib/usc4support.cpp b/src/lib/usc4support.cpp index b744f61..0bd20e7 100644 --- a/src/lib/usc4support.cpp +++ b/src/lib/usc4support.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -99,3 +100,11 @@ void UCS4ToUTF8(const mfstring &src, std::string &dest) } // TODO: Support for other chatsets + +// for alolang + +extern "C" long long __alolang_inner_load_string(char *str, long long addr) +{ + long long length = UTF8ToUCS4(std::string(str), (int *)addr); + return length; +} -- Gitee From 40091e8b845ae3e9228cf4d20074b27f5096b480 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Wed, 17 Mar 2021 23:38:37 +0800 Subject: [PATCH 80/95] Added support for generate protobuf for alolang user-defined type --- .vscode/settings.json | 8 +++++++- src/ipc_Stuff/genproto.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/ipc_Stuff/genproto.h | 11 +++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/ipc_Stuff/genproto.cpp create mode 100644 src/ipc_Stuff/genproto.h diff --git a/.vscode/settings.json b/.vscode/settings.json index b20dbbb..6a03129 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -79,6 +79,12 @@ "streambuf": "cpp", "thread": "cpp", "valarray": "cpp", - "variant": "cpp" + "variant": "cpp", + "compare": "cpp", + "concepts": "cpp", + "numbers": "cpp", + "ranges": "cpp", + "span": "cpp", + "stop_token": "cpp" } } \ No newline at end of file diff --git a/src/ipc_Stuff/genproto.cpp b/src/ipc_Stuff/genproto.cpp new file mode 100644 index 0000000..98cbef7 --- /dev/null +++ b/src/ipc_Stuff/genproto.cpp @@ -0,0 +1,36 @@ +#include "genproto.h" +#include +#include + +std::map alot_to_protot{{"int", "int64"}, + {"double", "double"}, + {"char", "int32"}, + {"byte", "int32"}, + {"pointer", "uint64"}}; + +proto::proto() +{ + this->protostr = ""; + this->protostr += + R"(syntax = "proto3"; + )"; +} + +void proto::addType(std::string typenamestr, + std::vector membertype) +{ + std::string typeMsg = ""; + typeMsg += (boost::format("message %1%\n") % typenamestr).str(); + typeMsg += "{\n"; + int li = 1; + for (auto mbs : membertype) { + auto tn = alot_to_protot.find(mbs) != alot_to_protot.end() + ? alot_to_protot[mbs] + : mbs; + typeMsg += + (boost::format(" %1% %2%_%3% = %3%;\n") % tn % mbs % li).str(); + li++; + } + typeMsg += "}\n"; + this->protostr += typeMsg += "\n"; +} \ No newline at end of file diff --git a/src/ipc_Stuff/genproto.h b/src/ipc_Stuff/genproto.h new file mode 100644 index 0000000..d6e9d51 --- /dev/null +++ b/src/ipc_Stuff/genproto.h @@ -0,0 +1,11 @@ +#include +#include + +class proto +{ + public: + std::string protostr; + void addType(std::string typenamestr, std::vector membertype); + inline std::string getProto() { return this->protostr; }; + proto(); +}; \ No newline at end of file -- Gitee From a81ce0b45f3a49ed4511d7bb0c868b150211c5b7 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 00:16:59 +0800 Subject: [PATCH 81/95] Fix lots of bugs --- src/CompileUnit.cpp | 27 +++++++++++++++++---------- src/CompileUnit.h | 6 ++---- src/aloc.cpp | 4 +++- src/ast/CallExprAST.cpp | 2 +- src/ast/CallExprAST.h | 1 + src/ast/ClassAST.h | 1 + src/ast/CodeBlockAST.h | 1 + src/lib/string.alo | 4 ++++ src/lib/testPuts.c | 18 ++++++++++++++++++ src/lib/testio.alo | 8 +++++++- src/lib/types.alo | 7 ++++++- src/lib/usc4support.cpp | 18 ++++++++++++++++-- src/preprocessor.cpp | 3 ++- 13 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp index 0ed23a1..2e78095 100644 --- a/src/CompileUnit.cpp +++ b/src/CompileUnit.cpp @@ -250,7 +250,7 @@ void CompileUnit::compile() } case tok_extern: { ExternAST *externast = ExternAST::ParseExtern(this); - externs.push_back(externast); + functions.push_back(externast); break; } case tok_identifier: { @@ -283,15 +283,22 @@ void CompileUnit::compile() v->Codegen(nullptr); //自动插入globalVariablesValue } std::map::iterator extern_iter; - for (ExternAST *v : externs) { - llvm::Function *f = v->Codegen(); - globalFunctions.insert( - std::pair>( - f->getName(), - std::pair(v->proto, f))); - } - for (FunctionAST *v : functions) { - llvm::Function *f = v->Codegen(); //自动插入globalFunctions + for (BaseAST *func : functions) { + if (ExternAST *v = dynamic_cast(func)) { + llvm::Function *f = v->Codegen(); + globalFunctions.insert( + std::pair>( + f->getName(), + std::pair(v->proto, f))); + + } else if (FunctionAST *v = dynamic_cast(func)) { + llvm::Function *f = v->Codegen(); //自动插入globalFunctions + + } else { + CompileError e("Unknown internal error."); + throw e; + } } build(); diff --git a/src/CompileUnit.h b/src/CompileUnit.h index 47b997b..b852f62 100644 --- a/src/CompileUnit.h +++ b/src/CompileUnit.h @@ -17,8 +17,7 @@ #include class TypeAST; -class FunctionAST; -class ExternAST; +class BaseAST; class VariableDefExprAST; class ClassAST; class PrototypeAST; @@ -39,8 +38,7 @@ class CompileUnit std::vector::iterator icurTok; std::map classes; std::vector globalVariables; - std::vector functions; - std::vector externs; + std::vector functions; //泛指function(包括extern) std::map, std::pair> binOperators; // LHS type,RHS type,binOP diff --git a/src/aloc.cpp b/src/aloc.cpp index 478ce8a..397ca5c 100644 --- a/src/aloc.cpp +++ b/src/aloc.cpp @@ -107,7 +107,9 @@ int main(int argc, char *argv[]) // buff = header + buff; try { preProcessed = preProcess(buff, 0, input_file_name); - // cout << preProcessed; + for (Tline line : preProcessed) { + std::cout << line.second << std::endl; + } // todo:这行代码写的极不规范,尽快修改 CompileUnit(input_file_name, preProcessed).compile(); system(("llc ./" + input_file_name + diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp index 49f173c..1cb1eed 100644 --- a/src/ast/CallExprAST.cpp +++ b/src/ast/CallExprAST.cpp @@ -110,7 +110,7 @@ std::vector CallExprAST::Codegen(llvm::IRBuilder<> *builder) } if (proto == nullptr) { - CompileError e("Function " + dname + " not found."); + CompileError e("Function " + dname + " not found.", source); throw e; } for (TypeAST *tAST : proto->returnTypes) { diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h index d708432..df93aa7 100644 --- a/src/ast/CallExprAST.h +++ b/src/ast/CallExprAST.h @@ -10,6 +10,7 @@ #include "ExprAST.h" +class FunctionAST; class CallExprAST : public ExprAST { public: diff --git a/src/ast/ClassAST.h b/src/ast/ClassAST.h index cfea558..91081d8 100644 --- a/src/ast/ClassAST.h +++ b/src/ast/ClassAST.h @@ -11,6 +11,7 @@ #include "BaseAST.h" #include "VariableDefExprAST.h" +class FunctionAST; class ClassAST : public BaseAST { public: diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h index 14f0985..12b8e7a 100644 --- a/src/ast/CodeBlockAST.h +++ b/src/ast/CodeBlockAST.h @@ -14,6 +14,7 @@ #include class VariableDefExprAST; +class FunctionAST; class CodeBlockAST : public BaseAST { public: diff --git a/src/lib/string.alo b/src/lib/string.alo index 3a972c1..3b49720 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -8,4 +8,8 @@ class string { return this->data.size(); } + func charAt(int index)->char + { + return *this->data.get(index); + } } \ No newline at end of file diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index fc6f802..4041612 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -1,9 +1,27 @@ #include +char *string2char(int *data, long long length); + extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } extern void _alolang_12testPrintInt3inte(long long a) { printf("%lld\n", a); } extern void _alolang_15testPrintDouble6doublee(double a) { printf("%lf\n", a); } +struct aloptr { + long long addr; +}; +struct aloarray_char { + struct aloptr pointer; + long long size; +}; +struct alostring { + struct aloarray_char data; +}; +extern void _alolang_15testPrintString6stringe(struct alostring str) +{ + char *rstr = string2char((int *)str.data.pointer.addr, str.data.size); + printf("%s\n", rstr); +}; + extern void _alolang_13testPrintBool4boole(int a) { if (a) { diff --git a/src/lib/testio.alo b/src/lib/testio.alo index ed7b6d1..ecbbf40 100644 --- a/src/lib/testio.alo +++ b/src/lib/testio.alo @@ -1,5 +1,11 @@ +%ifndef _TESTIO_ +%def _TESTIO_ + extern func testPrintInt(int i); extern func testPrintDouble(double f); extern func testPrintBool(bool b); +extern func testPrintString(string s); extern "S" func testGetInt() -> int; -extern "S" func testGetDouble() -> double; \ No newline at end of file +extern "S" func testGetDouble() -> double; + +%endif \ No newline at end of file diff --git a/src/lib/types.alo b/src/lib/types.alo index 39fd0f8..f109ddb 100644 --- a/src/lib/types.alo +++ b/src/lib/types.alo @@ -1,3 +1,6 @@ +%ifndef _TYPES_ +%def _TYPES_ + extern "S" func _cdouble2int(double v)->int; //返回一个小于传入参数的最大整数 @@ -11,4 +14,6 @@ func floor(double v)->int{ } double t= v - v1; return _cdouble2int(t); -} \ No newline at end of file +} + +%endif \ No newline at end of file diff --git a/src/lib/usc4support.cpp b/src/lib/usc4support.cpp index 0bd20e7..9583537 100644 --- a/src/lib/usc4support.cpp +++ b/src/lib/usc4support.cpp @@ -87,22 +87,36 @@ unsigned int UTF8ToUCS4(const std::string &src, mfchar_t *dest) return curIndex; } -void UCS4ToUTF8(const mfstring &src, std::string &dest) +std::string UCS4ToUTF8(const mfstring &src) { + std::string result; char out[MB_LEN_MAX]; std::mbstate_t state{}; for (char32_t c : src) { std::size_t rc = std::c32rtomb(out, c, &state); if (rc != (std::size_t)-1) for (char c8 : std::string_view{out, rc}) - dest.push_back(c8); + result.push_back(c8); } + return result; } // TODO: Support for other chatsets // for alolang +extern "C" const char *string2char(int *data, long long length) +{ + mfstring src; + for (long long i = 0; i < length; i++) { + src.push_back(data[i]); + printf("%lld\n", data[i]); + } + /*std::string result = UCS4ToUTF8(src); + return result.c_str();*/ + return ""; +} + extern "C" long long __alolang_inner_load_string(char *str, long long addr) { long long length = UTF8ToUCS4(std::string(str), (int *)addr); diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index b6b2355..ec2f99f 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -125,7 +125,8 @@ std::vector processPreInstruction(const std::string &line, int cnt, currentifstack--; return std::vector{Tline(TokenSource("", lineno), "")}; } else { - CompileError e("Unrecognized preprocessor command"); + CompileError e("Unrecognized preprocessor command " + + instruction.first); throw e; } } -- Gitee From 25ab9ef6a4c37a251f8c0edf2ca36e6b32a71038 Mon Sep 17 00:00:00 2001 From: zyb Date: Thu, 18 Mar 2021 01:06:25 +0800 Subject: [PATCH 82/95] listen.py --- src/lib/ipc/ipcpy/listen.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/lib/ipc/ipcpy/listen.py diff --git a/src/lib/ipc/ipcpy/listen.py b/src/lib/ipc/ipcpy/listen.py new file mode 100644 index 0000000..dc6bc42 --- /dev/null +++ b/src/lib/ipc/ipcpy/listen.py @@ -0,0 +1,32 @@ +import os +import time + +def close(rd): + try: + os.close(rd) + except: + print("不存在指定管道") + +def listen(pipename): + try: + rd = os.open(pipename, os.O_RDONLY) + except IOError: + print("不存在指定管道") + else: + fl = 0 + a='' + while True: + s = os.read(rd, 128) + if (len(s) == 0): + fl+=1 + time.sleep(1) + else: + fl == 0 + a += s + if (fl == 3) + return a + + + + + \ No newline at end of file -- Gitee From 90be7e3227ba61fa9c3ab8a11031976c65c62f71 Mon Sep 17 00:00:00 2001 From: zyb Date: Thu, 18 Mar 2021 01:07:57 +0800 Subject: [PATCH 83/95] =?UTF-8?q?=E6=89=8D=E5=8F=91=E7=8E=B0=E6=B2=A1?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=BB=99close=E5=8D=95=E7=8B=AC=E5=86=99?= =?UTF-8?q?=E4=B8=AA=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/ipc/ipcpy/listen.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/ipc/ipcpy/listen.py b/src/lib/ipc/ipcpy/listen.py index dc6bc42..cbb4c8e 100644 --- a/src/lib/ipc/ipcpy/listen.py +++ b/src/lib/ipc/ipcpy/listen.py @@ -1,12 +1,6 @@ import os import time -def close(rd): - try: - os.close(rd) - except: - print("不存在指定管道") - def listen(pipename): try: rd = os.open(pipename, os.O_RDONLY) @@ -23,7 +17,8 @@ def listen(pipename): else: fl == 0 a += s - if (fl == 3) + if (fl == 3): + os.close(rd) return a -- Gitee From 25d77df983a47bde0231c48e61b5f5428bcbf8c5 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 10:36:34 +0800 Subject: [PATCH 84/95] may have fixed the bug related to ucs to utf8 --- src/lib/{usc4support.cpp => ucs4support.cpp} | 27 ++++++++------------ 1 file changed, 11 insertions(+), 16 deletions(-) rename src/lib/{usc4support.cpp => ucs4support.cpp} (86%) diff --git a/src/lib/usc4support.cpp b/src/lib/ucs4support.cpp similarity index 86% rename from src/lib/usc4support.cpp rename to src/lib/ucs4support.cpp index 9583537..0bc4aa5 100644 --- a/src/lib/usc4support.cpp +++ b/src/lib/ucs4support.cpp @@ -4,9 +4,11 @@ #include #include #include +#include +// #include typedef int mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 -typedef std::basic_string mfstring; // 自定义的UCS-4字符串 +typedef std::u32string mfstring; // 自定义的UCS-4字符串 // 把utf-8编码的字符串转换成UCS-4编码的字符串 unsigned int UTF8ToUCS4(const std::string &src, mfchar_t *dest) @@ -87,18 +89,10 @@ unsigned int UTF8ToUCS4(const std::string &src, mfchar_t *dest) return curIndex; } -std::string UCS4ToUTF8(const mfstring &src) +std::string UCS4ToUTF8(const std::u32string &s) { - std::string result; - char out[MB_LEN_MAX]; - std::mbstate_t state{}; - for (char32_t c : src) { - std::size_t rc = std::c32rtomb(out, c, &state); - if (rc != (std::size_t)-1) - for (char c8 : std::string_view{out, rc}) - result.push_back(c8); - } - return result; + std::wstring_convert, char32_t> conv; + return conv.to_bytes(s); } // TODO: Support for other chatsets @@ -107,14 +101,15 @@ std::string UCS4ToUTF8(const mfstring &src) extern "C" const char *string2char(int *data, long long length) { - mfstring src; + std::u32string src; for (long long i = 0; i < length; i++) { src.push_back(data[i]); printf("%lld\n", data[i]); } - /*std::string result = UCS4ToUTF8(src); - return result.c_str();*/ - return ""; + std::string result = UCS4ToUTF8(src); + // std::cout << result << std::endl; + return result.c_str(); + // return ""; } extern "C" long long __alolang_inner_load_string(char *str, long long addr) -- Gitee From e0b02982503bcbe5e57990bbd0ecaf9c060429f7 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 10:58:58 +0800 Subject: [PATCH 85/95] more fix --- src/lib/ucs4support.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 0bc4aa5..86077ba 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -5,7 +5,7 @@ #include #include #include -// #include +#include typedef int mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 typedef std::u32string mfstring; // 自定义的UCS-4字符串 @@ -99,7 +99,7 @@ std::string UCS4ToUTF8(const std::u32string &s) // for alolang -extern "C" const char *string2char(int *data, long long length) +extern "C" void string2char(int *data, long long length, char *dst) { std::u32string src; for (long long i = 0; i < length; i++) { @@ -107,8 +107,9 @@ extern "C" const char *string2char(int *data, long long length) printf("%lld\n", data[i]); } std::string result = UCS4ToUTF8(src); - // std::cout << result << std::endl; - return result.c_str(); + std::cout << result << std::endl; + // return result.c_str(); + std::strncpy(dst,result.c_str(),result.length()); // return ""; } -- Gitee From 2db2c27764e750c035c1c687e5d96f660738e779 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 11:01:14 +0800 Subject: [PATCH 86/95] fixed a bug caused by my stupidity --- src/lib/ucs4support.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 86077ba..4d55f2e 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -109,7 +109,7 @@ extern "C" void string2char(int *data, long long length, char *dst) std::string result = UCS4ToUTF8(src); std::cout << result << std::endl; // return result.c_str(); - std::strncpy(dst,result.c_str(),result.length()); + std::strncpy(dst,result.c_str(),result.length()+1); // return ""; } -- Gitee From 92f1952cbae554f54710923fdf2045dbca1d2d76 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 11:07:56 +0800 Subject: [PATCH 87/95] commented out the debug code --- src/lib/ucs4support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 4d55f2e..3d31462 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +// #include typedef int mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 typedef std::u32string mfstring; // 自定义的UCS-4字符串 @@ -107,7 +107,7 @@ extern "C" void string2char(int *data, long long length, char *dst) printf("%lld\n", data[i]); } std::string result = UCS4ToUTF8(src); - std::cout << result << std::endl; + // std::cout << result << std::endl; // return result.c_str(); std::strncpy(dst,result.c_str(),result.length()+1); // return ""; -- Gitee From cc887eb67e845cab00e66119f3fff7d0ba4aa82d Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 11:16:21 +0800 Subject: [PATCH 88/95] format code --- src/lib/ucs4support.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 3d31462..3712730 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -1,10 +1,10 @@ #include +#include #include #include #include #include #include -#include // #include typedef int mfchar_t; // 无符号的4字节,用于容纳UCS-4的一个字符 @@ -109,7 +109,7 @@ extern "C" void string2char(int *data, long long length, char *dst) std::string result = UCS4ToUTF8(src); // std::cout << result << std::endl; // return result.c_str(); - std::strncpy(dst,result.c_str(),result.length()+1); + std::strncpy(dst, result.c_str(), result.length() + 1); // return ""; } -- Gitee From e6d935e49fce54df157820160ff64d70adf7a1e0 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 13:22:17 +0800 Subject: [PATCH 89/95] Fix some bugs --- src/lib/Makefile.am | 6 +++--- src/lib/ucs4support.cpp | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 102516d..dcb9fc3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,8 +1,8 @@ AUTOMAKE_OPTIONS = foreign lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c usc4support.cpp +libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp alolanglibdir=$(libdir) alolanglib_PROGRAMS = libalolangcore.so -libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c usc4support.cpp -libalolangcore_so_LDFLAGS = -shared -fpic +libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp +libalolangcore_so_LDFLAGS = -shared -fPIC -static diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 3712730..1a7e42a 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -107,10 +107,7 @@ extern "C" void string2char(int *data, long long length, char *dst) printf("%lld\n", data[i]); } std::string result = UCS4ToUTF8(src); - // std::cout << result << std::endl; - // return result.c_str(); std::strncpy(dst, result.c_str(), result.length() + 1); - // return ""; } extern "C" long long __alolang_inner_load_string(char *str, long long addr) -- Gitee From 319a19fe01ff17fcb2b2a3dbe8c93d4fd073d3e5 Mon Sep 17 00:00:00 2001 From: zyb Date: Thu, 18 Mar 2021 13:35:40 +0800 Subject: [PATCH 90/95] testprintchar --- src/lib/testPuts.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 4041612..3b5f7d2 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -16,6 +16,7 @@ struct aloarray_char { struct alostring { struct aloarray_char data; }; + extern void _alolang_15testPrintString6stringe(struct alostring str) { char *rstr = string2char((int *)str.data.pointer.addr, str.data.size); @@ -31,6 +32,13 @@ extern void _alolang_13testPrintBool4boole(int a) } } +extern void _alolang_13testPrintChar4chare(int alochar) +{ + char *a; + char *p=string2char(&alochar, 1); + printf("%s", p); +} + extern long long _alolang_10testGetInte() { long long a; -- Gitee From 93e53be3ae1538614b1039f971ab4f7b109b6b88 Mon Sep 17 00:00:00 2001 From: NaiveTomcat Date: Thu, 18 Mar 2021 16:31:59 +0800 Subject: [PATCH 91/95] changed library biuld method to libtool --- config.h.in~ | 6 ++++++ configure.ac | 1 + src/lib/Makefile.am | 15 +++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/config.h.in~ b/config.h.in~ index 06b7023..d538d32 100644 --- a/config.h.in~ +++ b/config.h.in~ @@ -3,6 +3,9 @@ /* define if the compiler supports basic C++17 syntax */ #undef HAVE_CXX17 +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -54,6 +57,9 @@ /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + /* Name of package */ #undef PACKAGE diff --git a/configure.ac b/configure.ac index f64a4ee..dc5d0eb 100644 --- a/configure.ac +++ b/configure.ac @@ -53,4 +53,5 @@ AC_CONFIG_FILES([ AX_CXX_COMPILE_STDCXX(17, [noext], [mandatory]) AM_INIT_AUTOMAKE +LT_INIT AC_OUTPUT diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index dcb9fc3..1a357f5 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,8 +1,11 @@ AUTOMAKE_OPTIONS = foreign -lib_LIBRARIES = libalolangcore.a -libalolangcore_a_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp +lib_LTLIBRARIES = libalolangcore.la +libalolangcore_la_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp +libalolangcore_la_LDFLAGS = -version-info 0:0:0 +# libalolangcore_la_CFLAGS = -fPIC +# libalolangcore_la_CXXFLAGS = -fPIC -alolanglibdir=$(libdir) -alolanglib_PROGRAMS = libalolangcore.so -libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp -libalolangcore_so_LDFLAGS = -shared -fPIC -static +# alolanglibdir=$(libdir) +# alolanglib_PROGRAMS = libalolangcore.so +# libalolangcore_so_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp +# libalolangcore_so_LDFLAGS = -shared -fPIC -static -- Gitee From 0e559e9d2aca6a31dc4fd13ec6b1db361440e824 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 17:20:10 +0800 Subject: [PATCH 92/95] Fix some bugs of the string i/o --- config.h.in~ | 6 ------ src/lib/testPuts.c | 13 +++++++------ src/lib/testio.alo | 1 + src/lib/ucs4support.cpp | 1 - 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/config.h.in~ b/config.h.in~ index d538d32..06b7023 100644 --- a/config.h.in~ +++ b/config.h.in~ @@ -3,9 +3,6 @@ /* define if the compiler supports basic C++17 syntax */ #undef HAVE_CXX17 -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -57,9 +54,6 @@ /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - /* Name of package */ #undef PACKAGE diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c index 3b5f7d2..643f52f 100644 --- a/src/lib/testPuts.c +++ b/src/lib/testPuts.c @@ -1,6 +1,6 @@ #include -char *string2char(int *data, long long length); +extern void string2char(int *data, long long length, char *dst); extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } @@ -19,8 +19,9 @@ struct alostring { extern void _alolang_15testPrintString6stringe(struct alostring str) { - char *rstr = string2char((int *)str.data.pointer.addr, str.data.size); - printf("%s\n", rstr); + char buff[str.data.size * 4 + 1]; + string2char((int *)str.data.pointer.addr, str.data.size, buff); + printf("%s\n", buff); }; extern void _alolang_13testPrintBool4boole(int a) @@ -34,9 +35,9 @@ extern void _alolang_13testPrintBool4boole(int a) extern void _alolang_13testPrintChar4chare(int alochar) { - char *a; - char *p=string2char(&alochar, 1); - printf("%s", p); + char a[5]; + string2char(&alochar, 1, a); + printf("%s\n", a); } extern long long _alolang_10testGetInte() diff --git a/src/lib/testio.alo b/src/lib/testio.alo index ecbbf40..678f6f3 100644 --- a/src/lib/testio.alo +++ b/src/lib/testio.alo @@ -5,6 +5,7 @@ extern func testPrintInt(int i); extern func testPrintDouble(double f); extern func testPrintBool(bool b); extern func testPrintString(string s); +extern func testPrintChar(char c); extern "S" func testGetInt() -> int; extern "S" func testGetDouble() -> double; diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 1a7e42a..6b94ed4 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -104,7 +104,6 @@ extern "C" void string2char(int *data, long long length, char *dst) std::u32string src; for (long long i = 0; i < length; i++) { src.push_back(data[i]); - printf("%lld\n", data[i]); } std::string result = UCS4ToUTF8(src); std::strncpy(dst, result.c_str(), result.length() + 1); -- Gitee From 0193178cdd8e3189eb4a7b87df6569432be9d264 Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 17:31:25 +0800 Subject: [PATCH 93/95] Lots of fix --- src/ast/BoolExprAST.cpp | 2 ++ src/ast/DoubleExprAST.cpp | 2 ++ src/lib/Makefile.am | 2 +- src/lib/array.alo | 2 +- src/lib/{testio.alo => io.alo} | 11 ++++++----- src/lib/{testPuts.c => io.c} | 23 ++++++++++++++--------- 6 files changed, 26 insertions(+), 16 deletions(-) rename src/lib/{testio.alo => io.alo} (39%) rename src/lib/{testPuts.c => io.c} (65%) diff --git a/src/ast/BoolExprAST.cpp b/src/ast/BoolExprAST.cpp index 5b9f7d4..0e49e3c 100644 --- a/src/ast/BoolExprAST.cpp +++ b/src/ast/BoolExprAST.cpp @@ -21,6 +21,8 @@ BoolExprAST::~BoolExprAST() std::vector BoolExprAST::Codegen(llvm::IRBuilder<> *builder) { + this->type.clear(); + this->type.push_back(new TypeAST(unit, "bool")); std::vector result; llvm::IntegerType * type = llvm::IntegerType::get(*unit->context, 1); llvm::ConstantInt * res = llvm::ConstantInt::get(type, val, true); diff --git a/src/ast/DoubleExprAST.cpp b/src/ast/DoubleExprAST.cpp index f31d35c..ac51f0a 100644 --- a/src/ast/DoubleExprAST.cpp +++ b/src/ast/DoubleExprAST.cpp @@ -21,6 +21,8 @@ DoubleExprAST::~DoubleExprAST() std::vector DoubleExprAST::Codegen(llvm::IRBuilder<> *builder) { + this->type.clear(); + this->type.push_back(new TypeAST(unit, "double")); std::vector result; llvm::Type * rtype = llvm::Type::getDoubleTy(*unit->context); llvm::Value * res = llvm::ConstantFP::get(rtype, val); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 1a357f5..5d2e8c3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign lib_LTLIBRARIES = libalolangcore.la -libalolangcore_la_SOURCES = unsafe.c testPuts.c types.c testrand.c ucs4support.cpp +libalolangcore_la_SOURCES = unsafe.c io.c types.c testrand.c ucs4support.cpp libalolangcore_la_LDFLAGS = -version-info 0:0:0 # libalolangcore_la_CFLAGS = -fPIC # libalolangcore_la_CXXFLAGS = -fPIC diff --git a/src/lib/array.alo b/src/lib/array.alo index f140e2c..c98c94b 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -84,7 +84,7 @@ class array func get(int _Index) -> A* { UnsafePointer cur; - cur.addr=this->ptr.addr+_Index * sizeof(int); + cur.addr=this->ptr.addr+_Index * sizeof(A); return cur.load(); } func pop_back() -> A diff --git a/src/lib/testio.alo b/src/lib/io.alo similarity index 39% rename from src/lib/testio.alo rename to src/lib/io.alo index 678f6f3..27212b3 100644 --- a/src/lib/testio.alo +++ b/src/lib/io.alo @@ -1,11 +1,12 @@ %ifndef _TESTIO_ %def _TESTIO_ -extern func testPrintInt(int i); -extern func testPrintDouble(double f); -extern func testPrintBool(bool b); -extern func testPrintString(string s); -extern func testPrintChar(char c); +extern func print(int i); +extern func print(double f); +extern func print(bool b); +extern func print(string s); +extern func print(char c); + extern "S" func testGetInt() -> int; extern "S" func testGetDouble() -> double; diff --git a/src/lib/testPuts.c b/src/lib/io.c similarity index 65% rename from src/lib/testPuts.c rename to src/lib/io.c index 643f52f..a726fc7 100644 --- a/src/lib/testPuts.c +++ b/src/lib/io.c @@ -1,11 +1,5 @@ #include -extern void string2char(int *data, long long length, char *dst); - -extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } - -extern void _alolang_12testPrintInt3inte(long long a) { printf("%lld\n", a); } -extern void _alolang_15testPrintDouble6doublee(double a) { printf("%lf\n", a); } struct aloptr { long long addr; }; @@ -17,14 +11,24 @@ struct alostring { struct aloarray_char data; }; -extern void _alolang_15testPrintString6stringe(struct alostring str) +extern void string2char(int *data, long long length, char *dst); + +// print(int) +extern void _alolang_5print3inte(long long a) { printf("%lld\n", a); } + +// print(double) +extern void _alolang_5print6doublee(double a) { printf("%lf\n", a); } + +// print(string) +extern void _alolang_5print6stringe(struct alostring str) { char buff[str.data.size * 4 + 1]; string2char((int *)str.data.pointer.addr, str.data.size, buff); printf("%s\n", buff); }; -extern void _alolang_13testPrintBool4boole(int a) +// print(bool) +extern void _alolang_5print4boole(int a) { if (a) { printf("true\n"); @@ -33,7 +37,8 @@ extern void _alolang_13testPrintBool4boole(int a) } } -extern void _alolang_13testPrintChar4chare(int alochar) +// print(char) +extern void _alolang_5print4chare(int alochar) { char a[5]; string2char(&alochar, 1, a); -- Gitee From 76ac4f016cedc23f915d4b1418dd6cdfb385932f Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 18:29:42 +0800 Subject: [PATCH 94/95] Small fixes and rebuild --- src/lib/Makefile.am | 2 +- src/lib/array.alo | 8 +++++++- src/lib/io.c | 15 ++------------- src/lib/rand.alo | 1 + src/lib/rand.c | 2 ++ src/lib/string.alo | 7 ++++++- src/lib/testrand.alo | 2 -- src/lib/time.alo | 1 + src/lib/{testrand.c => time.c} | 10 ++++++++-- src/lib/types/alostring.h | 22 ++++++++++++++++++++++ src/lib/ucs4support.cpp | 12 ++++++++---- src/lib/ucs4support.h | 14 ++++++++++++++ 12 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 src/lib/rand.alo create mode 100644 src/lib/rand.c delete mode 100644 src/lib/testrand.alo create mode 100644 src/lib/time.alo rename src/lib/{testrand.c => time.c} (66%) create mode 100644 src/lib/types/alostring.h create mode 100644 src/lib/ucs4support.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 5d2e8c3..cd41ffe 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign lib_LTLIBRARIES = libalolangcore.la -libalolangcore_la_SOURCES = unsafe.c io.c types.c testrand.c ucs4support.cpp +libalolangcore_la_SOURCES = unsafe.c io.c types.c rand.c ucs4support.cpp time.c libalolangcore_la_LDFLAGS = -version-info 0:0:0 # libalolangcore_la_CFLAGS = -fPIC # libalolangcore_la_CXXFLAGS = -fPIC diff --git a/src/lib/array.alo b/src/lib/array.alo index c98c94b..ffa9f48 100644 --- a/src/lib/array.alo +++ b/src/lib/array.alo @@ -1,3 +1,7 @@ +%ifndef _ARRAY_ +%def _ARRAY_ + + %import unsafe.alo %import types.alo @@ -113,4 +117,6 @@ class array p.addr = p.addr + this->sz * sizeof(A) - sizeof(A); return *(p.load()); } -} \ No newline at end of file +} + +%endif \ No newline at end of file diff --git a/src/lib/io.c b/src/lib/io.c index a726fc7..8692b05 100644 --- a/src/lib/io.c +++ b/src/lib/io.c @@ -1,18 +1,7 @@ +#include "types/alostring.h" +#include "ucs4support.h" #include -struct aloptr { - long long addr; -}; -struct aloarray_char { - struct aloptr pointer; - long long size; -}; -struct alostring { - struct aloarray_char data; -}; - -extern void string2char(int *data, long long length, char *dst); - // print(int) extern void _alolang_5print3inte(long long a) { printf("%lld\n", a); } diff --git a/src/lib/rand.alo b/src/lib/rand.alo new file mode 100644 index 0000000..612f207 --- /dev/null +++ b/src/lib/rand.alo @@ -0,0 +1 @@ +extern "S" func rand() -> int; \ No newline at end of file diff --git a/src/lib/rand.c b/src/lib/rand.c new file mode 100644 index 0000000..8947b1d --- /dev/null +++ b/src/lib/rand.c @@ -0,0 +1,2 @@ +#include +extern long long _alolang_4rand(void) { return rand(); } diff --git a/src/lib/string.alo b/src/lib/string.alo index 3b49720..fa40484 100644 --- a/src/lib/string.alo +++ b/src/lib/string.alo @@ -1,3 +1,6 @@ +%ifndef _STRING_ +%def _STRING_ + %import array.alo class string @@ -12,4 +15,6 @@ class string { return *this->data.get(index); } -} \ No newline at end of file +} + +%endif \ No newline at end of file diff --git a/src/lib/testrand.alo b/src/lib/testrand.alo deleted file mode 100644 index 54002be..0000000 --- a/src/lib/testrand.alo +++ /dev/null @@ -1,2 +0,0 @@ -extern "S" func testTime() -> int; -extern "S" func testRand() -> int; \ No newline at end of file diff --git a/src/lib/time.alo b/src/lib/time.alo new file mode 100644 index 0000000..97c0c38 --- /dev/null +++ b/src/lib/time.alo @@ -0,0 +1 @@ +extern "S" func time() -> int; \ No newline at end of file diff --git a/src/lib/testrand.c b/src/lib/time.c similarity index 66% rename from src/lib/testrand.c rename to src/lib/time.c index 29a04f7..22b4c95 100644 --- a/src/lib/testrand.c +++ b/src/lib/time.c @@ -1,8 +1,14 @@ +/* + * time.c + * + * Created on: Mar 18, 2021 + * Author: zbc + */ + #include #include #include #include -extern long long _alolang_8testRand(void) { return rand(); } int64_t currentTimeMillis() { @@ -13,4 +19,4 @@ int64_t currentTimeMillis() return s1 + s2; } -extern long long _alolang_8testTime(void) { return currentTimeMillis(); } +extern long long _alolang_4time(void) { return currentTimeMillis(); } diff --git a/src/lib/types/alostring.h b/src/lib/types/alostring.h new file mode 100644 index 0000000..5de2cbc --- /dev/null +++ b/src/lib/types/alostring.h @@ -0,0 +1,22 @@ +/* + * alostring.h + * + * Created on: Mar 18, 2021 + * Author: zbc + */ + +#ifndef SRC_LIB_TYPES_ALOSTRING_H_ +#define SRC_LIB_TYPES_ALOSTRING_H_ + +struct aloptr { + long long addr; +}; +struct aloarray_char { + struct aloptr pointer; + long long size; +}; +struct alostring { + struct aloarray_char data; +}; + +#endif /* SRC_LIB_TYPES_ALOSTRING_H_ */ diff --git a/src/lib/ucs4support.cpp b/src/lib/ucs4support.cpp index 6b94ed4..599d3b9 100644 --- a/src/lib/ucs4support.cpp +++ b/src/lib/ucs4support.cpp @@ -97,8 +97,6 @@ std::string UCS4ToUTF8(const std::u32string &s) // TODO: Support for other chatsets -// for alolang - extern "C" void string2char(int *data, long long length, char *dst) { std::u32string src; @@ -109,8 +107,14 @@ extern "C" void string2char(int *data, long long length, char *dst) std::strncpy(dst, result.c_str(), result.length() + 1); } +extern "C" long long char2string(char *str, int *dest) +{ + return UTF8ToUCS4(std::string(str), dest); +} + +// for alolang + extern "C" long long __alolang_inner_load_string(char *str, long long addr) { - long long length = UTF8ToUCS4(std::string(str), (int *)addr); - return length; + return char2string(str, (int *)addr); } diff --git a/src/lib/ucs4support.h b/src/lib/ucs4support.h new file mode 100644 index 0000000..563ee05 --- /dev/null +++ b/src/lib/ucs4support.h @@ -0,0 +1,14 @@ +/* + * ucs4support.h + * + * Created on: Mar 18, 2021 + * Author: zbc + */ + +#ifndef SRC_LIB_UCS4SUPPORT_H_ +#define SRC_LIB_UCS4SUPPORT_H_ + +extern long long char2string(char *str, int *dest); +extern void string2char(int *data, long long length, char *dst); + +#endif /* SRC_LIB_UCS4SUPPORT_H_ */ -- Gitee From 97c27f67f9c6df65c395aa76abaea669935e40ab Mon Sep 17 00:00:00 2001 From: uebian Date: Thu, 18 Mar 2021 18:52:56 +0800 Subject: [PATCH 95/95] Add %ifndef to library --- src/lib/io.alo | 4 ++-- src/lib/rand.alo | 7 ++++++- src/lib/time.alo | 7 ++++++- src/lib/unsafe.alo | 8 +++++++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/lib/io.alo b/src/lib/io.alo index 27212b3..b176222 100644 --- a/src/lib/io.alo +++ b/src/lib/io.alo @@ -1,5 +1,5 @@ -%ifndef _TESTIO_ -%def _TESTIO_ +%ifndef _IO_ +%def _IO_ extern func print(int i); extern func print(double f); diff --git a/src/lib/rand.alo b/src/lib/rand.alo index 612f207..e23e7fe 100644 --- a/src/lib/rand.alo +++ b/src/lib/rand.alo @@ -1 +1,6 @@ -extern "S" func rand() -> int; \ No newline at end of file +%ifndef _RAND_ +%def _RAND_ + +extern "S" func rand() -> int; + +%endif \ No newline at end of file diff --git a/src/lib/time.alo b/src/lib/time.alo index 97c0c38..136b2cd 100644 --- a/src/lib/time.alo +++ b/src/lib/time.alo @@ -1 +1,6 @@ -extern "S" func time() -> int; \ No newline at end of file +%ifndef _TIME_ +%def _TIME_ + +extern "S" func time() -> int; + +%endif \ No newline at end of file diff --git a/src/lib/unsafe.alo b/src/lib/unsafe.alo index e309012..0a940c0 100644 --- a/src/lib/unsafe.alo +++ b/src/lib/unsafe.alo @@ -1,3 +1,7 @@ +%ifndef _UNSAFE_ +%def _UNSAFE_ + + extern func __cfree(int addr); extern func __cmalloc(int size)->int; extern func __cmemcpy(int src,int dst,int size); @@ -41,4 +45,6 @@ class UnsafePointer __cfree(this->addr); return; } -} \ No newline at end of file +} + +%endif \ No newline at end of file -- Gitee