From 14b058793446f0103c120ac5315bd5d605f6f99a Mon Sep 17 00:00:00 2001 From: eching Date: Thu, 10 Feb 2022 14:12:22 -0800 Subject: [PATCH 01/10] Generator and generator function related clarifications and class updates. --- .../ast2cpp/runtime/include/builtins.h | 77 +++++++++++++++---- src/MapleFE/ast2cpp/runtime/include/ts2cpp.h | 10 ++- src/MapleFE/ast2cpp/runtime/src/builtins.cpp | 2 +- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/MapleFE/ast2cpp/runtime/include/builtins.h b/src/MapleFE/ast2cpp/runtime/include/builtins.h index 8eea79172d..0e09a4eacc 100644 --- a/src/MapleFE/ast2cpp/runtime/include/builtins.h +++ b/src/MapleFE/ast2cpp/runtime/include/builtins.h @@ -118,40 +118,91 @@ public: static Ctor ctor; }; + +// JavaScript generators and generator functions +// - The builtin GeneratorFunction is the constructor for all generator functions. +// - Generator functions are called directly to return generators (with closure). +// - Generators are iterators that calls corresponding generator function with +// data captured in closure to iterate for results. + +// ecma-262 section references are based on ecma-262 edition 12.0 + +// ecma262 27.1.1.5 IteratorResult interface: +struct IteratorResult { + bool _done; // status of iterator next() call + JS_Val _value; // done=false: current iteration element value + // done=true: return value of the iterator, undefined if none returned + IteratorResult() : _done(true), _value(undefined) { } + IteratorResult(bool done, JS_Val val) : _done(done), _value(val) { } + ~IteratorResult() { } +}; + +// ecma262 27.1.1.1 Iterable interface: +// To be iterable, an object or one of the objects up its prototype chain must +// have a property with a @@iterator key ([Symbol.iterator], the value of +// which is a function that returns iterators (i.e objects with Iterator interace +// methods next/return/throw). +// +// Note: For iterable objects such as arrays and strings, [Symbol.iterator]() +// returns a new iteraor object. But for the intrinsic object %IteratorPrototype% +// (27.1.2.1) it returns the current iterator instance, which +// means for all iterators, [Sumbol.iterator]() returns itself. + +// ecma262 27.1.2.1 %IteratorPrototype%: +// 1) All objects that implement iterator interface also inherit from %IteratorPrototype% +// 2) %IteratorPrototype% provides shared props for all iterator objects +// 3) %IteratorPrototype%[Symbol.iterator]() = this (current iterator instance) class IteratorProto : public Object { public: - // TODO IteratorProto(Function* ctor, Object* proto) : Object(ctor, proto) { } -}; + ~IteratorProto() { } + // note: arg passed to _next() should be ignored on iterator's 1st _next() call per spec + virtual IteratorResult _next(JS_Val arg) { return IteratorResult(); } + virtual IteratorResult _return(JS_Val val) { return IteratorResult(); } + virtual IteratorResult _throw() { return IteratorResult(); } -class GeneratorFunctionPrototype : public Function { -public: - GeneratorFunctionPrototype(Function* ctor, Object* proto, Object* prototype_proto) : Function(ctor, proto, prototype_proto) { } + // TODO: %IteratorPrototype%[Symbol.iterator]() = this (current iterator instance) }; - +// 27.5.1 Generator Prototype Object +// - in ecma edition 11: named %GeneratorPrototype% (25.4.1) +// - in ecma edition 12: named %GeneratorFunction.prototype.prototype% (27.5.1) but +// labelled as %GeneratoPrototype% in 27.3 Figure 5. +// Label corrected in version at tc39. class GeneratorProto : public IteratorProto { public: - // TODO GeneratorProto(Function* ctor, Object* proto) : IteratorProto(ctor, proto) { } + ~GeneratorProto() { } + bool _completed = false; // flag if generator is in completed state }; +// 27.3.1 GeneratorFunction Constructor class GeneratorFunc : public Function::Ctor { public: - // TODO GeneratorFunc(Function* ctor, Object* proto, Object* prototype_proto, Function* prototype_obj) : Function::Ctor(ctor, proto, prototype_proto, prototype_obj) { } + ~GeneratorFunc() {} +}; + +// 27.3.3 GeneratorFunction Prototype Obejct +// - in ecma edition 11: named %Generator% (25.2.3) +// - in ecma edition 12: named %GeneratorFunction.prorotype% (27.3.3) but +// labelled as %Generator% in 27.3 Figure 5. +// Label corrected in tc39 version. +class GeneratorFuncPrototype : public Function { +public: + GeneratorFuncPrototype(Function* ctor, Object* proto, Object* prototype_proto) : Function(ctor, proto, prototype_proto) { } }; -// GeneratorFunction objects. (Ref: ECMA spec 27.3) +// Generator related intrinsic objects. (ecma 27.3) // IteratorPrototype: It is not a prototype object of any constructor func, but holds shared properties for iterators -// GeneratorFunction: A builtin function used as the constructor for generators (i.e. generator functions).// -// Generator: (a.k.a. GeneratorFuncion.prototype in 2022 spec) is the prototype object of GeneratorFunction, +// GeneratorFunction: A builtin function used as the constructor for generator functions. +// Generator: (GeneratorFuncion.prototype in edition 12.0) is the prototype object of GeneratorFunction, // It is a special object used as both prototype object and constructor - as prototype for sharing // properties between generator functions, and as constructor whose prototype object (GeneratorPrototype -// in pre-2022 spec) holds shared properties for instances returned by generator functions. +// in edition 11) holds shared properties for generators (i.e. instances returned by generator functions. extern IteratorProto IteratorPrototype; extern GeneratorFunc GeneratorFunction; -extern GeneratorFunctionPrototype Generator; +extern GeneratorFuncPrototype Generator; extern Object* GeneratorPrototype; } // namespace t2crt diff --git a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h index e88bce6fca..29a40236fe 100644 --- a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h +++ b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h @@ -445,6 +445,11 @@ void GenerateDOTGraph( std::vector&obj, std::vector&name) } // namespace t2crt +extern std::ostream& operator<< (std::ostream& out, const t2crt::JS_Val& v); +extern std::ostream& operator<< (std::ostream& out, t2crt::Object* obj); +extern const t2crt::JS_Val undefined; +extern const t2crt::JS_Val null; + #include "builtins.h" template @@ -491,10 +496,7 @@ std::ostream& operator<< (std::ostream& out, const t2crt::Array& v) { } return out; } -extern std::ostream& operator<< (std::ostream& out, const t2crt::JS_Val& v); -extern std::ostream& operator<< (std::ostream& out, t2crt::Object* obj); -extern const t2crt::JS_Val undefined; -extern const t2crt::JS_Val null; + #define debugger (0) using t2crt::Object; diff --git a/src/MapleFE/ast2cpp/runtime/src/builtins.cpp b/src/MapleFE/ast2cpp/runtime/src/builtins.cpp index 8537db1295..43f6dd65fb 100644 --- a/src/MapleFE/ast2cpp/runtime/src/builtins.cpp +++ b/src/MapleFE/ast2cpp/runtime/src/builtins.cpp @@ -8,7 +8,7 @@ Number::Ctor Number::ctor (&Function::ctor, Function::ctor.prototype, Object: RegExp::Ctor RegExp::ctor (&Function::ctor, Function::ctor.prototype, Object::ctor.prototype); IteratorProto IteratorPrototype(&Object::ctor, Object::ctor.prototype); -GeneratorFunctionPrototype Generator(&GeneratorFunction, Function::ctor.prototype, &IteratorPrototype); +GeneratorFuncPrototype Generator(&GeneratorFunction, Function::ctor.prototype, &IteratorPrototype); GeneratorFunc GeneratorFunction(&Function::ctor, &Function::ctor, Function::ctor.prototype, &Generator); Object* GeneratorPrototype = Generator.prototype; -- Gitee From 2a0c1ec0eaabbcc3d104a873a6d6f35668261f66 Mon Sep 17 00:00:00 2001 From: yehandong Date: Fri, 11 Feb 2022 14:08:32 -0800 Subject: [PATCH 02/10] Handle more cases of AutoSemicolonInsert. --- .../unit_tests/semicolon-missing14.ts | 21 ++++++++++ .../unit_tests/semicolon-missing14.ts.result | 38 +++++++++++++++++++ src/MapleFE/typescript/src/lang_spec.cpp | 14 ++++++- 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts create mode 100644 src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts.result diff --git a/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts b/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts new file mode 100644 index 0000000000..2311369e56 --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts @@ -0,0 +1,21 @@ +class Car { + private _make: string; + constructor(make: string) { + this._make = make; + } + public getMake(): string { + return this._make; + } +} + +class Model extends Car { + private _model: string; + constructor(make: string, model: string) {super(make) this._model = super.getMake() + model; + } + public getModel(): string { + return this._model; + } +} + +let passat: Model = new Model("VW", "Passat"); +console.log(passat.getMake(), passat.getModel()); diff --git a/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts.result b/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts.result new file mode 100644 index 0000000000..5368fc30da --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/semicolon-missing14.ts.result @@ -0,0 +1,38 @@ +Matched 36 tokens. +Matched 88 tokens. +Matched 101 tokens. +Matched 118 tokens. +============= Module =========== +== Sub Tree == +class Car + Fields: + _make + Instance Initializer: + Constructors: + constructor (make) throws: + this._make Assign make + Methods: + func getMake() throws: + return this._make + LocalClasses: + LocalInterfaces: + +== Sub Tree == +class Model + Fields: + _model + Instance Initializer: + Constructors: + constructor (make,model) throws: + super(make) + this._model Assign super.getMake() Add model + Methods: + func getModel() throws: + return this._model + LocalClasses: + LocalInterfaces: + +== Sub Tree == +js_let Decl: passat=new Model("VW","Passat") +== Sub Tree == +console.log(passat.getMake(),passat.getModel()) diff --git a/src/MapleFE/typescript/src/lang_spec.cpp b/src/MapleFE/typescript/src/lang_spec.cpp index b585ae76c7..b2022817b9 100644 --- a/src/MapleFE/typescript/src/lang_spec.cpp +++ b/src/MapleFE/typescript/src/lang_spec.cpp @@ -585,14 +585,24 @@ bool TypescriptParser::TraverseASI(RuleTable *rule_table, // case 3. This is a special case we want to catch: // foo(x) a=b; <-- , is missing before a=b + // { foo(x) a=b; } <-- , is missing before a=b // There could be many more similar cases, but we just match this special one in our // unit test. We don't encourage people write weird code. if ( (curr_token->IsIdentifier() || curr_token->IsKeyword()) && - (prev_token->IsSeparator() && (prev_token->GetSepId() == SEP_Rparen)) ){ + (prev_token->IsSeparator() && (prev_token->GetSepId() == SEP_Rparen)) && + mActiveTokens.GetNum() > 4 ){ Token *prev_2_token = GetActiveToken(mCurToken - 2); Token *prev_3_token = GetActiveToken(mCurToken - 3); Token *prev_4_token = GetActiveToken(mCurToken - 4); - if ( prev_4_token->mLineBegin && + + bool lbrace_ok = false; + if (mActiveTokens.GetNum() > 5){ + Token *prev_5_token = GetActiveToken(mCurToken - 5); + if (prev_5_token->IsSeparator() && (prev_5_token->GetSepId() == SEP_Lbrace)) + lbrace_ok = true; + } + + if ( (prev_4_token->mLineBegin || lbrace_ok) && (prev_4_token->IsIdentifier() || prev_4_token->IsKeyword()) && (prev_2_token->IsIdentifier() || prev_2_token->IsKeyword()) && (prev_3_token->IsSeparator() && (prev_3_token->GetSepId() == SEP_Lparen)) ){ -- Gitee From ed78a8476a80b0f91765cf1b9908d8bfe821e925 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Mon, 14 Feb 2022 12:59:38 -0500 Subject: [PATCH 03/10] search exported decls --- src/MapleFE/astopt/src/ast_handler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/MapleFE/astopt/src/ast_handler.cpp b/src/MapleFE/astopt/src/ast_handler.cpp index 6d6bd0b0ce..eb6043f87f 100644 --- a/src/MapleFE/astopt/src/ast_handler.cpp +++ b/src/MapleFE/astopt/src/ast_handler.cpp @@ -200,6 +200,10 @@ TreeNode *Module_Handler::FindDecl(IdentifierNode *node, bool deep) { decl = scope->FindDeclOf(stridx); } + if (!decl && deep) { + decl = scope->FindExportedDeclOf(stridx); + } + if (decl) { AddNodeId2DeclMap(node->GetNodeId(), decl); } -- Gitee From 05efa92bb5abb28ba890a50e7ffe72006ebd66e0 Mon Sep 17 00:00:00 2001 From: yehandong Date: Mon, 14 Feb 2022 11:48:36 -0800 Subject: [PATCH 04/10] Adjust A[i] to become a type casting on A[i]. It was casting on A instead of A[i]. --- src/MapleFE/typescript/stmt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MapleFE/typescript/stmt.spec b/src/MapleFE/typescript/stmt.spec index 9e9f222ae6..cd2e72c5a8 100644 --- a/src/MapleFE/typescript/stmt.spec +++ b/src/MapleFE/typescript/stmt.spec @@ -390,7 +390,7 @@ rule MemberExpression : ONEOF( MemberExpression + '[' + KeyOf + ']', MemberExpression + '!', MemberExpression + '.' + JSIdentifier + "as" + "const", - '<' + Type + '>' + PrimaryExpression, + '<' + Type + '>' + MemberExpression, PrimaryExpression + "as" + "const", MemberExpression + '.' + KeywordPropName) attr.action.%1 : AddAsType(%1, %2) -- Gitee From ea9392e2e32b5725b42f768588daaa16ee2cbc09 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Mon, 14 Feb 2022 16:51:26 -0500 Subject: [PATCH 05/10] handle arraytype for array using Array --- src/MapleFE/astopt/src/ast_adj.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/MapleFE/astopt/src/ast_adj.cpp b/src/MapleFE/astopt/src/ast_adj.cpp index f5948760a4..2d11fd2014 100644 --- a/src/MapleFE/astopt/src/ast_adj.cpp +++ b/src/MapleFE/astopt/src/ast_adj.cpp @@ -179,11 +179,31 @@ UserTypeNode *AdjustASTVisitor::VisitUserTypeNode(UserTypeNode *node) { // use array type node DimensionNode *dim = node->GetDims(); + bool isarr = (dim != NULL); + // element type + TreeNode *etype = NULL; + + if (isarr) { + etype = node; + } else if (id && id->IsIdentifier()) { + IdentifierNode *idnode = static_cast(id); + isarr = (idnode->GetStrIdx() == gStringPool.GetStrIdx("Array")); + if (isarr) { + if (unsigned s = node->GetTypeGenericsNum()) { + if (s == 1) { + etype = node->GetTypeGeneric(0); + } else { + NOTYETIMPL("array usertype with multiple generic type"); + } + } + } + } + TreeNode *p = node->GetParent(); - if (dim && p->IsIdentifier()) { + if (isarr && p->IsIdentifier()) { ArrayTypeNode *arr = mHandler->NewTreeNode(); arr->SetDims(dim); - arr->SetElemType(node); + arr->SetElemType(etype); node->SetDims(NULL); IdentifierNode *inode = static_cast(p); inode->SetType(arr); -- Gitee From 6d3eb0c80f32e9a230b42b8fff7bd51da62c9428 Mon Sep 17 00:00:00 2001 From: Ed Ching Date: Mon, 14 Feb 2022 18:10:16 -0800 Subject: [PATCH 06/10] Update runtime interface for generators and generator functions for cpp emitter. --- .../ast2cpp/runtime/include/builtins.h | 20 +++++++++++++------ src/MapleFE/ast2cpp/runtime/include/ts2cpp.h | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/MapleFE/ast2cpp/runtime/include/builtins.h b/src/MapleFE/ast2cpp/runtime/include/builtins.h index 0e09a4eacc..d5aa30f5ec 100644 --- a/src/MapleFE/ast2cpp/runtime/include/builtins.h +++ b/src/MapleFE/ast2cpp/runtime/include/builtins.h @@ -119,6 +119,11 @@ public: }; +// 20.5 Error objects for execptions +class Error : public Object { + // TODO +}; + // JavaScript generators and generator functions // - The builtin GeneratorFunction is the constructor for all generator functions. // - Generator functions are called directly to return generators (with closure). @@ -151,15 +156,15 @@ struct IteratorResult { // ecma262 27.1.2.1 %IteratorPrototype%: // 1) All objects that implement iterator interface also inherit from %IteratorPrototype% // 2) %IteratorPrototype% provides shared props for all iterator objects -// 3) %IteratorPrototype%[Symbol.iterator]() = this (current iterator instance) +// 3) %IteratorPrototype%[Symbol.iterator]() = this (current iterator instance) - used in for loops class IteratorProto : public Object { public: IteratorProto(Function* ctor, Object* proto) : Object(ctor, proto) { } ~IteratorProto() { } - // note: arg passed to _next() should be ignored on iterator's 1st _next() call per spec - virtual IteratorResult _next(JS_Val arg) { return IteratorResult(); } - virtual IteratorResult _return(JS_Val val) { return IteratorResult(); } - virtual IteratorResult _throw() { return IteratorResult(); } + // note: the arg on an iterator's 1st next() call is ignored per spec 27.5.1.2 + virtual IteratorResult _next(JS_Val* arg) { return IteratorResult(); } + virtual IteratorResult _return(JS_Val* val) { return IteratorResult(); } + virtual IteratorResult _throw(Error exception) { return IteratorResult(); } // TODO: %IteratorPrototype%[Symbol.iterator]() = this (current iterator instance) }; @@ -173,7 +178,10 @@ class GeneratorProto : public IteratorProto { public: GeneratorProto(Function* ctor, Object* proto) : IteratorProto(ctor, proto) { } ~GeneratorProto() { } - bool _completed = false; // flag if generator is in completed state + void* _yield = nullptr; // pointer to yield label to resume execution + bool _finished = false; // flag if generator is in finished state + bool _firstNext = true; // flag if first next has been called on iterator (27.5.1.2) + JS_Val _retval = undefined; // save optional arg from iterator's return(arg) method }; // 27.3.1 GeneratorFunction Constructor diff --git a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h index 29a40236fe..5318a3c22f 100644 --- a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h +++ b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h @@ -82,6 +82,9 @@ struct JS_Val { JS_Type type; bool IsCxxProp() { return type & TY_CXX; } // true if a cxx field + bool IsNone() { return type == TY_None; } + bool IsNull() { return type & TY_Null; } + bool IsUndef() { return type & TY_Undef; } JS_Val() { x.val_long = 0l; type = TY_Undef; } JS_Val(int64_t l, JS_Type t, bool c) { x.val_long = l; type = t; } -- Gitee From 9afd8f1761ddf38c1af1912a06bed296dd72889c Mon Sep 17 00:00:00 2001 From: Wen HU Date: Tue, 15 Feb 2022 11:37:26 -0500 Subject: [PATCH 07/10] unify prim array type node to array type node --- src/MapleFE/astopt/include/ast_adj.h | 1 + src/MapleFE/astopt/src/ast_adj.cpp | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/MapleFE/astopt/include/ast_adj.h b/src/MapleFE/astopt/include/ast_adj.h index 04be9e8d36..5674e6678d 100644 --- a/src/MapleFE/astopt/include/ast_adj.h +++ b/src/MapleFE/astopt/include/ast_adj.h @@ -78,6 +78,7 @@ class AdjustASTVisitor : public AstVisitor { TypeAliasNode *VisitTypeAliasNode(TypeAliasNode *node); LiteralNode *VisitLiteralNode(LiteralNode *node); UnaOperatorNode *VisitUnaOperatorNode(UnaOperatorNode *node); + PrimArrayTypeNode *VisitPrimArrayTypeNode(PrimArrayTypeNode *node); }; } diff --git a/src/MapleFE/astopt/src/ast_adj.cpp b/src/MapleFE/astopt/src/ast_adj.cpp index 2d11fd2014..3a36e80d0f 100644 --- a/src/MapleFE/astopt/src/ast_adj.cpp +++ b/src/MapleFE/astopt/src/ast_adj.cpp @@ -169,6 +169,17 @@ StructNode *AdjustASTVisitor::VisitStructNode(StructNode *node) { return (StructNode*)newnode; } +// convert prim array node to array type node +PrimArrayTypeNode *AdjustASTVisitor::VisitPrimArrayTypeNode(PrimArrayTypeNode *node) { + (void) AstVisitor::VisitPrimArrayTypeNode(node); + ArrayTypeNode *arr = mHandler->NewTreeNode(); + DimensionNode *dim = node->GetDims(); + arr->SetDims(dim); + arr->SetElemType(node->GetPrim()); + + return (PrimArrayTypeNode *)arr; +} + // set UserTypeNode's mStrIdx to be its mId's UserTypeNode *AdjustASTVisitor::VisitUserTypeNode(UserTypeNode *node) { (void) AstVisitor::VisitUserTypeNode(node); @@ -199,16 +210,13 @@ UserTypeNode *AdjustASTVisitor::VisitUserTypeNode(UserTypeNode *node) { } } - TreeNode *p = node->GetParent(); - if (isarr && p->IsIdentifier()) { + if (isarr) { ArrayTypeNode *arr = mHandler->NewTreeNode(); arr->SetDims(dim); arr->SetElemType(etype); - node->SetDims(NULL); - IdentifierNode *inode = static_cast(p); - inode->SetType(arr); - mHandler->SetArrayElemTypeId(inode->GetNodeId(), id->GetTypeId()); + node = (UserTypeNode *)arr; } + return node; } -- Gitee From 1d6c0b426e3ba806060e89ed6ded2aeeff64ec90 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Tue, 15 Feb 2022 12:31:38 -0500 Subject: [PATCH 08/10] add dump for ArrayElemTypeIdMap --- src/MapleFE/astopt/include/ast_handler.h | 1 + src/MapleFE/astopt/src/ast_handler.cpp | 9 +++++++++ src/MapleFE/astopt/src/ast_ti.cpp | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/src/MapleFE/astopt/include/ast_handler.h b/src/MapleFE/astopt/include/ast_handler.h index fea8de93f6..b343f0131d 100644 --- a/src/MapleFE/astopt/include/ast_handler.h +++ b/src/MapleFE/astopt/include/ast_handler.h @@ -282,6 +282,7 @@ class Module_Handler { bool IsCppField(TreeNode *node); void Dump(char *msg); + void DumpArrayElemTypeIdMap(); }; } diff --git a/src/MapleFE/astopt/src/ast_handler.cpp b/src/MapleFE/astopt/src/ast_handler.cpp index eb6043f87f..7152a827d4 100644 --- a/src/MapleFE/astopt/src/ast_handler.cpp +++ b/src/MapleFE/astopt/src/ast_handler.cpp @@ -27,6 +27,7 @@ #include "ast_xxport.h" #include "astopt.h" #include "typetable.h" +#include "gen_astdump.h" namespace maplefe { @@ -270,4 +271,12 @@ void Module_Handler::Dump(char *msg) { func->Dump(); } +void Module_Handler::DumpArrayElemTypeIdMap() { + std::cout << "================= ArrayDeclId2EleTypeIdMap ==========" << std::endl; + for (auto it : mArrayDeclId2EleTypeIdMap) { + std::cout << "nodeid : " << it.first << + " " << AstDump::GetEnumTypeId(it.second) << std::endl; + } +} + } diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index cc2d1c69d6..e5bc786fbc 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -70,6 +70,10 @@ void TypeInfer::TypeInference() { MSGNOLOC0("============== Check Type =============="); CheckTypeVisitor visitor_check(mHandler, mFlags, true); visitor_check.Visit(module); + + if (mFlags & FLG_trace_3) { + mHandler->DumpArrayElemTypeIdMap(); + } } // build up mNodeId2Decl by visiting each Identifier -- Gitee From 88850d163ff88adb5dba3cd1baa462b092469054 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Wed, 16 Feb 2022 13:05:27 -0500 Subject: [PATCH 09/10] add API to query generator usage in Module_Handler void AddGeneratorUse(unsigned nid, FunctionNode *func); bool IsGeneratorUse(unsigned nid); FunctionNode *GetGeneratorUse(unsigned nid); void UpdateGeneratorUse(unsigned target, unsigned src); --- src/MapleFE/astopt/include/ast_handler.h | 50 ++++++------------- src/MapleFE/astopt/src/ast_handler.cpp | 63 +++++++++++++++++++++++- src/MapleFE/astopt/src/ast_ti.cpp | 9 ++++ 3 files changed, 84 insertions(+), 38 deletions(-) diff --git a/src/MapleFE/astopt/include/ast_handler.h b/src/MapleFE/astopt/include/ast_handler.h index b343f0131d..3dbd79ecf7 100644 --- a/src/MapleFE/astopt/include/ast_handler.h +++ b/src/MapleFE/astopt/include/ast_handler.h @@ -133,6 +133,8 @@ class Module_Handler { std::unordered_map mArrayDeclId2EleTypeIdxMap; // array literal's dim: decl node id to dim std::unordered_map mArrayDeclId2DimMap; + // nodeid to used generator + std::unordered_map mGeneratorUseMap; // fields' nodeid set std::unordered_set mDirectFieldSet; // alias type, identifier node id @@ -239,42 +241,18 @@ class Module_Handler { Module_Handler *GetModuleHandler(TreeNode *node) {return mASTHandler->GetModuleHandler(node);} // array's element typeid - TypeId GetArrayElemTypeId(unsigned nid) { - TypeId tid = TY_None; - if (mArrayDeclId2EleTypeIdMap.find(nid) != mArrayDeclId2EleTypeIdMap.end()) { - tid = mArrayDeclId2EleTypeIdMap[nid]; - } - return tid; - } - - void SetArrayElemTypeId(unsigned nid, TypeId tid) { - mArrayDeclId2EleTypeIdMap[nid] = tid; - } - - // array's element typeidx - unsigned GetArrayElemTypeIdx(unsigned nid) { - unsigned tidx = 0; - if (mArrayDeclId2EleTypeIdxMap.find(nid) != mArrayDeclId2EleTypeIdxMap.end()) { - tidx = mArrayDeclId2EleTypeIdxMap[nid]; - } - return tidx; - } - - void SetArrayElemTypeIdx(unsigned nid, unsigned tidx) { - mArrayDeclId2EleTypeIdxMap[nid] = tidx; - } - - DimensionNode *GetArrayDim(unsigned nid) { - DimensionNode *dim = NULL; - if (mArrayDeclId2DimMap.find(nid) != mArrayDeclId2DimMap.end()) { - dim = mArrayDeclId2DimMap[nid]; - } - return dim; - } - - void SetArrayDim(unsigned nid, DimensionNode *dim) { - mArrayDeclId2DimMap[nid] = dim; - } + TypeId GetArrayElemTypeId(unsigned nid); + void SetArrayElemTypeId(unsigned nid, TypeId tid); + unsigned GetArrayElemTypeIdx(unsigned nid); + void SetArrayElemTypeIdx(unsigned nid, unsigned tidx); + DimensionNode *GetArrayDim(unsigned nid); + void SetArrayDim(unsigned nid, DimensionNode *dim); + + // used generator + void AddGeneratorUse(unsigned nid, FunctionNode *func); + bool IsGeneratorUse(unsigned nid); + FunctionNode *GetGeneratorUse(unsigned nid); + void UpdateGeneratorUse(unsigned target, unsigned src); // API to check a node is c++ field which satisfy both: // 1. direct field diff --git a/src/MapleFE/astopt/src/ast_handler.cpp b/src/MapleFE/astopt/src/ast_handler.cpp index 7152a827d4..51b845e629 100644 --- a/src/MapleFE/astopt/src/ast_handler.cpp +++ b/src/MapleFE/astopt/src/ast_handler.cpp @@ -249,6 +249,65 @@ bool Module_Handler::IsDirectField(TreeNode *node) { return mDirectFieldSet.find(node->GetNodeId()) != mDirectFieldSet.end(); } +// array's element typeid +TypeId Module_Handler::GetArrayElemTypeId(unsigned nid) { + TypeId tid = TY_None; + if (mArrayDeclId2EleTypeIdMap.find(nid) != mArrayDeclId2EleTypeIdMap.end()) { + tid = mArrayDeclId2EleTypeIdMap[nid]; + } + return tid; +} + +void Module_Handler::SetArrayElemTypeId(unsigned nid, TypeId tid) { + mArrayDeclId2EleTypeIdMap[nid] = tid; +} + +// array's element typeidx +unsigned Module_Handler::GetArrayElemTypeIdx(unsigned nid) { + unsigned tidx = 0; + if (mArrayDeclId2EleTypeIdxMap.find(nid) != mArrayDeclId2EleTypeIdxMap.end()) { + tidx = mArrayDeclId2EleTypeIdxMap[nid]; + } + return tidx; +} + +void Module_Handler::SetArrayElemTypeIdx(unsigned nid, unsigned tidx) { + mArrayDeclId2EleTypeIdxMap[nid] = tidx; +} + +DimensionNode *Module_Handler::GetArrayDim(unsigned nid) { + DimensionNode *dim = NULL; + if (mArrayDeclId2DimMap.find(nid) != mArrayDeclId2DimMap.end()) { + dim = mArrayDeclId2DimMap[nid]; + } + return dim; +} + +void Module_Handler::SetArrayDim(unsigned nid, DimensionNode *dim) { + mArrayDeclId2DimMap[nid] = dim; +} + +void Module_Handler::AddGeneratorUse(unsigned nid, FunctionNode *func) { + mGeneratorUseMap[nid] = func; +} + +bool Module_Handler::IsGeneratorUse(unsigned nid) { + return (mGeneratorUseMap.find(nid) != mGeneratorUseMap.end()); +} + +FunctionNode *Module_Handler::GetGeneratorUse(unsigned nid) { + if (mGeneratorUseMap.find(nid) != mGeneratorUseMap.end()) { + return mGeneratorUseMap[nid]; + } + return NULL; +} + +void Module_Handler::UpdateGeneratorUse(unsigned target, unsigned src) { + if (mGeneratorUseMap.find(src) != mGeneratorUseMap.end()) { + mGeneratorUseMap[target] = mGeneratorUseMap[src]; + } +} + bool Module_Handler::IsFromLambda(TreeNode *node) { if (!node) { return false; @@ -274,8 +333,8 @@ void Module_Handler::Dump(char *msg) { void Module_Handler::DumpArrayElemTypeIdMap() { std::cout << "================= ArrayDeclId2EleTypeIdMap ==========" << std::endl; for (auto it : mArrayDeclId2EleTypeIdMap) { - std::cout << "nodeid : " << it.first << - " " << AstDump::GetEnumTypeId(it.second) << std::endl; + std::cout << "nodeid : " << it.first << " " + << AstDump::GetEnumTypeId(it.second) << std::endl; } } diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index e5bc786fbc..15dd8cd3b8 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -1056,6 +1056,10 @@ CallNode *TypeInferVisitor::VisitCallNode(CallNode *node) { if (decl) { if (decl->IsFunction()) { FunctionNode *func = static_cast(decl); + // check if called a generator + if (func->IsGenerator()) { + mHandler->AddGeneratorUse(node->GetNodeId(), func); + } // update call's return type if (func->GetType()) { UpdateTypeId(node, func->GetType()->GetTypeId()); @@ -1259,6 +1263,11 @@ DeclNode *TypeInferVisitor::VisitDeclNode(DeclNode *node) { elemTypeId = GetArrayElemTypeId(init); elemTypeIdx = GetArrayElemTypeIdx(init); isArray = (elemTypeId != TY_None); + // pass IsGeneratorUse + mHandler->UpdateGeneratorUse(node->GetNodeId(), init->GetNodeId()); + if (var) { + mHandler->UpdateGeneratorUse(var->GetNodeId(), init->GetNodeId()); + } } if (var) { // normal cases -- Gitee From 47e01b45aedbaa34feaf13891c821ab38a0aec48 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Wed, 16 Feb 2022 13:18:00 -0500 Subject: [PATCH 10/10] adjust API name --- src/MapleFE/astopt/include/ast_handler.h | 10 +++++----- src/MapleFE/astopt/src/ast_handler.cpp | 20 ++++++++++---------- src/MapleFE/astopt/src/ast_ti.cpp | 8 ++++---- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/MapleFE/astopt/include/ast_handler.h b/src/MapleFE/astopt/include/ast_handler.h index 3dbd79ecf7..fdeaa249df 100644 --- a/src/MapleFE/astopt/include/ast_handler.h +++ b/src/MapleFE/astopt/include/ast_handler.h @@ -134,7 +134,7 @@ class Module_Handler { // array literal's dim: decl node id to dim std::unordered_map mArrayDeclId2DimMap; // nodeid to used generator - std::unordered_map mGeneratorUseMap; + std::unordered_map mGeneratorUsedMap; // fields' nodeid set std::unordered_set mDirectFieldSet; // alias type, identifier node id @@ -249,10 +249,10 @@ class Module_Handler { void SetArrayDim(unsigned nid, DimensionNode *dim); // used generator - void AddGeneratorUse(unsigned nid, FunctionNode *func); - bool IsGeneratorUse(unsigned nid); - FunctionNode *GetGeneratorUse(unsigned nid); - void UpdateGeneratorUse(unsigned target, unsigned src); + void AddGeneratorUsed(unsigned nid, FunctionNode *func); + bool IsGeneratorUsed(unsigned nid); + FunctionNode *GetGeneratorUsed(unsigned nid); + void UpdateGeneratorUsed(unsigned target, unsigned src); // API to check a node is c++ field which satisfy both: // 1. direct field diff --git a/src/MapleFE/astopt/src/ast_handler.cpp b/src/MapleFE/astopt/src/ast_handler.cpp index 51b845e629..205cb110c6 100644 --- a/src/MapleFE/astopt/src/ast_handler.cpp +++ b/src/MapleFE/astopt/src/ast_handler.cpp @@ -287,24 +287,24 @@ void Module_Handler::SetArrayDim(unsigned nid, DimensionNode *dim) { mArrayDeclId2DimMap[nid] = dim; } -void Module_Handler::AddGeneratorUse(unsigned nid, FunctionNode *func) { - mGeneratorUseMap[nid] = func; +void Module_Handler::AddGeneratorUsed(unsigned nid, FunctionNode *func) { + mGeneratorUsedMap[nid] = func; } -bool Module_Handler::IsGeneratorUse(unsigned nid) { - return (mGeneratorUseMap.find(nid) != mGeneratorUseMap.end()); +bool Module_Handler::IsGeneratorUsed(unsigned nid) { + return (mGeneratorUsedMap.find(nid) != mGeneratorUsedMap.end()); } -FunctionNode *Module_Handler::GetGeneratorUse(unsigned nid) { - if (mGeneratorUseMap.find(nid) != mGeneratorUseMap.end()) { - return mGeneratorUseMap[nid]; +FunctionNode *Module_Handler::GetGeneratorUsed(unsigned nid) { + if (mGeneratorUsedMap.find(nid) != mGeneratorUsedMap.end()) { + return mGeneratorUsedMap[nid]; } return NULL; } -void Module_Handler::UpdateGeneratorUse(unsigned target, unsigned src) { - if (mGeneratorUseMap.find(src) != mGeneratorUseMap.end()) { - mGeneratorUseMap[target] = mGeneratorUseMap[src]; +void Module_Handler::UpdateGeneratorUsed(unsigned target, unsigned src) { + if (mGeneratorUsedMap.find(src) != mGeneratorUsedMap.end()) { + mGeneratorUsedMap[target] = mGeneratorUsedMap[src]; } } diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index 15dd8cd3b8..d69b053d62 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -1058,7 +1058,7 @@ CallNode *TypeInferVisitor::VisitCallNode(CallNode *node) { FunctionNode *func = static_cast(decl); // check if called a generator if (func->IsGenerator()) { - mHandler->AddGeneratorUse(node->GetNodeId(), func); + mHandler->AddGeneratorUsed(node->GetNodeId(), func); } // update call's return type if (func->GetType()) { @@ -1263,10 +1263,10 @@ DeclNode *TypeInferVisitor::VisitDeclNode(DeclNode *node) { elemTypeId = GetArrayElemTypeId(init); elemTypeIdx = GetArrayElemTypeIdx(init); isArray = (elemTypeId != TY_None); - // pass IsGeneratorUse - mHandler->UpdateGeneratorUse(node->GetNodeId(), init->GetNodeId()); + // pass IsGeneratorUsed + mHandler->UpdateGeneratorUsed(node->GetNodeId(), init->GetNodeId()); if (var) { - mHandler->UpdateGeneratorUse(var->GetNodeId(), init->GetNodeId()); + mHandler->UpdateGeneratorUsed(var->GetNodeId(), init->GetNodeId()); } } if (var) { -- Gitee