From 0d9bfae63cf3a064882856406973711c12e3cd98 Mon Sep 17 00:00:00 2001 From: Yan Zhang Date: Sat, 1 Jan 2022 13:33:10 -0800 Subject: [PATCH 1/9] Add a test case with 'break' as a method name --- .../test/typescript/unit_tests/identifiers20.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/MapleFE/test/typescript/unit_tests/identifiers20.ts diff --git a/src/MapleFE/test/typescript/unit_tests/identifiers20.ts b/src/MapleFE/test/typescript/unit_tests/identifiers20.ts new file mode 100644 index 0000000000..afe4d26516 --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/identifiers20.ts @@ -0,0 +1,11 @@ +class Klass { + items: number[] = []; + break() { + for (const i of this.items) + console.log(i); + } +} + +var obj: Klass = new Klass(); +obj.items.push(6, 2, 1, 4, 5, 3); +obj.break(); -- Gitee From 4cac5c6225164f08be1034b92a1bbcd2f73706f3 Mon Sep 17 00:00:00 2001 From: yehandong Date: Tue, 4 Jan 2022 12:21:04 -0800 Subject: [PATCH 2/9] Handle the ending \ in string literal. --- .../multi-line-string-literal.ts.result | 4 +- src/MapleFE/typescript/include/lang_spec.h | 1 + src/MapleFE/typescript/src/lang_spec.cpp | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/MapleFE/test/typescript/unit_tests/multi-line-string-literal.ts.result b/src/MapleFE/test/typescript/unit_tests/multi-line-string-literal.ts.result index db55fa5640..7a631af425 100644 --- a/src/MapleFE/test/typescript/unit_tests/multi-line-string-literal.ts.result +++ b/src/MapleFE/test/typescript/unit_tests/multi-line-string-literal.ts.result @@ -2,8 +2,6 @@ Matched 7 tokens. Matched 14 tokens. ============= Module =========== == Sub Tree == -js_var Decl: str="This \ -is \ -a string literal" +js_var Decl: str="This is a string literal" == Sub Tree == console.log(str) diff --git a/src/MapleFE/typescript/include/lang_spec.h b/src/MapleFE/typescript/include/lang_spec.h index 4784801111..929de87c24 100644 --- a/src/MapleFE/typescript/include/lang_spec.h +++ b/src/MapleFE/typescript/include/lang_spec.h @@ -33,6 +33,7 @@ public: bool StringToBool(std::string &s); Char StringToChar(std::string &s); bool StringIsNull(std::string &s); + const char* StringToString(std::string &); }; extern LitData ProcessLiteral(LitId type, const char *str); diff --git a/src/MapleFE/typescript/src/lang_spec.cpp b/src/MapleFE/typescript/src/lang_spec.cpp index e175d3e5ba..45d754b4ad 100644 --- a/src/MapleFE/typescript/src/lang_spec.cpp +++ b/src/MapleFE/typescript/src/lang_spec.cpp @@ -44,6 +44,44 @@ bool StringToValueImpl::StringToBool(std::string &s) { bool StringToValueImpl::StringIsNull(std::string &s) {return false;} +const char* StringToValueImpl::StringToString(std::string &in_str) { + std::string target; + + // For most languages, the input 'in_str' still contains the leading " or ' and the + // ending " or '. They need to be removed. + std::string str; + + // If empty string literal, return the empty 'target'. + if (in_str.size() == 2) { + const char *s = gStringPool.FindString(target); + return s; + } else { + str.assign(in_str, 1, in_str.size() - 2); + } + + // For typescript, if a string literal is: + // s : string = "abc \ + // efg"; + // The \ is actually connnecting the next line into the string literal. + // We need handle the connection. + + std::string s_ret; + for (unsigned i = 0; i < str.length(); i++) { + char c = str[i]; + if (c == '\\') { + if ((i < str.length() - 1) && (str[i+1] == '\n')) { + // skip \ and \n + i += 1; + continue; + } + } + s_ret.push_back(c); + } + + const char *s = gStringPool.FindString(s_ret); + return s; +} + static char DeEscape(char c) { switch(c) { case 'b': -- Gitee From 449ee09d9d01c58127310989c5ad2f725731dd44 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Tue, 4 Jan 2022 15:29:23 -0500 Subject: [PATCH 3/9] add Utility Types as keywords --- .../typescript/include/lang_keywords.def | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/MapleFE/typescript/include/lang_keywords.def b/src/MapleFE/typescript/include/lang_keywords.def index 76d3e2dd2a..b8e018414e 100644 --- a/src/MapleFE/typescript/include/lang_keywords.def +++ b/src/MapleFE/typescript/include/lang_keywords.def @@ -89,13 +89,33 @@ LANGKEYWORD(async) LANGKEYWORD(global) +// Utility Types +LANGKEYWORD(Partial) +LANGKEYWORD(Required) +LANGKEYWORD(Readonly) +LANGKEYWORD(Record) +LANGKEYWORD(Pick) +LANGKEYWORD(Omit) +LANGKEYWORD(Exclude) +LANGKEYWORD(Extract) +LANGKEYWORD(NonNullable) +LANGKEYWORD(Parameters) +LANGKEYWORD(ConstructorParameters) +LANGKEYWORD(ReturnType) +LANGKEYWORD(InstanceType) +LANGKEYWORD(ThisParameterType) +LANGKEYWORD(OmitThisParameter) +LANGKEYWORD(ThisType) +LANGKEYWORD(Uppercase) +LANGKEYWORD(Lowercase) +LANGKEYWORD(Capitalize) +LANGKEYWORD(Uncapitalize) + +LANGKEYWORD(Error) + // extra LANGKEYWORD(console) LANGKEYWORD(log) LANGKEYWORD(null) - -LANGKEYWORD(Parameters) -LANGKEYWORD(Error) -LANGKEYWORD(NonNullable) -- Gitee From 33985f54b0e6167fad1bea186f5555d6d99babd9 Mon Sep 17 00:00:00 2001 From: yehandong Date: Tue, 4 Jan 2022 12:38:54 -0800 Subject: [PATCH 4/9] Move FindXXXToken() functions to global so everybody can use. --- src/MapleFE/shared/include/lexer.h | 9 +--- src/MapleFE/shared/include/token.h | 6 +++ src/MapleFE/shared/src/lexer.cpp | 62 ---------------------- src/MapleFE/shared/src/token.cpp | 66 ++++++++++++++++++++++++ src/MapleFE/typescript/src/lang_spec.cpp | 6 +-- 5 files changed, 77 insertions(+), 72 deletions(-) diff --git a/src/MapleFE/shared/include/lexer.h b/src/MapleFE/shared/include/lexer.h index 292cb2a97c..380d8ed41b 100644 --- a/src/MapleFE/shared/include/lexer.h +++ b/src/MapleFE/shared/include/lexer.h @@ -126,6 +126,8 @@ public: const char* GetIdentifier(); bool GetComment(); + Token* FindRegExprToken(); + // For most languages, this does nothing. TS/JS are doing something. virtual bool CharIsSeparator(const char c) {return false;} @@ -138,13 +140,6 @@ public: //void PlantTraverseRuleTable(RuleTable*); //void PlantTraverseTableData(TableData*); - // - Token* FindSeparatorToken(SepId id); - Token* FindOperatorToken(OprId id); - Token* FindKeywordToken(const char *key); - Token* FindCommentToken(); - Token* FindRegExprToken(); - // When we start walk a rule table to find a token, do we need check if // the following data is a separator? bool mCheckSeparator; diff --git a/src/MapleFE/shared/include/token.h b/src/MapleFE/shared/include/token.h index b7c9449014..d9132cc681 100644 --- a/src/MapleFE/shared/include/token.h +++ b/src/MapleFE/shared/include/token.h @@ -158,5 +158,11 @@ struct Token { void Dump(); }; + // + Token* FindSeparatorToken(SepId id); + Token* FindOperatorToken(OprId id); + Token* FindKeywordToken(const char *key); + Token* FindCommentToken(); + } #endif diff --git a/src/MapleFE/shared/src/lexer.cpp b/src/MapleFE/shared/src/lexer.cpp index 2c4b97e2da..89460e331b 100644 --- a/src/MapleFE/shared/src/lexer.cpp +++ b/src/MapleFE/shared/src/lexer.cpp @@ -135,68 +135,6 @@ void Lexer::PrepareForString(const char *str) { endoffile = false; } -/////////////////////////////////////////////////////////////////////////// -// Utilities for finding system tokens -// Remember the order of tokens are operators, separators, and keywords. -/////////////////////////////////////////////////////////////////////////// - -Token* Lexer::FindOperatorToken(OprId id) { - Token *token = NULL; - bool found = false; - for (unsigned i = 0; i < gOperatorTokensNum; i++) { - token = &gSystemTokens[i]; - MASSERT(token->mTkType == TT_OP); - if (token->GetOprId() == id) { - found = true; - break; - } - } - MASSERT(found && token); - return token; -} - -Token* Lexer::FindSeparatorToken(SepId id) { - Token *token = NULL; - bool found = false; - for (unsigned i = gOperatorTokensNum; i < gOperatorTokensNum + gSeparatorTokensNum; i++) { - token = &gSystemTokens[i]; - MASSERT(token->mTkType == TT_SP); - if (token->GetSepId() == id) { - found = true; - break; - } - } - MASSERT(found && token); - return token; -} - -// The caller of this function makes sure 'key' is already in the -// string pool of Lexer. -Token* Lexer::FindKeywordToken(const char *key) { - Token *token = NULL; - bool found = false; - for (unsigned i = gOperatorTokensNum + gSeparatorTokensNum; - i < gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum; - i++) { - token = &gSystemTokens[i]; - MASSERT(token->mTkType == TT_KW); - if (strlen(key) == strlen(token->GetName()) && - !strncmp(key, token->GetName(), strlen(key))) { - found = true; - break; - } - } - MASSERT(found && token); - return token; -} - -// CommentToken is the last predefined token -Token* Lexer::FindCommentToken() { - Token *token = &gSystemTokens[gSystemTokensNum - 1]; - MASSERT((token->mTkType == TT_CM) && "Last system token is not a comment token."); - return token; -} - ///////////////////////////////////////////////////////////////////////////// // Both ClearLeadingNewLine() and AddEndingNewLine() will later be implemented // as language specific, and they will be overriding functions. diff --git a/src/MapleFE/shared/src/token.cpp b/src/MapleFE/shared/src/token.cpp index 0142e12185..2155b33687 100644 --- a/src/MapleFE/shared/src/token.cpp +++ b/src/MapleFE/shared/src/token.cpp @@ -14,8 +14,12 @@ */ #include "token.h" #include "stringpool.h" +#include "rule_summary.h" #include "massert.h" +#include +#include + namespace maplefe { #undef SEPARATOR @@ -167,4 +171,66 @@ bool Token::Equal(Token *t) { return equal; } +/////////////////////////////////////////////////////////////////////////// +// Utilities for finding system tokens +// Remember the order of tokens are operators, separators, and keywords. +/////////////////////////////////////////////////////////////////////////// + +Token* FindOperatorToken(OprId id) { + Token *token = NULL; + bool found = false; + for (unsigned i = 0; i < gOperatorTokensNum; i++) { + token = &gSystemTokens[i]; + MASSERT(token->mTkType == TT_OP); + if (token->GetOprId() == id) { + found = true; + break; + } + } + MASSERT(found && token); + return token; +} + +Token* FindSeparatorToken(SepId id) { + Token *token = NULL; + bool found = false; + for (unsigned i = gOperatorTokensNum; i < gOperatorTokensNum + gSeparatorTokensNum; i++) { + token = &gSystemTokens[i]; + MASSERT(token->mTkType == TT_SP); + if (token->GetSepId() == id) { + found = true; + break; + } + } + MASSERT(found && token); + return token; +} + +// The caller of this function makes sure 'key' is already in the +// string pool of Lexer. +Token* FindKeywordToken(const char *key) { + Token *token = NULL; + bool found = false; + for (unsigned i = gOperatorTokensNum + gSeparatorTokensNum; + i < gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum; + i++) { + token = &gSystemTokens[i]; + MASSERT(token->mTkType == TT_KW); + if (strlen(key) == strlen(token->GetName()) && + !strncmp(key, token->GetName(), strlen(key))) { + found = true; + break; + } + } + MASSERT(found && token); + return token; +} + +// CommentToken is the last predefined token +Token* FindCommentToken() { + Token *token = &gSystemTokens[gSystemTokensNum - 1]; + MASSERT((token->mTkType == TT_CM) && "Last system token is not a comment token."); + return token; +} + } diff --git a/src/MapleFE/typescript/src/lang_spec.cpp b/src/MapleFE/typescript/src/lang_spec.cpp index 45d754b4ad..99b61265fe 100644 --- a/src/MapleFE/typescript/src/lang_spec.cpp +++ b/src/MapleFE/typescript/src/lang_spec.cpp @@ -478,7 +478,7 @@ bool TypescriptParser::TokenSplit(Token *t) { if (!type_arg->IsIdentifier()) return false; - Token *extends_token = mLexer->FindKeywordToken("extends"); + Token *extends_token = FindKeywordToken("extends"); Token *lt = mActiveTokens.ValueAtIndex(size - 2); @@ -494,8 +494,8 @@ bool TypescriptParser::TokenSplit(Token *t) { } // Now we got a matching case. - Token *gt_token = mLexer->FindOperatorToken(OPR_GT); - Token *assign_token = mLexer->FindOperatorToken(OPR_Assign); + Token *gt_token = FindOperatorToken(OPR_GT); + Token *assign_token = FindOperatorToken(OPR_Assign); mActiveTokens.PushBack(gt_token); mActiveTokens.PushBack(assign_token); -- Gitee From c18c8bee6e9a63f145adf16d4d2324cc525c33ba Mon Sep 17 00:00:00 2001 From: eching Date: Tue, 4 Jan 2022 23:51:33 -0800 Subject: [PATCH 5/9] Use TI API interfaces FindDecl deep and GetTypeFromTypeIdx to lookup decl and type info for imported objects. --- src/MapleFE/ast2cpp/include/cpp_definition.h | 3 +-- src/MapleFE/ast2cpp/include/cpp_emitter.h | 2 ++ src/MapleFE/ast2cpp/src/cpp_definition.cpp | 23 ++++--------------- src/MapleFE/ast2cpp/src/cpp_emitter.cpp | 24 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/MapleFE/ast2cpp/include/cpp_definition.h b/src/MapleFE/ast2cpp/include/cpp_definition.h index 3d8157d8d2..73953d592d 100644 --- a/src/MapleFE/ast2cpp/include/cpp_definition.h +++ b/src/MapleFE/ast2cpp/include/cpp_definition.h @@ -69,7 +69,7 @@ public: std::string EmitFuncScopeVarDecls(FunctionNode *node); std::string EmitStructNode(StructNode *node); std::string EmitStructLiteralNode(StructLiteralNode* node); - std::string EmitObjPropInit(std::string varName, TreeNode* idType, StructLiteralNode* n); + std::string EmitObjPropInit(TreeNode* var, std::string varName, TreeNode* idType, StructLiteralNode* n); std::string EmitDirectFieldInit(std::string varName, StructLiteralNode* node); std::string EmitCppCtor(ClassNode* node); std::string EmitCtorInstance(ClassNode *c); @@ -79,7 +79,6 @@ public: std::string EmitArrayLiterals(TreeNode* arrLiteral, int dim, std::string type); TypeId GetTypeIdFromDecl(TreeNode* id); bool IsClassField(ArrayElementNode* node, std::string propKey); - bool IsClassId(TreeNode* node); std::string GetTypeForTemplateArg(TreeNode* node); TreeNode* FindDeclType(TreeNode* node); std::string GetThisParamObjType(TreeNode *node); diff --git a/src/MapleFE/ast2cpp/include/cpp_emitter.h b/src/MapleFE/ast2cpp/include/cpp_emitter.h index 7d09327347..1ec4ffe927 100644 --- a/src/MapleFE/ast2cpp/include/cpp_emitter.h +++ b/src/MapleFE/ast2cpp/include/cpp_emitter.h @@ -31,6 +31,8 @@ public: bool IsInNamespace(TreeNode *node); std::string GetNamespace(TreeNode *node); std::string GetQualifiedName(IdentifierNode *node); + bool IsClassId(TreeNode *node); + bool IsVarTypeClass(TreeNode* var); }; } // namespace maplefe diff --git a/src/MapleFE/ast2cpp/src/cpp_definition.cpp b/src/MapleFE/ast2cpp/src/cpp_definition.cpp index 3bf7f1d473..23a8d30dff 100644 --- a/src/MapleFE/ast2cpp/src/cpp_definition.cpp +++ b/src/MapleFE/ast2cpp/src/cpp_definition.cpp @@ -406,7 +406,7 @@ std::string CppDef::EmitDirectFieldInit(std::string varName, StructLiteralNode* auto lit = field->GetLiteral(); std::string fieldName = EmitTreeNode(field->GetFieldName()); std::string fieldVal = EmitTreeNode(lit); - if (false) // TODO: Check if it accesses a Cxx class field + if (mHandler->IsCppField(field)) // Check if it accesses a Cxx class field str += tab(1) + varName + "->"s + fieldName + " = "s + fieldVal + ";\n"s; else str += tab(1) + "(*"s + varName + ")[\""s + fieldName + "\"] = "s + fieldVal + ";\n"s; @@ -415,7 +415,7 @@ std::string CppDef::EmitDirectFieldInit(std::string varName, StructLiteralNode* return str; } -std::string CppDef::EmitObjPropInit(std::string varName, TreeNode* varIdType, StructLiteralNode* node) { +std::string CppDef::EmitObjPropInit(TreeNode* var, std::string varName, TreeNode* varIdType, StructLiteralNode* node) { if (varName.empty()) return std::string(); @@ -426,11 +426,10 @@ std::string CppDef::EmitObjPropInit(std::string varName, TreeNode* varIdType, St if (userType == nullptr) { // no type info - create instance of builtin t2crt::Object with proplist str = varName+ " = t2crt::Object_ctor._new("s + EmitTreeNode(node) + ")"s; - } else if (IsClassId(userType->GetId())) { - // user def class type + } else if (IsVarTypeClass(var)) { + // init var of type TS class // - create obj instance of user defined class and do direct field access init // - todo: handle class with generics - // - todo: generate addprop instead of direct field access if prop is not a field in class decl str = varName+ " = "s +userType->GetId()->GetName()+ "_ctor._new();\n"s; str += EmitDirectFieldInit(varName, node); } else { @@ -526,7 +525,7 @@ std::string CppDef::EmitDeclNode(DeclNode *node) { if (n->IsArrayLiteral()) str += varStr + " = " + EmitArrayLiteral(idType, n); else if (n->IsStructLiteral()) - str += EmitObjPropInit(varStr, idType, static_cast(n)); + str += EmitObjPropInit(node->GetVar(), varStr, idType, static_cast(n)); else if (node->GetVar()->IsIdentifier() && n->IsIdentifier() && n->IsTypeIdClass()) str += varStr + "= &"s + n->GetName() + "_ctor"s; // init with ctor address else if (n->IsFunction()) { @@ -981,18 +980,6 @@ std::string CppDef::EmitBracketNotationProp(ArrayElementNode* ae, OprId binOpId, return str; } -// return true if identifier is a class -bool CppDef::IsClassId(TreeNode* node) { - if (node != nullptr && - node->IsIdentifier() && - node->IsTypeIdClass() && - mHandler->FindDecl(static_cast(node)) && - mHandler->FindDecl(static_cast(node))->IsClass()) - return true; - else - return false; -} - std::string CppDef::EmitBinOperatorNode(BinOperatorNode *node) { if (node == nullptr) return std::string(); diff --git a/src/MapleFE/ast2cpp/src/cpp_emitter.cpp b/src/MapleFE/ast2cpp/src/cpp_emitter.cpp index d770142bfe..efdf178a6c 100644 --- a/src/MapleFE/ast2cpp/src/cpp_emitter.cpp +++ b/src/MapleFE/ast2cpp/src/cpp_emitter.cpp @@ -98,4 +98,28 @@ std::string CppEmitter::GetQualifiedName(IdentifierNode *node) { return ns.empty() ? name : ns + "::"s + name; } +// Returns true if identifier is a class +bool CppEmitter::IsClassId(TreeNode* node) { + if (node == nullptr || !node->IsIdentifier()) + return false; + if (auto decl = mHandler->FindDecl(static_cast(node), true)) { // deep, cross module lookup + if (decl->IsClass()) + return true; + // TODO: handle type alias + } + return false; +} + +// Returns true if the declared type of a var is a TS class +bool CppEmitter::IsVarTypeClass(TreeNode* var) { + if (var == nullptr) + return false; + if (auto n = gTypeTable.GetTypeFromTypeIdx(var->GetTypeIdx())) { + if (n->IsClass()) + return true; + } + return false; +} + + } // namespace maplefe -- Gitee From 1da15001dfd44968ca47c1baf21027f503282419 Mon Sep 17 00:00:00 2001 From: eching Date: Wed, 5 Jan 2022 19:48:21 -0800 Subject: [PATCH 6/9] Add declaration for JS class object constructor in generated .h file --- src/MapleFE/ast2cpp/src/cpp_declaration.cpp | 22 +++++++++++---------- src/MapleFE/ast2cpp/src/cpp_definition.cpp | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/MapleFE/ast2cpp/src/cpp_declaration.cpp b/src/MapleFE/ast2cpp/src/cpp_declaration.cpp index 8272ffefe6..4a53c953c5 100644 --- a/src/MapleFE/ast2cpp/src/cpp_declaration.cpp +++ b/src/MapleFE/ast2cpp/src/cpp_declaration.cpp @@ -755,15 +755,16 @@ std::string CppDecl::EmitClassNode(ClassNode *node) { if (node == nullptr) return std::string(); + std::string clsName = node->GetName(); // 1. c++ class for JS object base = (node->GetSuperClassesNum() != 0)? node->GetSuperClass(0)->GetName() : "t2crt::Object"; - str += "class "s + node->GetName() + " : public "s + base + " {\n"s; + str += "class "s + clsName + " : public "s + base + " {\n"s; str += "public:\n"; // constructor decl - str += " "s + node->GetName() + "(t2crt::Function* ctor, t2crt::Object* proto);\n"s; - str += " ~"s + node->GetName() + "(){}\n"; + str += " "s + clsName + "(t2crt::Function* ctor, t2crt::Object* proto);\n"s; + str += " ~"s + clsName + "(){}\n"; // class field decl and init. TODO: handle private, protected attrs. for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { @@ -776,8 +777,8 @@ std::string CppDecl::EmitClassNode(ClassNode *node) { IdentifierNode* id = static_cast(n); if (HasAttrStatic(id)) { // static field - add field to ctor prop and init later at field def in cpp - staticProps += tab(3) + "this->AddProp(\""s + n->GetName() + "\", t2crt::JS_Val("s + - TypeIdToJSTypeCXX[n->GetTypeId()] + ", &"s + node->GetName() + "::"s + id->GetName() + "));\n"s; + staticProps += tab(3) + "this->AddProp(\""s + clsName + "\", t2crt::JS_Val("s + + TypeIdToJSTypeCXX[n->GetTypeId()] + ", &"s + clsName + "::"s + id->GetName() + "));\n"s; } else if (auto init = id->GetInit()) { if (init->IsArrayLiteral() && id->GetType() && id->GetType()->IsPrimArrayType()) { // Generate initializer for t2crt::Array member field decl in header file @@ -809,7 +810,7 @@ std::string CppDecl::EmitClassNode(ClassNode *node) { for (unsigned i = 0; i < node->GetConstructorsNum(); ++i) { std::string ctor; if (auto c = node->GetConstructor(i)) { - ctor = indent + " "s + node->GetName() + "* operator()("s + node->GetName() + "* obj"s; + ctor = indent + " "s + clsName + "* operator()("s + clsName + "* obj"s; for (unsigned k = 0; k < c->GetParamsNum(); ++k) { ctor += ", "s; if (auto n = c->GetParam(k)) { @@ -823,13 +824,14 @@ std::string CppDecl::EmitClassNode(ClassNode *node) { // Generate decl for default constructor function if none declared for class if (node->GetConstructorsNum() == 0) - str += indent + " "s + node->GetName() + "* operator()("s + node->GetName() + "* obj);\n"s; + str += indent + " "s + clsName + "* operator()("s + clsName + "* obj);\n"s; // Generate new() function - str += indent + " "s+node->GetName()+"* _new() {return new "s+node->GetName()+"(this, this->prototype);}\n"s; - str += indent + " virtual const char* __GetClassName() const {return \""s + node->GetName() + " \";}\n"s; + str += indent + " "s+clsName+"* _new() {return new "s+clsName+"(this, this->prototype);}\n"s; + str += indent + " virtual const char* __GetClassName() const {return \""s + clsName + " \";}\n"s; str += indent + "};\n"; - str += "};\n\n"; + str += "};\n"; + str += "extern " + clsName + "::Ctor "s + clsName + "_ctor;\n"s; // emit declaration for JS class object constructor return str; } diff --git a/src/MapleFE/ast2cpp/src/cpp_definition.cpp b/src/MapleFE/ast2cpp/src/cpp_definition.cpp index 23a8d30dff..85f391f612 100644 --- a/src/MapleFE/ast2cpp/src/cpp_definition.cpp +++ b/src/MapleFE/ast2cpp/src/cpp_definition.cpp @@ -30,8 +30,8 @@ std::string CppDef::EmitCtorInstance(ClassNode *c) { prototypeProto = proto + ".prototype"s; proto.insert(0, "&"s, 0, std::string::npos); } - str = "\n// Instantiate constructor\n"s; - str += thisClass + "::Ctor "s + thisClass+"_ctor("s +ctor+","s+proto+","+prototypeProto+");\n"s; + str = "\n// Instantiate constructor for class "+ thisClass+ "\n"s; + str += thisClass + "::Ctor "s + thisClass+"_ctor("s +ctor+","s+proto+","+prototypeProto+");\n\n"s; // piggy back generation of static field definition for (unsigned i = 0; i < c->GetFieldsNum(); ++i) { -- Gitee From 075b9be62baa5efa88922e580b73af60288ae5b8 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Thu, 6 Jan 2022 11:32:40 -0500 Subject: [PATCH 7/9] add isAliasType(TreeNode *node) --- src/MapleFE/astopt/src/ast_scp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MapleFE/astopt/src/ast_scp.cpp b/src/MapleFE/astopt/src/ast_scp.cpp index 126a95b1b3..cd2f46565c 100644 --- a/src/MapleFE/astopt/src/ast_scp.cpp +++ b/src/MapleFE/astopt/src/ast_scp.cpp @@ -490,6 +490,9 @@ TypeAliasNode *BuildScopeVisitor::VisitTypeAliasNode(TypeAliasNode *node) { if (ut->IsUserType()) { TreeNode *id = static_cast(ut)->GetId(); AddDecl(scope, id); + + // add to Alias type + mHandler->AddAliasType(id->GetNodeId()); } return node; } -- Gitee From 24f8420382a1e447d2c2decef29602ed3fdf6da0 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Thu, 6 Jan 2022 16:05:45 -0500 Subject: [PATCH 8/9] add isAliasType() header file --- src/MapleFE/astopt/include/ast_handler.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/MapleFE/astopt/include/ast_handler.h b/src/MapleFE/astopt/include/ast_handler.h index a0a2494149..90949a367f 100644 --- a/src/MapleFE/astopt/include/ast_handler.h +++ b/src/MapleFE/astopt/include/ast_handler.h @@ -131,6 +131,8 @@ class Module_Handler { std::unordered_map mArrayDeclId2EleTypeIdMap; // fields' nodeid set std::unordered_set mDirectFieldSet; + // alias type, identifier node id + std::unordered_set mAliasTypeSet; public: explicit Module_Handler(unsigned f) : @@ -214,6 +216,12 @@ class Module_Handler { mNodeId2Decl[nid] = node; } + void AddAliasType(unsigned nid) { mAliasTypeSet.insert(nid); } + bool isAliasType(unsigned nid) { + return mAliasTypeSet.find(nid) != mAliasTypeSet.end(); + } + bool isAliasType(TreeNode *node) { return isAliasType(node->GetNodeId()); } + template T *NewTreeNode() { T *node = (T*)gTreePool.NewTreeNode(sizeof(T)); -- Gitee From f0c8c6041aadd860509afb5169e9cff5f4a970c2 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Thu, 6 Jan 2022 17:34:10 -0500 Subject: [PATCH 9/9] move FindPreprocessorKeywordToken() from lexer.h to token.h together with similar functions --- src/MapleFE/shared/include/lexer.h | 2 -- src/MapleFE/shared/include/token.h | 1 + src/MapleFE/shared/src/lexer.cpp | 19 ------------------- src/MapleFE/shared/src/parser.cpp | 2 +- src/MapleFE/shared/src/token.cpp | 19 +++++++++++++++++++ 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/MapleFE/shared/include/lexer.h b/src/MapleFE/shared/include/lexer.h index b71d2246ff..380d8ed41b 100644 --- a/src/MapleFE/shared/include/lexer.h +++ b/src/MapleFE/shared/include/lexer.h @@ -140,8 +140,6 @@ public: //void PlantTraverseRuleTable(RuleTable*); //void PlantTraverseTableData(TableData*); - Token* FindPreprocessorKeywordToken(const char *key); - // When we start walk a rule table to find a token, do we need check if // the following data is a separator? bool mCheckSeparator; diff --git a/src/MapleFE/shared/include/token.h b/src/MapleFE/shared/include/token.h index e3d3d00e70..5eef894505 100644 --- a/src/MapleFE/shared/include/token.h +++ b/src/MapleFE/shared/include/token.h @@ -163,6 +163,7 @@ struct Token { Token* FindSeparatorToken(SepId id); Token* FindOperatorToken(OprId id); Token* FindKeywordToken(const char *key); + Token* FindPreprocessorKeywordToken(const char *key); Token* FindCommentToken(); } diff --git a/src/MapleFE/shared/src/lexer.cpp b/src/MapleFE/shared/src/lexer.cpp index 2a13c3a2ca..89460e331b 100644 --- a/src/MapleFE/shared/src/lexer.cpp +++ b/src/MapleFE/shared/src/lexer.cpp @@ -135,25 +135,6 @@ void Lexer::PrepareForString(const char *str) { endoffile = false; } -// The caller of this function makes sure 'key' is already in the -// string pool of Lexer. -Token* Lexer::FindPreprocessorKeywordToken(const char *key) { - Token *token = NULL; - bool found = false; - for (unsigned i = gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum; - i < gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum + gPreprocessorKeywordTokensNum; - i++) { - token = &gSystemTokens[i]; - MASSERT(token->mTkType == TT_PKW); - if (strlen(key) == strlen(token->GetName()) && - !strncmp(key, token->GetName(), strlen(key))) { - found = true; - break; - } - } - return found && token ? token : NULL; -} - ///////////////////////////////////////////////////////////////////////////// // Both ClearLeadingNewLine() and AddEndingNewLine() will later be implemented // as language specific, and they will be overriding functions. diff --git a/src/MapleFE/shared/src/parser.cpp b/src/MapleFE/shared/src/parser.cpp index 10ef502f77..d13dc648a4 100644 --- a/src/MapleFE/shared/src/parser.cpp +++ b/src/MapleFE/shared/src/parser.cpp @@ -357,7 +357,7 @@ bool Parser::HandlePreprocessorToken(Token *t) { return false; } - Token *pt = mLexer->FindPreprocessorKeywordToken(t->mData.mName); + Token *pt = FindPreprocessorKeywordToken(t->mData.mName); if (pt == nullptr) return false; diff --git a/src/MapleFE/shared/src/token.cpp b/src/MapleFE/shared/src/token.cpp index 31ec87121e..b647225d10 100644 --- a/src/MapleFE/shared/src/token.cpp +++ b/src/MapleFE/shared/src/token.cpp @@ -226,6 +226,25 @@ Token* FindKeywordToken(const char *key) { return token; } +// The caller of this function makes sure 'key' is already in the +// string pool of Lexer. +Token* FindPreprocessorKeywordToken(const char *key) { + Token *token = NULL; + bool found = false; + for (unsigned i = gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum; + i < gOperatorTokensNum + gSeparatorTokensNum + gKeywordTokensNum + gPreprocessorKeywordTokensNum; + i++) { + token = &gSystemTokens[i]; + MASSERT(token->mTkType == TT_PKW); + if (strlen(key) == strlen(token->GetName()) && + !strncmp(key, token->GetName(), strlen(key))) { + found = true; + break; + } + } + return found && token ? token : NULL; +} + // CommentToken is the last predefined token Token* FindCommentToken() { Token *token = &gSystemTokens[gSystemTokensNum - 1]; -- Gitee