Zen
A cross-platform functional programming language
|
00001 00007 #pragma once 00008 #include "Ast.hpp" 00009 #include "Project.hpp" 00010 #include "GetXRef.hpp" 00011 00013 #define INTERNAL_TOKEN_REF 00014 #include "zbl/Token.hpp" 00015 00017 namespace zbl { 00019 00021 class LexerContext { 00022 public: 00025 enum IdentifierState { 00026 iInit, 00027 iImportDef, 00028 iNamespaceDef, 00029 iChildTypeRef, 00030 iChildTypeScope, 00031 iChildVarRef, 00032 iChildVarScope, 00033 }; 00034 00035 public: 00038 inline LexerContext() : _identifierState(iInit), _currentTypeSpec(0) {} 00039 00040 public: 00043 inline void resetLexerState() {_identifierState = iInit;} 00044 00047 inline void enterImportState() {_identifierState = iImportDef;} 00048 00051 inline void enterNamespaceState() {_identifierState = iNamespaceDef;} 00052 00055 inline void enterTypeRefState(const Ast::TypeSpec* typeSpec) {assert(typeSpec); _identifierState = iChildTypeRef; _currentTypeSpec = typeSpec;} 00056 00059 inline void enterTypeScopeState() {_identifierState = iChildTypeScope;} 00060 00063 inline void enterVarRefState() {_identifierState = iChildVarRef;} 00064 00067 inline void enterVarScopeState() {_identifierState = iChildVarScope;} 00068 00069 public: 00073 inline const IdentifierState& getIdentifierState() const {return _identifierState;} 00074 00075 public: 00079 inline const Ast::TypeSpec& getCurrentTypeSpec() const {return ref(_currentTypeSpec);} 00080 00081 private: 00083 IdentifierState _identifierState; 00084 00086 const Ast::TypeSpec* _currentTypeSpec; 00087 }; 00088 00090 00092 class Compiler; 00093 00095 00097 class ParseContext : public LexerContext { 00098 private: 00101 class IndexableTypeCaster { 00102 public: 00107 inline void cast(ParseContext& pctx, const Ast::TypeSpec& ptypeSpec) { 00108 const Ast::TypeSpec* typeSpec = ptr(ptypeSpec); 00109 const Ast::TypeDef* typeDef = dynamic_cast<const Ast::TypeDef*>(typeSpec); 00110 while(typeDef) { 00111 typeSpec = ptr(ref(typeDef).getTargetType().getTypeSpec()); 00112 const Ast::TypeDef* t1 = dynamic_cast<const Ast::TypeDef*>(typeSpec); 00113 if(!t1) 00114 break; 00115 typeDef = t1; 00116 } 00117 00118 const Ast::ListTemplate* list = dynamic_cast<const Ast::ListTemplate*>(typeSpec); 00119 if(list) { 00120 return visitList(pctx, ref(list)); 00121 } 00122 00123 const Ast::DictTemplate* dict = dynamic_cast<const Ast::DictTemplate*>(typeSpec); 00124 if(dict) { 00125 return visitDict(pctx, ref(dict)); 00126 } 00127 00128 // special case for some typedecl 00129 const Ast::TypeDecl* typeDecl = dynamic_cast<const Ast::TypeDecl*>(typeSpec); 00130 if(typeDecl) { 00131 if(ref(typeDecl).getName() == "tree") { 00132 return visitTree(pctx, ref(typeDecl)); 00133 } 00134 if(ref(typeDecl).getName() == "data") { 00135 return visitTree(pctx, ref(typeDecl)); 00136 } 00137 if(ref(typeDecl).getName() == "buffer") { 00138 return visitBuffer(pctx, ref(typeDecl)); 00139 } 00140 if(ref(typeDecl).getName() == "view") { 00141 return visitView(pctx, ref(typeDecl)); 00142 } 00143 if(ref(typeDecl).getName() == "widget") { 00144 return visitWidget(pctx, ref(typeDecl)); 00145 } 00146 } 00147 00148 throw z::exception(z::string::creator("%{err} Not an indexable/iterable type: %{type}").arg(z::any("err"), z::any(pctx.err())).arg(z::any("type"), z::any(ref(typeSpec).getFullName(z::string("::")))).value()); 00149 } 00150 00151 private: 00156 virtual void visitList(ParseContext& pctx, const Ast::ListTemplate& type) = 0; 00157 00162 virtual void visitDict(ParseContext& pctx, const Ast::DictTemplate& type) = 0; 00163 00168 virtual void visitTree(ParseContext& pctx, const Ast::TypeDecl& type) = 0; 00169 00174 virtual void visitBuffer(ParseContext& pctx, const Ast::TypeDecl& type) = 0; 00175 00180 virtual void visitView(ParseContext& pctx, const Ast::TypeDecl& type) = 0; 00181 00186 virtual void visitWidget(ParseContext& pctx, const Ast::TypeDecl& type) = 0; 00187 }; 00188 00189 private: 00195 struct ImportFrame { 00197 Ast::UserDefinedTypeSpec::NativeType _ntype; 00198 00200 z::string _fname; 00201 00203 int _line; 00204 00206 int _col; 00207 00209 typedef z::stack<Ast::ChildTypeSpec*> TypeSpecStack; 00210 00212 TypeSpecStack _typeSpecStack; 00213 }; 00214 00217 typedef z::stack<ImportFrame> ImportStack; 00218 00221 ImportStack _importStack; 00222 00223 public: 00228 inline void enterImport(const Ast::UserDefinedTypeSpec::NativeType& ntype, const z::string& fname) { 00229 _importStack.push(ImportFrame()); 00230 ImportFrame& fi = _importStack.top(); 00231 fi._ntype = ntype; 00232 fi._fname = fname; 00233 fi._line = 0; 00234 fi._col = 0; 00235 00236 // if we are importing, set the current type to importNS. 00237 // Imported types don't need to go into Ast::Unit 00238 if(_importStack.size() > 1) { 00239 fi._typeSpecStack.push(ptr(_unit.getImportNS())); 00240 } else { 00241 fi._typeSpecStack.push(ptr(_unit.getRootNS())); 00242 } 00243 } 00244 00247 inline void leaveImport() { 00248 _importStack.pop(); 00249 } 00250 00254 inline bool inImport() const {return (_importStack.size() > 1);} 00255 00259 inline ImportFrame& getImportFrame() { 00260 assert(_importStack.size() > 0); 00261 return _importStack.top(); 00262 } 00263 00267 inline const ImportFrame& getImportFrame() const { 00268 assert(_importStack.size() > 0); 00269 return _importStack.top(); 00270 } 00271 00275 inline const Ast::UserDefinedTypeSpec::NativeType& getNativeType() const { 00276 const ImportFrame& fi = getImportFrame(); 00277 return fi._ntype; 00278 } 00279 00280 public: 00284 inline Ast::ChildTypeSpec& getCurrentType() const { 00285 const ImportFrame& fi = getImportFrame(); 00286 return ref(fi._typeSpecStack.top()); 00287 } 00288 00295 inline Ast::ChildTypeSpec& enterCurrentType(Ast::ChildTypeSpec& type) { 00296 ImportFrame& fi = getImportFrame(); 00297 fi._typeSpecStack.push(ptr(type)); 00298 return type; 00299 } 00300 00307 inline Ast::ChildTypeSpec& leaveCurrentType(Ast::ChildTypeSpec& type) { 00308 ImportFrame& fi = getImportFrame(); 00309 fi._typeSpecStack.pop(); 00310 return type; 00311 } 00312 00313 public: 00317 inline const z::string& getFilename() const { 00318 const ImportFrame& fi = getImportFrame(); 00319 return fi._fname; 00320 } 00321 00322 public: 00327 inline void setTokenPos(const int& line, const int& col) { 00328 ImportFrame& fi = getImportFrame(); 00329 fi._line = line; 00330 fi._col = col; 00331 } 00332 00333 public: 00338 inline ParseContext(zbl::Compiler& compiler, Ast::Unit& unit) 00339 : _compiler(compiler), _unit(unit), 00340 _curr_vdef(0) 00341 { 00342 enterImport(Ast::TypeDefTypeSpec::ntNone, unit.getFilename()); 00343 } 00344 00347 inline ~ParseContext() { 00348 assert(_importStack.size() == 1); 00349 leaveImport(); 00350 } 00351 00352 public: 00358 inline const zbl::TokenData& getNullToken() const {return _nullToken;} 00359 00360 private: 00366 inline z::string err(const int& line, const int& col) const { 00367 z::string str; 00368 z::stringstream z(str); 00369 #ifdef _WIN32 00370 // MSVC style error message 00371 z << getFilename() << "(" << line << ", " << col << "): "; 00372 #else 00373 // GCC style error message, or default. 00374 unused(col); 00375 z << getFilename() << ":" << line << ": "; 00376 #endif 00377 return str; 00378 } 00379 00380 public: 00384 inline z::string err() const { 00385 const ImportFrame& fi = getImportFrame(); 00386 return err(fi._line, fi._col); 00387 } 00388 00393 inline z::string err(const zbl::TokenData& token) const { 00394 return err(token.line, token.col); 00395 } 00396 00397 private: 00404 void importHeaderFile(const Ast::ImportStatement& stmt, const Ast::ImportStatement::Type& type); 00405 00406 public: 00411 inline void importHeader(Ast::ImportStatement& stmt, const Ast::ImportStatement::Type& type) { 00412 resetLexerState(); 00413 for(Ast::Unit::ImportList::iterator it(_unit.getImportList()); !it.end(); ++it) { 00414 const Ast::ImportStatement& istmt = ref(*it); 00415 if((istmt.getName().join("::") == stmt.getName().join("::")) && (istmt.getType() == type)) { 00416 return; 00417 } 00418 } 00419 00420 stmt.setType(type); 00421 _unit.addImport(stmt); 00422 if(type != Ast::ImportStatement::itNative) { 00423 importHeaderFile(stmt, type); 00424 } 00425 } 00426 00427 public: 00432 inline Ast::ImportStatement& createImportNamespace(const z::string& name) { 00433 enterImportState(); 00434 Ast::ImportStatement& stmt = _unit.addNode(new Ast::ImportStatement()); 00435 stmt.addPart(name); 00436 return stmt; 00437 } 00438 00439 private: 00445 inline Ast::Namespace& addChildNamespace(Ast::ChildTypeSpec& type, const z::string& name) { 00446 if(!inImport()) { 00447 _unit.addUnitNS(name); 00448 } 00449 00450 Ast::Namespace* ns = dynamic_cast<Ast::Namespace*>(ptr(type)); 00451 Ast::Namespace* cns = ref(ns).hasNamespace(name); 00452 if(cns) 00453 return *cns; 00454 Ast::Namespace& nns = _unit.addNode(new Ast::Namespace(Ast::TypeSpec::AccessType::Public, ref(ns), name)); 00455 00456 return ref(ns).addNamespace(nns); 00457 } 00458 00459 public: 00464 inline Ast::Namespace& enterUnitNamespace(const z::string& name) { 00465 Ast::Namespace& cns = addChildNamespace(getCurrentType(), name); 00466 enterCurrentType(cns); 00467 return cns; 00468 } 00469 00475 inline Ast::Namespace& addUnitNamespace(Ast::Namespace& ns, const z::string& name) { 00476 Ast::Namespace& cns = addChildNamespace(ns, name); 00477 enterCurrentType(cns); 00478 return cns; 00479 } 00480 00484 inline void leaveUnitNamespace(Ast::Namespace& ns) { 00485 unused(ns); 00486 } 00487 00488 private: 00493 inline Ast::ChildTypeSpec* getParent(Ast::ChildTypeSpec* child) { 00494 Ast::TypeSpec& parent = ref(child).getParent(); 00495 return dynamic_cast<Ast::ChildTypeSpec*>(ptr(parent)); 00496 } 00497 00502 inline Ast::ChildTypeSpec& getParent(Ast::ChildTypeSpec& child) { 00503 return ref(getParent(ptr(child))); 00504 } 00505 00506 public: 00513 inline Ast::TypeSpec* hasRootType(const z::string& name) { 00514 // start from current type and search for this type 00515 // up the type nesting all the way up to the root NS. 00516 Ast::ChildTypeSpec* ctype = ptr(getCurrentType()); 00517 while(ctype) { 00518 Ast::TypeSpec* root = hasChildType(ref(ctype), name); 00519 if(root) 00520 return root; 00521 ctype = getParent(ctype); 00522 } 00523 00524 // finally check all the imported types. 00525 ctype = _unit.getImportNS().hasChild<Ast::ChildTypeSpec>(name); 00526 return ctype; 00527 } 00528 00534 inline Ast::TypeSpec* hasChildType(const Ast::TypeSpec& parent, const z::string& name) { 00535 return parent.hasChild<Ast::ChildTypeSpec>(name); 00536 } 00537 00538 public: 00544 inline Ast::TypeSpec& getChildType(const Ast::TypeSpec& parent, const zbl::TokenData& name) { 00545 if(!(name.typeSpec)) { 00546 throw z::exception(z::string::creator("%{err} Unknown child type: %{child} of %{parent}") 00547 .arg(z::any("err"), z::any(err())) 00548 .arg(z::any("child"), z::any(zbl::Token::getValue(name))) 00549 .arg(z::any("parent"), z::any(parent.getName())) 00550 .value()); 00551 } 00552 return ref(name.typeSpec); 00553 } 00554 00555 public: 00560 inline Ast::TypeSpec& enterTypeSpecRef(const zbl::TokenData& token) { 00561 return ref(token.typeSpec); 00562 } 00563 00568 inline Ast::TypeSpec& leaveTypeSpecRef(Ast::TypeSpec& typeSpec) { 00569 return typeSpec; 00570 } 00571 00572 public: 00579 inline Ast::QualifiedType& createQualifiedType(const bool& isConst, const Ast::TypeSpec& type, const bool& isRef) { 00580 return _unit.addNode(new Ast::QualifiedType(isConst, type, isRef)); 00581 } 00582 00583 private: 00585 typedef z::dict<z::string, Ast::QualifiedType*> QualifiedTypeMap; 00586 00588 QualifiedTypeMap _qualifiedTypeMap; 00589 00590 private: 00597 inline Ast::QualifiedType& getQualifiedType(const z::string& name) { 00598 // check if already in map 00599 QualifiedTypeMap::found f = _qualifiedTypeMap.find(name); 00600 if(f) 00601 return ref(*f); 00602 00603 // search import namespace 00604 const Ast::ChildTypeSpec* ts = _unit.getImportNS().hasChild<Ast::ChildTypeSpec>(name); 00605 if(!ts) { 00606 // search root namespace. This will not find anything, for now, 00607 // since this function is meant for intrinsic types only. 00608 ts = _unit.getRootNS().hasChild<Ast::ChildTypeSpec>(name); 00609 if(!ts) 00610 throw z::exception(z::string::creator("%{err} Unknown type: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(name)).value()); 00611 } 00612 00613 // create qtype 00614 Ast::QualifiedType& qtype = createQualifiedType(false, ref(ts), false); 00615 00616 // add to map 00617 _qualifiedTypeMap.insert(name, ptr(qtype)); 00618 00619 // return qtype 00620 return qtype; 00621 } 00622 00623 private: 00625 typedef z::list<const Ast::TypeSpec*> CoertionList; 00626 00628 CoertionList _coertionList; 00629 00630 public: 00634 inline void enterCoertionList(const Ast::TypeSpec& type) { 00635 _coertionList.append(ptr(type)); 00636 } 00637 00641 inline void addCoertionItem(const Ast::TypeSpec& type) { 00642 _coertionList.append(ptr(type)); 00643 } 00644 00647 inline void leaveCoertionList() { 00648 _coertionList.append(0); 00649 } 00650 00651 private: 00656 inline int getTypeIndex(const Ast::QualifiedType& type) const { 00657 const z::string& name = type.getTypeSpec().getName(); 00658 int idx = 0; 00659 for(CoertionList::iterator it(_coertionList); !it.end(); ++it, ++idx) { 00660 const Ast::TypeSpec* ts = *it; 00661 // IMP: this must be a separate check. Do not combine with the next if-stmt. 00662 if(!ts) 00663 return -1; 00664 if(ref(ts).getName() == name) 00665 return idx; 00666 } 00667 return -1; 00668 } 00669 00670 private: 00672 typedef z::dict<const Ast::TypeSpec*, const Ast::TypeSpec*> CoertionSubMap; 00673 00675 typedef z::dict<const Ast::TypeSpec*, CoertionSubMap> CoertionMap; 00676 00678 CoertionMap _coertionMap; 00679 00680 public: 00688 inline void addCoertionMap(const Ast::TypeSpec& lhs, const Ast::TypeSpec& rhs, const Ast::TypeSpec& dst) { 00689 if(!_coertionMap.has(ptr(lhs))) 00690 _coertionMap.insert(ptr(lhs), CoertionSubMap()); 00691 00692 CoertionSubMap& smap = _coertionMap.at(ptr(lhs)); 00693 if(smap.has(ptr(rhs))) 00694 throw z::exception(z::string::creator("%{err} Coertion map already exists").arg(z::any("err"), z::any(err())).value()); 00695 00696 smap.insert(ptr(rhs), ptr(dst)); 00697 } 00698 00699 private: 00705 inline const Ast::TypeSpec* getTarget(const Ast::QualifiedType& lhs, const Ast::QualifiedType& rhs) { 00706 CoertionMap::found lf = _coertionMap.find(ptr(lhs.getTypeSpec())); 00707 if(!lf) 00708 return 0; 00709 00710 CoertionSubMap::found sf = (*lf).find(ptr(rhs.getTypeSpec())); 00711 if(!sf) 00712 return 0; 00713 00714 return *sf; 00715 } 00716 00717 private: 00723 inline const Ast::VariableDef* hasUdtMember(const Ast::UserDefinedTypeSpec& udt, const z::string& name) const { 00724 return udt.hasMember(name); 00725 } 00726 00732 inline const Ast::VariableDef* hasMember(const Ast::VariableDef& vd, const zbl::TokenData& name) const { 00733 const Ast::TypeSpec& vtype = vd.getType().getTypeSpec(); 00734 const Ast::UserDefinedTypeSpec* udt = dynamic_cast<const Ast::UserDefinedTypeSpec*>(ptr(vtype)); 00735 if(!udt) 00736 return 0; 00737 return hasUdtMember(ref(udt), zbl::Token::getValue(name)); 00738 } 00739 00740 private: 00746 inline Ast::Expr& getEnumRefExpr(const Ast::EnumDef& enumRef, const z::string& id) { 00747 const Ast::QualifiedType& qtype = createQualifiedType(false, enumRef, false); 00748 return _unit.addNode(new Ast::EnumRefExpr(qtype, enumRef, id)); 00749 } 00750 00751 private: 00756 inline bool isAny(const Ast::QualifiedType& rhs) { 00757 const Ast::QualifiedType& anyType = getQualifiedType(z::string("any")); 00758 return (ptr(anyType.getTypeSpec()) == ptr(rhs.getTypeSpec())); 00759 } 00760 00761 private: 00767 inline const Ast::QualifiedType& coerce(const Ast::QualifiedType& lhs, const Ast::QualifiedType& rhs) { 00768 const z::string& lname = lhs.getTypeSpec().getName(); 00769 const z::string& rname = rhs.getTypeSpec().getName(); 00770 00771 // check the linear lists 00772 int idxl = getTypeIndex(lhs); 00773 int idxr = getTypeIndex(rhs); 00774 if((lname == rname) || ( (idxl >= 0) && (idxr >= 0) )) { 00775 if((lhs.isConst() == rhs.isConst()) && (lhs.isRef() == rhs.isRef())) { 00776 if(idxl < idxr) 00777 return rhs; 00778 return lhs; 00779 } 00780 if(idxl < idxr) 00781 return createQualifiedType(false, rhs.getTypeSpec(), false); 00782 return createQualifiedType(false, lhs.getTypeSpec(), false); 00783 } 00784 00785 const Ast::TypeSpec* lt = getTarget(lhs, rhs); 00786 if(lt) 00787 return createQualifiedType(false, ref(lt), false); 00788 00789 const Ast::TypeSpec* rt = getTarget(rhs, lhs); 00790 if(rt) 00791 return createQualifiedType(false, ref(rt), false); 00792 00793 throw z::exception(z::string::creator("%{err} Type mismatch: %{lname} and %{rname}").arg(z::any("err"), z::any(err())).arg(z::any("lname"), z::any(lname)).arg(z::any("rname"), z::any(rname)).value()); 00794 } 00795 00796 public: 00798 typedef z::dict<const Ast::TypeSpec*, const Ast::Expr*> TypeDefaultValueMap; 00799 00801 TypeDefaultValueMap _typeDefaultValueMap; 00802 00807 inline void addTypeDefaultValue(const Ast::TypeSpec& type, const Ast::Expr& expr) { 00808 _typeDefaultValueMap.insert(ptr(type), ptr(expr)); 00809 } 00810 00815 inline const Ast::Expr& getTypeDefaultValue(const Ast::TypeSpec& type) { 00816 TypeDefaultValueMap::found f = _typeDefaultValueMap.find(ptr(type)); 00817 if(f) { 00818 return ref(*f); 00819 } 00820 00821 const Ast::ListTemplate* list = dynamic_cast<const Ast::ListTemplate*>(ptr(type)); 00822 if(list) { 00823 Ast::ListList& llist = createListList(); 00824 const Ast::QualifiedType& vtype = list->getType(); 00825 llist.setType(ptr(vtype)); 00826 return createListExpr(llist); 00827 } 00828 00829 const Ast::DictTemplate* dict = dynamic_cast<const Ast::DictTemplate*>(ptr(type)); 00830 if(dict) { 00831 Ast::DictList& dlist = createDictList(); 00832 const Ast::QualifiedType& ktype = dict->getKey(); 00833 const Ast::QualifiedType& vtype = dict->getType(); 00834 dlist.setKeyType(ptr(ktype)); 00835 dlist.setValueType(ptr(vtype)); 00836 return createDictExpr(dlist); 00837 } 00838 00839 const Ast::EnumDef* enumDef = dynamic_cast<const Ast::EnumDef*>(ptr(type)); 00840 if(enumDef) { 00841 if(ref(enumDef).getDefList().getList().size() == 0) { 00842 throw z::exception(z::string::creator("%{err} Internal error: enum: %{name} must have at least one member").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(type.getFullName(z::string("::")))).value()); 00843 } 00844 00845 const Ast::EnumMemberDef* mdef = ref(enumDef).getDefList().getList().at(0); 00846 return getEnumRefExpr(ref(enumDef), z::string(ref(mdef).getName())); 00847 } 00848 00849 Ast::ExprList& exprList = createExprList(); 00850 return createInstanceExpr(type, exprList); 00851 } 00852 00853 public: 00860 inline Ast::StructMemberVariableDef& createStructVariableDefInit(const Ast::QualifiedType& type, const z::string& name, const Ast::Expr& expr) { 00861 return _unit.addNode(new Ast::StructMemberVariableDef(type, name, expr)); 00862 } 00863 00871 inline Ast::StructMemberVariableDef& createStructVariableDef(const Ast::QualifiedType& type, const z::string& name) { 00872 const Ast::Expr& expr = getTypeDefaultValue(type.getTypeSpec()); 00873 return createStructVariableDefInit(type, name, expr); 00874 } 00875 00882 inline Ast::ParamVariableDef& createParamVariableDefInit(const Ast::QualifiedType& type, const z::string& name, const Ast::Expr& expr) { 00883 return _unit.addNode(new Ast::ParamVariableDef(type, name, expr)); 00884 } 00885 00893 inline Ast::ParamVariableDef& createParamVariableDef(const Ast::QualifiedType& type, const z::string& name) { 00894 const Ast::Expr& expr = getTypeDefaultValue(type.getTypeSpec()); 00895 return createParamVariableDefInit(type, name, expr); 00896 } 00897 00905 inline Ast::InitVariableDef& createInitVariableDefInit(const Ast::VariableDef::DefType& defType, const Ast::QualifiedType& type, const z::string& name, const Ast::Expr& expr) { 00906 assert(defType == Ast::VariableDef::Local); 00907 Ast::InitVariableDef& vdef = _unit.addNode(new Ast::InitVariableDef(defType, type, name, expr)); 00908 if(0 != _curr_vdef) { 00909 throw z::exception(z::string::creator("%{err} Internal error: _curr_vdef: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(ref(_curr_vdef).getName())).value()); 00910 } 00911 _curr_vdef = ptr(vdef); 00912 return vdef; 00913 } 00914 00921 inline Ast::InitVariableDef& createInitVariableDef(const Ast::VariableDef::DefType& defType, const z::string& name, const Ast::Expr& expr) { 00922 const Ast::QualifiedType& type = expr.getType(); 00923 return createInitVariableDefInit(defType, type, name, expr); 00924 } 00925 00928 class InitVariableDefCreator : public IndexableTypeCaster { 00929 public: 00935 inline InitVariableDefCreator(const Ast::VariableDef::DefType& defType, const z::string& name, const Ast::Expr& expr) 00936 : _defType(defType), _name(name), _expr(expr), _rv(0) {} 00937 public: 00943 inline Ast::InitVariableDef& create(ParseContext& pctx, const Ast::TypeSpec& typeSpec) { 00944 cast(pctx, typeSpec); 00945 return ref(_rv); 00946 } 00947 00948 private: 00953 virtual void visitList(ParseContext& pctx, const Ast::ListTemplate& type) { 00954 unused(pctx); 00955 const Ast::QualifiedType& qtype = type.getType(); 00956 _rv = ptr(pctx.createInitVariableDefInit(_defType, qtype, _name, _expr)); 00957 } 00958 00963 virtual void visitDict(ParseContext& pctx, const Ast::DictTemplate& type) { 00964 const Ast::QualifiedType& qtype = type.getType(); 00965 _rv = ptr(pctx.createInitVariableDefInit(_defType, qtype, _name, _expr)); 00966 } 00967 00972 virtual void visitTree(ParseContext& pctx, const Ast::TypeDecl& type) { 00973 unused(pctx); 00974 unused(type); 00975 assert(false); 00976 } 00977 00982 virtual void visitBuffer(ParseContext& pctx, const Ast::TypeDecl& type) { 00983 unused(type); 00984 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("char")); 00985 _rv = ptr(pctx.createInitVariableDefInit(_defType, qtype, _name, _expr)); 00986 } 00987 00992 virtual void visitView(ParseContext& pctx, const Ast::TypeDecl& type) { 00993 unused(type); 00994 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("widget")); 00995 _rv = ptr(pctx.createInitVariableDefInit(_defType, qtype, _name, _expr)); 00996 } 00997 01002 virtual void visitWidget(ParseContext& pctx, const Ast::TypeDecl& type) { 01003 unused(type); 01004 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("property")); 01005 _rv = ptr(pctx.createInitVariableDefInit(_defType, qtype, _name, _expr)); 01006 } 01007 01008 private: 01010 const Ast::VariableDef::DefType& _defType; 01011 01013 const z::string& _name; 01014 01016 const Ast::Expr& _expr; 01017 01019 Ast::InitVariableDef* _rv; 01020 }; 01021 01036 inline Ast::InitVariableDef& createForeachInitVariableDef(const Ast::VariableDef::DefType& defType, const z::string& name, const Ast::Expr& expr) { 01037 InitVariableDefCreator creator(defType, name, expr); 01038 return creator.create(ref(this), expr.getType().getTypeSpec()); 01039 } 01040 01045 inline Ast::QualifiedType& createOutParam(const Ast::VariableDefMap& defList) { 01046 Ast::OutParam& op = _unit.addNode(new Ast::OutParam(Ast::TypeSpec::AccessType::Private, z::string("Return"), getNativeType(), defList, true)); 01047 return createQualifiedType(false, op, false); 01048 } 01049 01050 private: 01057 inline Ast::SharedVariableDef& createSharedVariableDef(const Ast::QualifiedType& qtype, const z::string& name, const Ast::Expr& expr) { 01058 return _unit.addNode(new Ast::SharedVariableDef(Ast::VariableDef::Shared, qtype, name, expr)); 01059 } 01060 01061 public: 01068 inline Ast::SharedVariableDef& createSharedTypeExprDef(const Ast::QualifiedType& qtype, const zbl::TokenData& name, const Ast::Expr& expr) { 01069 return createSharedVariableDef(qtype, zbl::Token::getValue(name), expr); 01070 } 01071 01077 inline Ast::SharedVariableDef& createSharedExprDef(const zbl::TokenData& name, const Ast::Expr& expr) { 01078 const Ast::QualifiedType& qtype = expr.getType(); 01079 return createSharedVariableDef(qtype, zbl::Token::getValue(name), expr); 01080 } 01081 01086 inline Ast::SharedVariableDef& createSharedMemberDef(const Ast::VariableRef& vref) { 01087 const Ast::QualifiedType& qtype = vref.getLast().getType(); 01088 const z::string& name = vref.getLast().getName(); 01089 const Ast::Expr& expr = createVariableRefExpr(vref); 01090 return createSharedVariableDef(qtype, name, expr); 01091 } 01092 01093 public: 01098 inline Ast::SharedDef& createSharedDef(const Ast::VariableDefMap& defList) { 01099 Ast::SharedDef& list = _unit.addNode(new Ast::SharedDef(Ast::TypeSpec::AccessType::Private, z::string("Shared"), getNativeType(), defList)); 01100 return addChildLevel(list); 01101 } 01102 01106 inline Ast::FunctionDef& getFunctionDef() const { 01107 Ast::ChildTypeSpec& type = getCurrentType(); 01108 Ast::FunctionDef* fdef = dynamic_cast<Ast::FunctionDef*>(ptr(type)); 01109 if(!fdef) { 01110 throw z::exception(z::string::creator("%{err} Internal error: %{name} is not a FunctionDef").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(type.getFullName(z::string("::")))).value()); 01111 } 01112 return ref(fdef); 01113 } 01114 01115 public: 01121 inline const Ast::VariableDef* getIdentifier(const z::string& name, Ast::Storage::T& storage) const { 01122 storage = Ast::Storage::Block; 01123 01124 // Because of the way the parser works, in some situations the most 01125 // recent variable_def is not yet added to the scope. Hence this check. 01126 if(_curr_vdef) { 01127 if(ref(_curr_vdef).getName() == name) { 01128 return _curr_vdef; 01129 } 01130 } 01131 01132 // search backward through the scope stack (from last to first) 01133 // for a variable with this name. 01134 ScopeStack::iterator it(_scopeStack); 01135 it.toBack(); 01136 while(!it.begin()) { 01137 Ast::Scope& scope = ref(--it); 01138 const Ast::VariableDef* vd = scope.getDefList().hasDef(name); 01139 if(vd) { 01140 return vd; 01141 } 01142 } 01143 return 0; 01144 } 01145 01146 private: 01153 inline Ast::VariableDef& addVariableDef(const Ast::VariableDef::DefType& defType, const Ast::QualifiedType& type, const z::string& name) { 01154 assert(_scopeStack.size() > 0); 01155 Ast::Storage::T storage = Ast::Storage::Init; 01156 const Ast::VariableDef* vd = getIdentifier(name, storage); 01157 if(vd) { 01158 throw z::exception(z::string::creator("%{err} Variable: %{name} shadows earlier variable with same name").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(name)).value()); 01159 } 01160 Ast::VariableDef& vdef = _unit.addNode(new Ast::VariableDef(defType, type, name)); 01161 ref(_scopeStack.top()).addDef(vdef); 01162 return vdef; 01163 } 01164 01169 inline Ast::VariableDef& addVariableDef(Ast::VariableDef& vdef) { 01170 assert(_scopeStack.size() > 0); 01171 Ast::Storage::T storage = Ast::Storage::Init; 01172 const Ast::VariableDef* vd = getIdentifier(vdef.getName(), storage); 01173 if(vd) { 01174 throw z::exception(z::string::creator("%{err} Variable: %{name} shadows earlier variable with same name").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(vdef.getName())).value()); 01175 } 01176 ref(_scopeStack.top()).addDef(vdef); 01177 return vdef; 01178 } 01179 01180 private: 01185 template <typename T> 01186 inline T& addChildLevel(T& t) { 01187 getCurrentType().addChild(t); 01188 return t; 01189 } 01190 01195 template <typename T> 01196 inline T& enterTypeSpec(T& t) { 01197 enterCurrentType(t); 01198 return t; 01199 } 01200 01205 template <typename T> 01206 inline T& leaveTypeSpec(T& t) { 01207 assert(ptr(getCurrentType()) == ptr(t)); 01208 leaveCurrentType(getParent(getCurrentType())); 01209 return t; 01210 } 01211 01212 public: 01216 inline Ast::VariableDefMap& createVariableDefMap() { 01217 return _unit.addNode(new Ast::VariableDefMap()); 01218 } 01219 01223 inline Ast::StructDefList& createStructDefList() { 01224 return _unit.addNode(new Ast::StructDefList()); 01225 } 01226 01227 public: 01233 inline Ast::StructDef& enterStructDef(const Ast::TypeSpec::AccessType::T& accessType, const z::string& name) { 01234 Ast::StructDef& rv = _unit.addNode(new Ast::StructDef(accessType, name, getNativeType())); 01235 return addChildLevel(rv); 01236 } 01237 01242 inline Ast::StructDef& leaveStructDef(Ast::StructDef& structDef) { 01243 return structDef; 01244 } 01245 01252 inline Ast::StructDef& leaveStructDefList(Ast::StructDef& structDef, const Ast::VariableDefMap& defList, const Ast::StructDefList& subTypeList) { 01253 structDef.setDefList(defList); 01254 structDef.setSubTypeList(subTypeList); 01255 return leaveStructDef(structDef); 01256 } 01257 01258 public: 01265 inline Ast::EnumDef& createEnumDef(const Ast::TypeSpec::AccessType::T& accessType, const z::string& name, Ast::EnumMemberDefList& defList) { 01266 Ast::EnumDef& rv = _unit.addNode(new Ast::EnumDef(accessType, name, getNativeType(), defList)); 01267 return addChildLevel(rv); 01268 } 01269 01273 inline Ast::EnumMemberDefList& createEnumMemberDefList() { 01274 Ast::EnumMemberDefList& rv = _unit.addNode(new Ast::EnumMemberDefList()); 01275 return rv; 01276 } 01277 01284 inline Ast::EnumMemberDef& createEnumMemberDefInit(const zbl::TokenData& name, const bool& hasInit, const Ast::Expr& initExpr) { 01285 Ast::EnumMemberDef& rv = _unit.addNode(new Ast::EnumMemberDef(Ast::TypeSpec::AccessType::Private, zbl::Token::getValue(name), hasInit, initExpr)); 01286 return rv; 01287 } 01288 01293 inline Ast::EnumMemberDef& createEnumMemberDef(const zbl::TokenData& name) { 01294 Ast::NumericConstantExpr& expr = createNumericConstantExpr(z::string("int"), z::string("0")); 01295 return createEnumMemberDefInit(name, false, expr); 01296 } 01297 01298 public: 01300 struct TypeDefSig { 01302 Ast::TypeSpec::AccessType::T accessType; 01303 01305 zbl::TokenData name; 01306 }; 01307 01308 public: 01314 inline TypeDefSig createTypeDefSig(const Ast::TypeSpec::AccessType::T& accessType, const zbl::TokenData& name) { 01315 TypeDefSig sig; 01316 sig.accessType = accessType; 01317 sig.name = name; 01318 return sig; 01319 } 01320 01325 inline Ast::TypeDecl& createTypeDecl(const TypeDefSig& sig) { 01326 Ast::TypeDecl& rv = _unit.addNode(new Ast::TypeDecl(sig.accessType, zbl::Token::getValue(sig.name), getNativeType())); 01327 return addChildLevel(rv); 01328 } 01329 01335 inline Ast::TypeDef& createTypeDef(const TypeDefSig& sig, const Ast::QualifiedType& type) { 01336 Ast::TypeDef& rv = _unit.addNode(new Ast::TypeDef(sig.accessType, zbl::Token::getValue(sig.name), getNativeType(), type)); 01337 return addChildLevel(rv); 01338 } 01339 01340 public: 01348 inline Ast::GrammarToken& createGrammarToken(const TokenData& name, const TokenData& txt, const bool& isRex, const bool& isNot) { 01349 z::string namev = zbl::Token::getValue(name); 01350 if(namev.length() > 0) { 01351 const Ast::QualifiedType& type = getQualifiedType(z::string("string")); 01352 addVariableDef(Ast::VariableDef::Param, type, namev); 01353 } 01354 01355 Ast::GrammarToken& rv = _unit.addNode(new Ast::GrammarToken(namev, zbl::Token::getValue(txt), isRex, isNot)); 01356 return rv; 01357 } 01358 01362 inline Ast::GrammarTokenList& createGrammarTokenList() { 01363 Ast::GrammarTokenList& rv = _unit.addNode(new Ast::GrammarTokenList()); 01364 return rv; 01365 } 01366 01371 inline Ast::GrammarMemberId& createGrammarMemberId(const TokenData& name) { 01372 Ast::GrammarMemberId& rv = _unit.addNode(new Ast::GrammarMemberId(zbl::Token::getValue(name))); 01373 return rv; 01374 } 01375 01380 inline const Ast::VariableDef& createGrammarMemberNameDef(const TokenData& name) { 01381 const Ast::QualifiedType& type = getQualifiedType(z::string("string")); 01382 return addVariableDef(Ast::VariableDef::Param, type, zbl::Token::getValue(name)); 01383 } 01384 01390 inline Ast::GrammarMemberNameId& createGrammarMemberNameId(const TokenData& name, const TokenData& txt) { 01391 const Ast::VariableDef& vdef = createGrammarMemberNameDef(name); 01392 Ast::GrammarMemberNameId& rv = _unit.addNode(new Ast::GrammarMemberNameId(vdef, zbl::Token::getValue(txt))); 01393 return rv; 01394 } 01395 01399 inline Ast::GrammarMemberList& createGrammarMemberList() { 01400 Ast::GrammarMemberList& rv = _unit.addNode(new Ast::GrammarMemberList()); 01401 return rv; 01402 } 01403 01404 public: 01411 inline Ast::FunctionDef& enterGrammarRuleOut(Ast::QualifiedType& out, const TokenData& name, Ast::Scope& in) { 01412 int idx = _unit.getImplList().size(); 01413 01414 z::string fname = z::string::creator(z::string("_gru_%{n}_%{i}")) 01415 .arg(z::any("n"), z::any(zbl::Token::getValue(name))) 01416 .arg(z::any("i"), z::any(idx)) 01417 .value(); 01418 01419 Ast::TypeSpec::AccessType::T accessType = Ast::TypeSpec::AccessType::Private; 01420 Ast::FunctionDef::Modifier::T modifier = Ast::FunctionDef::Modifier::None; 01421 Ast::FunctionDef& fdef = enterFunctionName(accessType, out, fname, in, modifier); 01422 fdef.setGrammarName(zbl::Token::getValue(name)); 01423 return fdef; 01424 } 01425 01433 inline Ast::FunctionDef& enterGrammarRule(const TokenData& name, Ast::Scope& in) { 01434 Ast::QualifiedType& out = getQualifiedType(z::string("int")); 01435 return enterGrammarRuleOut(out, name, in); 01436 } 01437 01444 inline Ast::GrammarRuleStatement& leaveGrammarRuleBlock(Ast::FunctionDef& fdef, const Ast::GrammarMemberList& list, const Ast::StatementList& stmtList) { 01445 Ast::FunctionBlock& fblock = createFunctionBlock(stmtList); 01446 Ast::FunctionImplItem& implItem = leaveFunctionDef(fdef, fblock); 01447 unused(implItem); 01448 01449 Ast::GrammarRuleStatement& rv = _unit.addNode(new Ast::GrammarRuleStatement(fdef.getGrammarName(), fdef, fblock, list)); 01450 return rv; 01451 } 01452 01460 inline Ast::GrammarRuleStatement& leaveGrammarRule(Ast::FunctionDef& fdef, const Ast::GrammarMemberList& list) { 01461 // manually construct a "return true;" statement and add it to the empty statement list. 01462 Ast::BooleanConstantExpr& texpr = createBooleanConstantExpr(z::string("true")); 01463 Ast::RoutineReturnStatement& rtn = createRoutineReturnStatement(texpr); 01464 Ast::StatementList& stmtList = createEmptyStatementList(); 01465 stmtList.addStatement(rtn); 01466 01467 return leaveGrammarRuleBlock(fdef, list, stmtList); 01468 } 01469 01470 private: 01475 inline Ast::GrammarLexer& enterLexerState(const z::string& name) { 01476 Ast::GrammarLexer& rv = _unit.addNode(new Ast::GrammarLexer(name)); 01477 _grammarLexerStack.push(ptr(rv)); 01478 return rv; 01479 } 01480 01481 public: 01486 inline Ast::GrammarLexer& enterLexerState(const TokenData& name) { 01487 return enterLexerState(zbl::Token::getValue(name)); 01488 } 01489 01493 inline Ast::GrammarLexer& enterLexerState() { 01494 return enterLexerState(z::string("stdlx")); 01495 } 01496 01502 inline Ast::GrammarLexer& leaveLexerState(Ast::GrammarLexer& lexer, Ast::LexerStatementList& list) { 01503 assert(_grammarLexerStack.top() == ptr(lexer)); 01504 _grammarLexerStack.pop(); 01505 01506 lexer.setList(list); 01507 return lexer; 01508 } 01509 01510 public: 01516 inline Ast::FunctionDef& enterLexer(const TokenData& name, Ast::Scope& in) { 01517 assert(_grammarLexerStack.size() > 0); 01518 Ast::GrammarLexer& lexer = ref(_grammarLexerStack.top()); 01519 01520 int idx = _unit.getImplList().size(); 01521 01522 z::string fname = z::string::creator( 01523 z::string("_glx_%{l}_%{n}_%{i}")) 01524 .arg(z::any("l"), z::any(lexer.getName())) 01525 .arg(z::any("n"), z::any(zbl::Token::getValue(name))) 01526 .arg(z::any("i"), z::any(idx) 01527 ).value(); 01528 01529 Ast::QualifiedType& out = getQualifiedType(z::string("string")); 01530 Ast::TypeSpec::AccessType::T accessType = Ast::TypeSpec::AccessType::Private; 01531 Ast::FunctionDef::Modifier::T modifier = Ast::FunctionDef::Modifier::None; 01532 Ast::FunctionDef& fdef = enterFunctionName(accessType, out, fname, in, modifier); 01533 fdef.setGrammarName(zbl::Token::getValue(name)); 01534 return fdef; 01535 } 01536 01543 inline Ast::LexerStatement& leaveLexer(Ast::FunctionDef& fdef, const Ast::GrammarTokenList& list, const Ast::StatementList& stmtList) { 01544 // get top-most lexer 01545 assert(_grammarLexerStack.size() > 0); 01546 Ast::GrammarLexer& lexer = ref(_grammarLexerStack.top()); 01547 01548 // leave function 01549 Ast::FunctionBlock& fblock = createFunctionBlock(stmtList); 01550 leaveFunctionDef(fdef, fblock); 01551 01552 // create lexer 01553 Ast::LexerStatement& rv = _unit.addNode(new Ast::LexerStatement(fdef.getGrammarName(), fdef, fblock, lexer, list)); 01554 return rv; 01555 } 01556 01562 inline Ast::LexerStatement& leaveLexer(Ast::FunctionDef& fdef, const Ast::GrammarTokenList& list) { 01563 // add dummy in-param 01564 Ast::Scope& in = fdef.getInType(); 01565 Ast::QualifiedType& type = getQualifiedType(z::string("string")); 01566 Ast::ParamVariableDef& vdef = createParamVariableDef(type, z::string("_t")); 01567 in.addDef(vdef); 01568 01569 // manually construct a "return _t;" statement... 01570 const Ast::VariableRef& vref = createVariableRef(Ast::Storage::Block, vdef); 01571 Ast::Expr& vrefExpr = createVariableRefExpr(vref); 01572 Ast::RoutineReturnStatement& rtn = createRoutineReturnStatement(vrefExpr); 01573 01574 // and add it to the empty statement list. 01575 Ast::StatementList& stmtList = createEmptyStatementList(); 01576 stmtList.addStatement(rtn); 01577 01578 return leaveLexer(fdef, list, stmtList); 01579 } 01580 01581 public: 01585 inline Ast::LexerStatementList& createLexerStatementList() { 01586 Ast::LexerStatementList& rv = _unit.addNode(new Ast::LexerStatementList()); 01587 return rv; 01588 } 01589 01593 inline Ast::GrammarLexerList& createGrammarLexerList() { 01594 Ast::GrammarLexerList& rv = _unit.addNode(new Ast::GrammarLexerList()); 01595 return rv; 01596 } 01597 01601 inline Ast::GrammarStatementList& createGrammarStatementList() { 01602 Ast::GrammarStatementList& rv = _unit.addNode(new Ast::GrammarStatementList()); 01603 return rv; 01604 } 01605 01610 inline Ast::GrammarOptionValueList& createGrammarOptionValueList(const TokenData& value) { 01611 Ast::GrammarOptionValueList& rv = _unit.addNode(new Ast::GrammarOptionValueList()); 01612 rv.addValue(zbl::Token::getValue(value)); 01613 return rv; 01614 } 01615 01621 inline Ast::GrammarOptionValueList& addGrammarOptionValue(Ast::GrammarOptionValueList& list, const TokenData& value) { 01622 list.addValue(zbl::Token::getValue(value)); 01623 return list; 01624 } 01625 01631 inline Ast::GrammarOption& createGrammarOption(const TokenData& name, const Ast::GrammarOptionValueList& list) { 01632 Ast::GrammarOption& rv = _unit.addNode(new Ast::GrammarOption(zbl::Token::getValue(name), list)); 01633 return rv; 01634 } 01635 01639 inline Ast::GrammarOptionList& createGrammarOptionList() { 01640 Ast::GrammarOptionList& rv = _unit.addNode(new Ast::GrammarOptionList()); 01641 return rv; 01642 } 01643 01644 private: 01652 inline void addOutParamChild(Ast::MethodTypeSpec& rv, const Ast::QualifiedType& out) const { 01653 const Ast::TypeSpec& ts = out.getTypeSpec(); 01654 const Ast::OutParam* cop = dynamic_cast<const Ast::OutParam*>(ptr(ts)); 01655 if(0 != cop) { 01656 Ast::OutParam* op = const_cast<Ast::OutParam*>(cop); //TODO: eliminate const_cast 01657 rv.addChild(ref(op)); 01658 rv.setIsTuple(ref(op).getIsTuple()); 01659 } 01660 } 01661 01662 public: 01671 inline Ast::FunctionDef& enterFunctionName(const Ast::TypeSpec::AccessType::T& accessType, const Ast::QualifiedType& out, const z::string& name, Ast::Scope& in, const Ast::FunctionDef::Modifier::T& modifier) { 01672 Ast::FunctionDef& fdef = _unit.addNode(new Ast::FunctionDef(accessType, out, name, in, getNativeType(), modifier)); 01673 addOutParamChild(fdef, out); 01674 01675 addChildLevel(fdef); 01676 return enterTypeSpec(fdef); 01677 } 01678 01687 inline Ast::FunctionDef& enterFunction(const Ast::TypeSpec::AccessType::T& accessType, Ast::QualifiedType& out, const zbl::TokenData& name, Ast::Scope& in, const Ast::FunctionDef::Modifier::T& modifier) { 01688 return enterFunctionName(accessType, out, zbl::Token::getValue(name), in, modifier); 01689 } 01690 01691 public: 01696 inline Ast::FunctionDef& leaveFunction(Ast::FunctionDef& fdef) { 01697 leaveInParamScope(); 01698 return leaveTypeSpec(fdef); 01699 } 01700 01701 private: 01707 template <typename BlockT, typename ImplT> 01708 inline ImplT& createImplItemT(Ast::FunctionDef& fdef, const BlockT& block) { 01709 int idx = _unit.getImplList().size(); 01710 ImplT& item = _unit.addNode(new ImplT(idx, fdef, block)); 01711 _unit.addItem(item); 01712 fdef.setImpl(item); 01713 return item; 01714 } 01715 01721 template <typename BlockT, typename ImplT> 01722 inline ImplT& leaveFunctionT(Ast::FunctionDef& fdef, const BlockT& block) { 01723 ImplT& item = createImplItemT<BlockT, ImplT>(fdef, block); 01724 leaveFunction(fdef); 01725 return item; 01726 } 01727 01728 public: 01734 inline Ast::FunctionImplItem& leaveFunctionDef(Ast::FunctionDef& fdef, const Ast::FunctionBlock& block) { 01735 if(fdef.getName() == "main") { 01736 // manually create the AST nodes to generate a continuation that invokes the main function. 01737 enterContinuation(); 01738 Ast::FunctionCall& fcall = createFunctionCall(fdef); 01739 Ast::ExprList& exprList = createExprList(); 01740 01741 const Ast::QualifiedType& stype = getQualifiedType(z::string("string")); 01742 Ast::ListTemplate& ltype = createListTemplate(stype); 01743 const Ast::QualifiedType& type = createQualifiedType(false, ltype, false); 01744 Ast::VariableDef& vdef = addVariableDef(Ast::VariableDef::Local, type, "_argl"); 01745 01746 Ast::VariableRef& vref = createVariableRef(Ast::Storage::Block, vdef); 01747 Ast::VariableRefExpr& vrefExpr = createVariableRefExpr(vref); 01748 exprList.addExpr(vrefExpr); 01749 01750 Ast::Invoker& invoker = createInvoker(fcall, exprList); 01751 Ast::InitClosure& closure = createCallClosure(invoker); 01752 Ast::ClosureList& closureList = createClosureList(closure); 01753 Ast::ContinuationImplItem& continuation = createContinuationImplItem(closureList); 01754 leaveContinuation(continuation); 01755 01756 // set _mainSeq in unit. 01757 _unit.setMainContinuation(continuation); 01758 } 01759 01760 Ast::FunctionImplItem& impl = leaveFunctionT<Ast::FunctionBlock, Ast::FunctionImplItem>(fdef, block); 01761 return impl; 01762 } 01763 01769 inline Ast::RoutineImplItem& leaveRoutineDef(Ast::FunctionDef& fdef, const Ast::RoutineBlock& block) { 01770 return leaveFunctionT<Ast::RoutineBlock, Ast::RoutineImplItem>(fdef, block); 01771 } 01772 01778 inline Ast::GrammarImplItem& leaveGrammarDef(Ast::FunctionDef& fdef, const Ast::GrammarBlock& block) { 01779 return leaveFunctionT<Ast::GrammarBlock, Ast::GrammarImplItem>(fdef, block); 01780 } 01781 01787 inline Ast::WindowImplItem& leaveWindowDef(Ast::FunctionDef& fdef, const Ast::WindowBlock& block) { 01788 return leaveFunctionT<Ast::WindowBlock, Ast::WindowImplItem>(fdef, block); 01789 } 01790 01791 public: 01796 inline Ast::FunctionDef& enterFunctionImpl(Ast::TypeSpec& type) { 01797 Ast::FunctionDef* fdef = dynamic_cast<Ast::FunctionDef*>(ptr(type)); 01798 if(0 == fdef) { 01799 throw z::exception(z::string::creator("%{err} Not a function: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(type.getFullName(z::string("::")))).value()); 01800 } 01801 01802 Ast::Scope& scope = ref(fdef).getInType(); 01803 _scopeStack.push(ptr(scope)); 01804 enterTypeSpec(ref(fdef)); 01805 01806 return ref(fdef); 01807 } 01808 01814 inline Ast::FunctionImplItem& leaveFunctionImpl(Ast::FunctionDef& fdef, Ast::FunctionBlock& block) { 01815 int idx = _unit.getImplList().size(); 01816 Ast::FunctionImplItem& item = _unit.addNode(new Ast::FunctionImplItem(idx, fdef, block)); 01817 _unit.addItem(item); 01818 01819 leaveTypeSpec(fdef); 01820 _scopeStack.pop(); 01821 01822 return item; 01823 01824 } 01825 01830 inline Ast::FunctionImplExpr& createFunctionImplExpr(Ast::FunctionImplItem& item) { 01831 const Ast::QualifiedType& qtype = createQualifiedType(false, item.getFunctionDef(), false); 01832 Ast::FunctionImplExpr& impl = _unit.addNode(new Ast::FunctionImplExpr(qtype, item)); 01833 return impl; 01834 } 01835 01840 inline Ast::FunctionDefImplExpr& createFunctionDefImplExpr(Ast::ImplItem& item) { 01841 const Ast::QualifiedType& qtype = createQualifiedType(false, item.getFunctionDef(), false); 01842 Ast::FunctionDefImplExpr& impl = _unit.addNode(new Ast::FunctionDefImplExpr(qtype, item)); 01843 return impl; 01844 } 01845 01846 public: 01851 inline Ast::RoutineBlock& createRoutineBlock(Ast::StatementList& list) { 01852 const Ast::StatementBlock& sblock = createStatementBlock(list); 01853 Ast::VariableRefList refList; 01854 Ast::RoutineBlock& block = _unit.addNode(new Ast::RoutineBlock(refList, sblock)); 01855 return block; 01856 } 01857 01862 inline Ast::FunctionBlock& createFunctionBlock(const Ast::StatementList& list) { 01863 const Ast::FunctionDef& fdef = getFunctionDef(); 01864 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 01865 col.getStatementListRefList(fdef, list); 01866 const Ast::VariableRefList& refList = col.getRefList(); 01867 01868 const Ast::StatementBlock& sblock = createStatementBlock(list); 01869 Ast::FunctionBlock& block = _unit.addNode(new Ast::FunctionBlock(refList, sblock)); 01870 return block; 01871 } 01872 01879 inline Ast::GrammarBlock& createGrammarBlock(const Ast::GrammarOptionList& optList, const Ast::GrammarStatementList& list, const Ast::GrammarLexerList& lexList) { 01880 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 01881 const Ast::VariableRefList& refList = col.getRefList(); 01882 01883 Ast::GrammarBlock& rv = _unit.addNode(new Ast::GrammarBlock(refList, optList, list, lexList)); 01884 return rv; 01885 } 01886 01891 inline Ast::WindowBlock& createWindowBlock(Ast::FunctionBlock& functionBlock) { 01892 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 01893 const Ast::VariableRefList& refList = col.getRefList(); 01894 01895 Ast::WindowBlock& rv = _unit.addNode(new Ast::WindowBlock(refList, functionBlock)); 01896 return rv; 01897 } 01898 01899 private: 01904 inline const Ast::AnyExpr& createVarExpr(const Ast::Expr& expr) { 01905 const Ast::QualifiedType& type = getQualifiedType(z::string("any")); 01906 return _unit.addNode(new Ast::AnyExpr(type, expr)); 01907 } 01908 01913 inline const Ast::CastExpr& createCastExpr(const Ast::Expr& expr) { 01914 const Ast::QualifiedType& type = expr.getType(); 01915 return _unit.addNode(new Ast::CastExpr(type, expr)); 01916 } 01917 01918 public: 01923 inline Ast::OwnerTemplate& createOwnerTemplate(const Ast::QualifiedType& type) { 01924 return _unit.addNode(new Ast::OwnerTemplate(Ast::TypeSpec::AccessType::Private, z::string("owner"), type)); 01925 } 01926 01931 inline Ast::ListTemplate& createListTemplate(const Ast::QualifiedType& type) { 01932 return _unit.addNode(new Ast::ListTemplate(Ast::TypeSpec::AccessType::Private, z::string("list"), type)); 01933 } 01934 01940 inline Ast::DictTemplate& createDictTemplate(const Ast::QualifiedType& key, const Ast::QualifiedType& type) { 01941 return _unit.addNode(new Ast::DictTemplate(Ast::TypeSpec::AccessType::Private, z::string("dict"), key, type)); 01942 } 01943 01944 public: 01949 inline Ast::ListItem& createListItem(const Ast::Expr& expr) { 01950 return _unit.addNode(new Ast::ListItem(expr)); 01951 } 01952 01958 inline void addListItem(Ast::ListList& list, const Ast::ListItem& item) { 01959 const Ast::QualifiedType* ltype = list.hasType(); 01960 const Ast::QualifiedType* rtype = ptr(item.getExpr().getType()); 01961 if(ltype != 0) { 01962 const Ast::QualifiedType& type = coerce(ref(ltype), ref(rtype)); 01963 rtype = ptr(type); 01964 } 01965 assert(rtype != 0); 01966 list.setType(rtype); 01967 return list.addItem(item); 01968 } 01969 01973 inline Ast::ListList& createListList() { 01974 return _unit.addNode(new Ast::ListList()); 01975 } 01976 01977 public: 01983 inline Ast::DictItem& createDictItem(const Ast::Expr& key, const Ast::Expr& expr) { 01984 return _unit.addNode(new Ast::DictItem(key, expr)); 01985 } 01986 01992 inline void addDictItem(Ast::DictList& list, const Ast::DictItem& item) { 01993 const Ast::QualifiedType* lkey = list.hasKey(); 01994 const Ast::QualifiedType* rkey = ptr(item.getKey().getType()); 01995 if(lkey != 0) { 01996 const Ast::QualifiedType& key = coerce(ref(lkey), ref(rkey)); 01997 rkey = ptr(key); 01998 } 01999 assert(rkey != 0); 02000 list.setKeyType(rkey); 02001 02002 const Ast::QualifiedType* ltype = list.hasType(); 02003 const Ast::QualifiedType* rtype = ptr(item.getExpr().getType()); 02004 if(ltype != 0) { 02005 const Ast::QualifiedType& type = coerce(ref(ltype), ref(rtype)); 02006 rtype = ptr(type); 02007 } 02008 assert(rtype != 0); 02009 list.setValueType(rtype); 02010 02011 return list.addItem(item); 02012 } 02013 02017 inline Ast::DictList& createDictList() { 02018 return _unit.addNode(new Ast::DictList()); 02019 } 02020 02021 public: 02027 inline Ast::DictItem& createTreeItem(const Ast::Expr& key, const Ast::Expr& expr) { 02028 return _unit.addNode(new Ast::DictItem(createVarExpr(key), createVarExpr(expr))); 02029 } 02030 02036 inline void addTreeItem(Ast::DictList& list, const Ast::DictItem& item) { 02037 return list.addItem(item); 02038 } 02039 02043 inline Ast::DictList& createTreeList() { 02044 const Ast::QualifiedType* ltype = ptr(getQualifiedType(z::string("any"))); 02045 Ast::DictList& list = _unit.addNode(new Ast::DictList()); 02046 list.setKeyType(ltype); 02047 list.setValueType(ltype); 02048 return list; 02049 } 02050 02051 private: 02057 inline const Ast::VariableDef& addClosureVariableDef(const Ast::QualifiedType& type, const zbl::TokenData& name) { 02058 const Ast::VariableDef& vdef = addVariableDef(Ast::VariableDef::Closure, type, zbl::Token::getValue(name)); 02059 return vdef; 02060 } 02061 02062 public: 02066 inline Ast::RunClosure& createRunClosure() { 02067 Ast::VariableRefList refList; 02068 const Ast::QualifiedType& qtype = getQualifiedType(z::string("void")); 02069 return _unit.addNode(new Ast::RunClosure(refList, qtype)); 02070 } 02071 02075 inline Ast::ExitClosure& createExitClosure() { 02076 Ast::VariableRefList refList; 02077 const Ast::QualifiedType& qtype = getQualifiedType(z::string("void")); 02078 return _unit.addNode(new Ast::ExitClosure(refList, qtype)); 02079 } 02080 02086 inline Ast::CallClosure& createNamedCallClosure(const zbl::TokenData& name, const Ast::Invoker& fcall) { 02087 const Ast::VariableDef& vdef = addClosureVariableDef(fcall.getInvokerType().getFunctionDef().getOutType(), name); 02088 02089 if(fcall.getInvokerType().getFunctionDef().getModifier() == Ast::FunctionDef::Modifier::Routine) { 02090 Ast::VariableRefList refList; 02091 return _unit.addNode(new Ast::CallClosure(refList, vdef, fcall)); 02092 } 02093 02094 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02095 col.getInvokerRefList(fcall); 02096 const Ast::VariableRefList& refList = col.getRefList(); 02097 02098 return _unit.addNode(new Ast::CallClosure(refList, vdef, fcall)); 02099 } 02100 02105 inline Ast::CallClosure& createCallClosure(const Ast::Invoker& fcall) { 02106 zbl::Token name(fcall.getInvokerType().getFunctionDef().getName()); 02107 return createNamedCallClosure(name, fcall); 02108 } 02109 02115 inline Ast::FunctionCallClosure& createFunctionCallClosure(const zbl::TokenData& name, const Ast::Invoker& fcall) { 02116 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02117 col.getInvokerRefList(fcall); 02118 const Ast::VariableRefList& refList = col.getRefList(); 02119 02120 const Ast::VariableDef& vdef = addClosureVariableDef(fcall.getInvokerType().getFunctionDef().getOutType(), name); 02121 return _unit.addNode(new Ast::FunctionCallClosure(refList, vdef, fcall)); 02122 } 02123 02128 inline Ast::FunctionCallClosure& createFunctionCallClosure(const Ast::Invoker& fcall) { 02129 z::string iname = fcall.getInvokerType().getFunctionDef().getName(); 02130 iname = "c" + iname; 02131 zbl::Token name(iname); 02132 02133 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02134 col.getInvokerRefList(fcall); 02135 const Ast::VariableRefList& refList = col.getRefList(); 02136 02137 const Ast::VariableDef& vdef = addClosureVariableDef(fcall.getInvokerType().getFunctionDef().getOutType(), name); 02138 return _unit.addNode(new Ast::FunctionCallClosure(refList, vdef, fcall)); 02139 } 02140 02145 inline Ast::LoopClosure& createLoopClosure(const Ast::Expr& expr) { 02146 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02147 col.getExprRefList(expr); 02148 const Ast::VariableRefList& refList = col.getRefList(); 02149 02150 return _unit.addNode(new Ast::LoopClosure(refList, expr)); 02151 } 02152 02158 inline Ast::SharedClosure& createSharedClosure(const zbl::TokenData& name, const Ast::SharedDef& sharedList) { 02159 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02160 col.getSharedDefRefList(sharedList); 02161 const Ast::VariableRefList& refList = col.getRefList(); 02162 02163 const Ast::QualifiedType& qtype = createQualifiedType(false, sharedList, false); 02164 const Ast::VariableDef& vdef = addClosureVariableDef(qtype, name); 02165 return _unit.addNode(new Ast::SharedClosure(refList, vdef, sharedList)); 02166 } 02167 02173 inline Ast::ReturnClosure& createReturnClosure(const Ast::Closure::Type& type, const Ast::ExprList& list) { 02174 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02175 col.getExprListRefList(list); 02176 const Ast::VariableRefList& refList = col.getRefList(); 02177 Ast::ReturnClosure& closure = _unit.addNode(new Ast::ReturnClosure(refList, list)); 02178 02179 closure.setType(type); 02180 return closure; 02181 } 02182 02190 inline Ast::ReturnClosure& createDefaultReturnClosure(const Ast::Closure::Type& type, Ast::FunctionDef& fdef) { 02191 Ast::ExprList& list = createExprList(); 02192 02193 const Ast::TypeSpec& ts = fdef.getOutType().getTypeSpec(); 02194 02195 // if outtype of fdef is not an outparam, return default value for qtype 02196 const Ast::OutParam* op = dynamic_cast<const Ast::OutParam*>(ptr(ts)); 02197 if(0 != op) { 02198 for(Ast::VariableDefMap::List::iterator it(ref(op).getDefList().getList()); !it.end(); ++it) { 02199 const Ast::VariableDef& vdef = ref(*it); 02200 const Ast::Expr& expr = getTypeDefaultValue(vdef.getType().getTypeSpec()); 02201 list.addExpr(expr); 02202 } 02203 } else { 02204 const Ast::Expr& expr = getTypeDefaultValue(ts); 02205 list.addExpr(expr); 02206 } 02207 02208 return createReturnClosure(type, list); 02209 } 02210 02211 public: 02216 inline Ast::ClosureList& createClosureList(Ast::Closure& closure) { 02217 Ast::ClosureList& rv = _unit.addNode(new Ast::ClosureList()); 02218 rv.addClosure(closure); 02219 return rv; 02220 } 02221 02228 inline Ast::ClosureList& addClosureToList(Ast::ClosureList& list, const Ast::Closure::Type& type, Ast::Closure& closure) { 02229 list.addClosure(closure); 02230 closure.setType(type); 02231 return list; 02232 } 02233 02239 inline Ast::ContinuationImplItem& createContinuationImplItem(Ast::ClosureList& closureList, const Ast::ReturnClosure& retnClosure) { 02240 Ast::FunctionDef& fdef = getFunctionDef(); 02241 int id = _unit.getImplList().size(); 02242 Ast::ContinuationImplItem& item = _unit.addNode(new Ast::ContinuationImplItem(id, fdef, closureList, retnClosure)); 02243 _unit.addItem(item); 02244 02245 zbl::RefCollector col(ref(this), Ast::Storage::ExternalRef); 02246 col.getImplItemRefList(item); 02247 const Ast::VariableRefList& refList = col.getRefList(); 02248 item.setXRefList(refList); 02249 02250 return item; 02251 } 02252 02259 inline Ast::ContinuationImplItem& createContinuationImplItem(Ast::ClosureList& closureList) { 02260 Ast::FunctionDef& fdef = getFunctionDef(); 02261 Ast::ReturnClosure& retnClosure = createDefaultReturnClosure(Ast::Closure::Link, fdef); 02262 return createContinuationImplItem(closureList, retnClosure); 02263 } 02264 02265 public: 02269 inline Ast::ExprList& createExprList() {return _unit.addNode(new Ast::ExprList());} 02270 02271 private: 02276 inline const Ast::Expr& convertToQueryConstant(const Ast::Expr& expr) { 02277 if(isQueryType(expr.getType())) 02278 return expr; 02279 02280 // Note there is no binary expression per se here. We are only coercing expr's 02281 // type with val, to get the query expression type from a native constant value. 02282 const Ast::QualifiedType& ctype = getQualifiedType(z::string("qval")); 02283 const Ast::QualifiedType& qtype = coerce(ctype, expr.getType()); 02284 return _unit.addNode(new Ast::QueryConstantExpr(qtype, expr)); 02285 } 02286 02287 public: 02292 inline Ast::QueryExpr& createQueryExpr(const Ast::Expr& expr) { 02293 const Ast::QualifiedType& type = getQualifiedType(z::string("query")); 02294 return _unit.addNode(new Ast::QueryExpr(type, expr)); 02295 } 02296 02302 inline Ast::QueryPartExpr& createQueryPartExpr(const Ast::Expr& keyExpr, const Ast::Expr& valExpr) { 02303 const Ast::QualifiedType& type = getQualifiedType(z::string("qpair")); 02304 const Ast::Expr& kexpr = convertToQueryConstant(keyExpr); 02305 const Ast::Expr& vexpr = convertToQueryConstant(valExpr); 02306 return _unit.addNode(new Ast::QueryPartExpr(type, kexpr, vexpr)); 02307 } 02308 02312 inline Ast::QueryValExpr& createQueryValExpr() { 02313 const Ast::QualifiedType& type = getQualifiedType(z::string("qval")); 02314 return _unit.addNode(new Ast::QueryValExpr(type)); 02315 } 02316 02317 private: 02322 inline bool isQueryType(const Ast::QualifiedType& type) { 02323 const Ast::TypeSpec* ts = ptr(type.getTypeSpec()); 02324 const Ast::UserDefinedTypeSpec* uts = dynamic_cast<const Ast::UserDefinedTypeSpec*>(ts); 02325 if(!uts) 02326 return false; 02327 return (ref(uts).getNativeType() == Ast::UserDefinedTypeSpec::ntQuery); 02328 } 02329 02330 public: 02339 inline Ast::TernaryOpExpr& createTernaryOpExpr(const Ast::Expr& lhs, const z::string& op1, const Ast::Expr& rhs1, const z::string& op2, const Ast::Expr& rhs2) { 02340 const Ast::QualifiedType& type = coerce(rhs1.getType(), rhs2.getType()); 02341 return _unit.addNode(new Ast::TernaryOpExpr(type, lhs, op1, rhs1, op2, rhs2)); 02342 } 02343 02350 inline Ast::BinaryExpr& createBinaryOpExpr(const Ast::Expr& lhs, const z::string& op, const Ast::Expr& rhs) { 02351 const Ast::QualifiedType& type = coerce(lhs.getType(), rhs.getType()); 02352 if(isQueryType(type)) { 02353 const Ast::QualifiedType& qtype = getQualifiedType(z::string("qbinary")); 02354 const Ast::Expr& lexpr = convertToQueryConstant(lhs); 02355 const Ast::Expr& rexpr = convertToQueryConstant(rhs); 02356 return _unit.addNode(new Ast::QueryBinaryExpr(qtype, lexpr, op, rexpr)); 02357 } 02358 02359 const Ast::QualifiedType& qtype = createQualifiedType(false, type.getTypeSpec(), false); 02360 return _unit.addNode(new Ast::BinaryOpExpr(qtype, lhs, op, rhs)); 02361 } 02362 02367 inline Ast::OrderedExpr& createOrderedExpr(const Ast::Expr& rhs) { 02368 const Ast::QualifiedType& type = rhs.getType(); 02369 return _unit.addNode(new Ast::OrderedExpr(type, rhs)); 02370 } 02371 02374 class IndexExprCreator : public IndexableTypeCaster { 02375 public: 02380 inline IndexExprCreator(const Ast::Expr& expr, const Ast::Expr& idx) : _rv(0), _expr(expr), _idx(idx) {} 02381 02382 public: 02388 inline Ast::IndexExpr& create(ParseContext& pctx, const Ast::TypeSpec& typeSpec) { 02389 cast(pctx, typeSpec); 02390 return pctx._unit.addNode(_rv); 02391 } 02392 02393 private: 02398 virtual void visitList(ParseContext& pctx, const Ast::ListTemplate& type) { 02399 unused(pctx); 02400 const Ast::QualifiedType& qtype = type.getType(); 02401 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02402 } 02403 02408 virtual void visitDict(ParseContext& pctx, const Ast::DictTemplate& type) { 02409 const Ast::QualifiedType& qtype = type.getType(); 02410 // possible hack. The index of a tree must be an any expr. 02411 if((qtype.getTypeSpec().getName() == "any") && (_idx.getType().getTypeSpec().getName() != "any")) { 02412 const Ast::AnyExpr& vexpr = pctx.createVarExpr(_idx); 02413 _rv = new Ast::IndexExpr(qtype, _expr, vexpr); 02414 return; 02415 } 02416 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02417 } 02418 02423 virtual void visitTree(ParseContext& pctx, const Ast::TypeDecl& type) { 02424 unused(type); 02425 02426 // The index of a tree must be an any expr. 02427 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("any")); 02428 if(_idx.getType().getTypeSpec().getName() != "any") { 02429 const Ast::AnyExpr& vexpr = pctx.createVarExpr(_idx); 02430 _rv = new Ast::IndexExpr(qtype, _expr, vexpr); 02431 return; 02432 } 02433 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02434 } 02435 02440 virtual void visitBuffer(ParseContext& pctx, const Ast::TypeDecl& type) { 02441 unused(type); 02442 02443 // The index of a buffer must be a char expr. 02444 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("char")); 02445 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02446 } 02447 02452 virtual void visitView(ParseContext& pctx, const Ast::TypeDecl& type) { 02453 unused(type); 02454 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("widget")); 02455 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02456 } 02457 02462 virtual void visitWidget(ParseContext& pctx, const Ast::TypeDecl& type) { 02463 unused(type); 02464 const Ast::QualifiedType& qtype = pctx.getQualifiedType(z::string("property")); 02465 _rv = new Ast::IndexExpr(qtype, _expr, _idx); 02466 } 02467 02468 private: 02470 Ast::IndexExpr* _rv; 02471 02473 const Ast::Expr& _expr; 02474 02476 const Ast::Expr& _idx; 02477 }; 02478 02484 inline Ast::IndexExpr& createIndexExpr(const Ast::Expr& expr, const Ast::Expr& idx) { 02485 IndexExprCreator creator(expr, idx); 02486 return creator.create(ref(this), expr.getType().getTypeSpec()); 02487 } 02488 02494 inline Ast::IndexExpr& createIndexKeyExpr(const Ast::Expr& expr, const TokenData& idx) { 02495 const Ast::Expr& idxe = createStringConstantExpr(idx); 02496 return createIndexExpr(expr, idxe); 02497 } 02498 02504 inline Ast::PrefixOpExpr& createPrefixOpExpr(const z::string& op, const Ast::Expr& rhs) { 02505 const Ast::QualifiedType& type = rhs.getType(); 02506 return _unit.addNode(new Ast::PrefixOpExpr(type, op, rhs)); 02507 } 02508 02514 inline Ast::PostfixOpExpr& createPostfixOpExpr(const Ast::Expr& lhs, const z::string& op) { 02515 const Ast::QualifiedType& type = lhs.getType(); 02516 return _unit.addNode(new Ast::PostfixOpExpr(type, lhs, op)); 02517 } 02518 02524 inline Ast::StringFormatExpr& createStringFormatExpr(const Ast::Expr& format, const Ast::DictList& list) { 02525 const Ast::QualifiedType& type = getQualifiedType(z::string("string")); 02526 return _unit.addNode(new Ast::StringFormatExpr(type, format, list)); 02527 } 02528 02533 inline Ast::ListExpr& createListExpr(const Ast::ListList& list) { 02534 const Ast::QualifiedType* ltype = list.hasType(); 02535 if(ltype == 0) 02536 ltype = ptr(getQualifiedType(z::string("void"))); 02537 02538 const Ast::ListTemplate& type = createListTemplate(ref(ltype)); 02539 const Ast::QualifiedType& etype = createQualifiedType(false, type, false); 02540 return _unit.addNode(new Ast::ListExpr(etype, list)); 02541 } 02542 02547 inline Ast::DictExpr& createDictExpr(const Ast::DictList& list) { 02548 const Ast::QualifiedType* lkey = list.hasKey(); 02549 if(lkey == 0) 02550 lkey = ptr(getQualifiedType(z::string("any"))); 02551 02552 const Ast::QualifiedType* ltype = list.hasType(); 02553 if(ltype == 0) 02554 ltype = ptr(getQualifiedType(z::string("any"))); 02555 02556 const Ast::DictTemplate& type = createDictTemplate(ref(lkey), ref(ltype)); 02557 const Ast::QualifiedType& etype = createQualifiedType(false, type, false); 02558 return _unit.addNode(new Ast::DictExpr(etype, list)); 02559 } 02560 02565 inline Ast::TreeExpr& createTreeExpr(const Ast::DictList& list) { 02566 const Ast::QualifiedType& etype = getQualifiedType(z::string("tree")); 02567 return _unit.addNode(new Ast::TreeExpr(etype, list)); 02568 } 02569 02570 public: 02576 inline Ast::VariableRef& createVariableRef(const Ast::Storage::T& storage, const Ast::VariableDef& vdef) { 02577 Ast::VariableRef& vref = _unit.addNode(new Ast::VariableRef(storage)); 02578 vref.addDef(vdef); 02579 return vref; 02580 } 02581 02586 inline Ast::VariableRef& createVariableRef(const zbl::TokenData& name) { 02587 Ast::Storage::T storage = name.storage; 02588 const Ast::VariableDef* vd = name.vdef; 02589 if(!vd) { 02590 throw z::exception(z::string::creator("%{err} Variable: %{name} not found") 02591 .arg(z::any("err"), z::any(err())) 02592 .arg(z::any("name"), z::any(zbl::Token::getValue(name))) 02593 .value()); 02594 } 02595 return createVariableRef(storage, ref(vd)); 02596 } 02597 02603 inline Ast::VariableRef& addVariableDefToList(Ast::VariableRef& vref, const zbl::TokenData& name) { 02604 const Ast::VariableDef& vdefl = vref.getLast(); 02605 const Ast::VariableDef* cvd = hasMember(vdefl, name); 02606 if(!cvd) { 02607 throw z::exception(z::string::creator("%{err} Member variable: %{name} of %{parent} not found") 02608 .arg(z::any("err"), z::any(err(name))) 02609 .arg(z::any("name"), z::any(zbl::Token::getValue(name))) 02610 .arg(z::any("parent"), z::any(vref.getLast().getName())) 02611 .value()); 02612 } 02613 vref.addDef(ref(cvd)); 02614 return vref; 02615 } 02616 02621 inline Ast::VariableRefExpr& createVariableRefExpr(const Ast::VariableRef& vref) { 02622 // get type of last entry in vardef list. So if vdl is 'x.y.i', get the qtype of 'i'. 02623 const Ast::QualifiedType& type = vref.getLast().getType(); 02624 02625 // create new qtype which is a ref of the original (const-ness remains the same) 02626 const Ast::QualifiedType& qtype = createQualifiedType(type.isConst(), type.getTypeSpec(), true); 02627 02628 // create node 02629 return _unit.addNode(new Ast::VariableRefExpr(qtype, vref)); 02630 } 02631 02637 inline Ast::Expr& createEnumRefExpr(const Ast::TypeSpec& typeSpec, const zbl::TokenData& id) { 02638 const Ast::EnumDef* enumDef = dynamic_cast<const Ast::EnumDef*>(ptr(typeSpec)); 02639 if(enumDef) { 02640 return getEnumRefExpr(ref(enumDef), zbl::Token::getValue(id)); 02641 } 02642 02643 throw z::exception(z::string::creator("%{err} Not an enum type: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(typeSpec.getFullName(z::string("::")))).value()); 02644 } 02645 02646 private: 02648 typedef z::stack<const Ast::StructDef*> StructInitStack; 02649 02651 StructInitStack _structInitStack; 02652 02653 public: 02657 inline void enterStructInit(const Ast::TypeSpec& typeSpec) { 02658 const Ast::StructDef* structDef = dynamic_cast<const Ast::StructDef*>(ptr(typeSpec)); 02659 if(structDef) { 02660 _structInitStack.push(structDef); 02661 return; 02662 } 02663 02664 throw z::exception(z::string::creator("%{err} Type is not a struct: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(typeSpec.getFullName(z::string("::")))).value()); 02665 } 02666 02672 inline Ast::StructInitItem& createStructInitItem(const zbl::TokenData& name, const Ast::Expr& expr) { 02673 const Ast::StructDef& structDef = ref(_structInitStack.top()); 02674 const Ast::VariableDef* cvd = hasUdtMember(structDef, zbl::Token::getValue(name)); 02675 if(!cvd) { 02676 throw z::exception(z::string::creator("%{err} Struct member variable: %{name} of %{parent} not found") 02677 .arg(z::any("err"), z::any(err(name))) 02678 .arg(z::any("name"), z::any(zbl::Token::getValue(name))) 02679 .arg(z::any("parent"), z::any(structDef.getName())) 02680 .value()); 02681 } 02682 02683 return _unit.addNode(new Ast::StructInitItem(ref(cvd), expr)); 02684 } 02685 02691 inline Ast::StructInitList& addStructInitItemToList(Ast::StructInitList& list, const Ast::StructInitItem& item) { 02692 list.addItem(item); 02693 return list; 02694 } 02695 02699 inline Ast::StructInitList& createStructInitList() { 02700 return _unit.addNode(new Ast::StructInitList()); 02701 } 02702 02707 inline Ast::StructInitExpr& createStructInitExpr(const Ast::StructInitList& initList) { 02708 if(_structInitStack.size() <= 0) { 02709 throw z::exception(z::string::creator("%{err} Internal error: Struct stack underflow").arg(z::any("err"), z::any(err())).value()); 02710 } 02711 02712 const Ast::StructDef* structDef = _structInitStack.pop(); 02713 const Ast::QualifiedType& type = createQualifiedType(false, ref(structDef), false); 02714 return _unit.addNode(new Ast::StructInitExpr(type, initList)); 02715 } 02716 02720 inline Ast::StructInitExpr& createStructInitEmptyExpr() { 02721 const Ast::StructInitList& initList = createStructInitList(); 02722 return createStructInitExpr(initList); 02723 } 02724 02725 public: 02733 inline Ast::InstanceExpr& createInstanceExpr(const Ast::TypeSpec& typeSpec, const Ast::ExprList& exprList) { 02734 const Ast::StructDef* strct = dynamic_cast<const Ast::StructDef*>(ptr(typeSpec)); 02735 if(strct) { 02736 const Ast::QualifiedType& type = createQualifiedType(false, ref(strct), false); 02737 return _unit.addNode(new Ast::StructExpr(type, exprList)); 02738 } 02739 02740 const Ast::TypeDefTypeSpec* typeDef = dynamic_cast<const Ast::TypeDefTypeSpec*>(ptr(typeSpec)); 02741 if(typeDef) { 02742 const Ast::QualifiedType& type = createQualifiedType(false, ref(typeDef), false); 02743 return _unit.addNode(new Ast::TypeDefExpr(type, exprList)); 02744 } 02745 02746 const Ast::FunctionDef* function = dynamic_cast<const Ast::FunctionDef*>(ptr(typeSpec)); 02747 if(function) { 02748 const Ast::QualifiedType& type = createQualifiedType(false, ref(function), false); 02749 return _unit.addNode(new Ast::FunctionExpr(type, ref(function), exprList)); 02750 } 02751 02752 const Ast::ListTemplate* list = dynamic_cast<const Ast::ListTemplate*>(ptr(typeSpec)); 02753 if(list) { 02754 const Ast::QualifiedType& type = createQualifiedType(false, ref(list), false); 02755 return _unit.addNode(new Ast::ListTemplateExpr(type, exprList)); 02756 } 02757 02758 const Ast::DictTemplate* dict = dynamic_cast<const Ast::DictTemplate*>(ptr(typeSpec)); 02759 if(dict) { 02760 const Ast::QualifiedType& type = createQualifiedType(false, ref(dict), false); 02761 return _unit.addNode(new Ast::DictTemplateExpr(type, exprList)); 02762 } 02763 02764 throw z::exception(z::string::creator("%{err} Cannot create instance for type: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(typeSpec.getFullName(z::string("::")))).value()); 02765 } 02766 02767 public: 02775 inline const Ast::QualifiedType& getInternalCallType(const TokenData& name, const Ast::ExprList& exprList) { 02776 if(zbl::Token::getValue(name) == "create") { 02777 assert(exprList.getList().size() == 1); 02778 const Ast::Expr& expr = ref(exprList.getList().at(0)); 02779 const Ast::TypeSpec& qtype = expr.getType().getTypeSpec(); 02780 const Ast::TypeDef* typeDef = dynamic_cast<const Ast::TypeDef*>(ptr(qtype)); 02781 if(!typeDef) { 02782 throw z::exception(z::string::creator("%{err} First parameter of create must be typedef type").arg(z::any("err"), z::any(err(name))).value()); 02783 } 02784 02785 const Ast::TypeSpec& targetTypeSpec = ref(typeDef).getTargetType().getTypeSpec(); 02786 const Ast::OwnerTemplate* ownerTypeSpec = dynamic_cast<const Ast::OwnerTemplate*>(ptr(targetTypeSpec)); 02787 if(!ownerTypeSpec) { 02788 throw z::exception(z::string::creator("%{err} First parameter of create must be typedef of owner type").arg(z::any("err"), z::any(err(name))).value()); 02789 } 02790 02791 const Ast::TypeSpec& instanceTypeSpec = ref(ownerTypeSpec).getType().getTypeSpec(); 02792 const Ast::QualifiedType& type = createQualifiedType(false, instanceTypeSpec, true); 02793 return type; 02794 } 02795 02796 const Ast::QualifiedType& type = getQualifiedType(z::string("void")); 02797 return type; 02798 } 02799 02805 inline Ast::InternalCallExpr& createInternalCallExpr(const TokenData& name, const Ast::ExprList& exprList) { 02806 const Ast::QualifiedType& type = getInternalCallType(name, exprList); 02807 return _unit.addNode(new Ast::InternalCallExpr(type, zbl::Token::getValue(name), exprList)); 02808 } 02809 02814 inline Ast::InvokerCallExpr& createInvokerCallExpr(const Ast::Invoker& invoker) { 02815 const Ast::QualifiedType& type = invoker.getInvokerType().getFunctionDef().getOutType(); 02816 return _unit.addNode(new Ast::InvokerCallExpr(type, invoker)); 02817 } 02818 02823 inline Ast::FunctionCallExpr& createFunctionCallExpr(Ast::ContinuationImplItem& continuation) { 02824 const Ast::QualifiedType& type = continuation.getInitClosure().getOutType(); 02825 return _unit.addNode(new Ast::FunctionCallExpr(type, continuation)); 02826 } 02827 02828 public: 02834 inline Ast::Invoker& createInvoker(const Ast::InvokerType& invokerType, const Ast::ExprList& exprList) { 02835 return _unit.addNode(new Ast::Invoker(invokerType, exprList)); 02836 } 02837 02838 public: 02843 inline Ast::FunctionCall& createFunctionCall(const Ast::TypeSpec& typeSpec) { 02844 const Ast::FunctionDef* function = dynamic_cast<const Ast::FunctionDef*>(ptr(typeSpec)); 02845 if(function) { 02846 return _unit.addNode(new Ast::FunctionCall(ref(function))); 02847 } 02848 02849 throw z::exception(z::string::creator("%{err} Not a function type: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(typeSpec.getFullName(z::string("::")))).value()); 02850 } 02851 02856 inline Ast::FunctionDefCall& createFunctionDefCall(const Ast::ImplItem& item) { 02857 return _unit.addNode(new Ast::FunctionDefCall(item.getFunctionDef(), item)); 02858 } 02859 02864 inline Ast::FunctionImplCall& createFunctionImplCall(const Ast::ImplItem& item) { 02865 return _unit.addNode(new Ast::FunctionImplCall(item.getFunctionDef(), item)); 02866 } 02867 02872 inline Ast::FunctorCall& createFunctorExprCall(const Ast::Expr& expr) { 02873 const Ast::TypeSpec& typeSpec = expr.getType().getTypeSpec(); 02874 const Ast::FunctionDef* function = dynamic_cast<const Ast::FunctionDef*>(ptr(typeSpec)); 02875 if(function) { 02876 return _unit.addNode(new Ast::FunctorCall(ref(function), expr)); 02877 } 02878 02879 throw z::exception(z::string::creator("%{err} Not a function type: %{name}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any(typeSpec.getFullName(z::string("::")))).value()); 02880 } 02881 02886 inline Ast::FunctorCall& createFunctorObjectCall(const Ast::VariableRef& vref) { 02887 Ast::Expr& expr = createVariableRefExpr(vref); 02888 return createFunctorExprCall(expr); 02889 } 02890 02891 public: 02897 inline Ast::NumericConstantExpr& createNumericConstantExpr(const z::string& typestr, const z::string& val) { 02898 const Ast::QualifiedType& type = getQualifiedType(typestr); 02899 return _unit.addNode(new Ast::NumericConstantExpr(type, val)); 02900 } 02901 02906 inline Ast::BooleanConstantExpr& createBooleanConstantExpr(const z::string& val) { 02907 const Ast::QualifiedType& type = getQualifiedType(z::string("bool")); 02908 return _unit.addNode(new Ast::BooleanConstantExpr(type, val)); 02909 } 02910 02915 inline Ast::CharConstantExpr& createCharConstantExpr(const z::string& val) { 02916 const Ast::QualifiedType& type = getQualifiedType(z::string("char")); 02917 return _unit.addNode(new Ast::CharConstantExpr(type, val)); 02918 } 02919 02924 inline Ast::StringConstantExpr& createStringConstantExpr(const zbl::TokenData& token) { 02925 z::string val = zbl::Token::getValue(token); 02926 const Ast::QualifiedType& type = getQualifiedType(z::string("string")); 02927 return _unit.addNode(new Ast::StringConstantExpr(type, val)); 02928 } 02929 02930 public: 02935 inline Ast::ExprStatement& createExprStatement(const Ast::Expr& expr) { 02936 return _unit.addNode(new Ast::ExprStatement(expr)); 02937 } 02938 02943 inline Ast::StatementBlock& createStatementBlock(const Ast::StatementList& list) { 02944 return _unit.addNode(new Ast::StatementBlock(list)); 02945 } 02946 02951 inline Ast::DefineVarStatement& createDefineVarStatement(Ast::InitVariableDef& vdef) { 02952 return _unit.addNode(new Ast::DefineVarStatement(vdef)); 02953 } 02954 02960 inline Ast::IfThenStatement& createIfThenStatement(const Ast::Expr& cond, const Ast::StatementList& tlist) { 02961 return _unit.addNode(new Ast::IfThenStatement(cond, tlist)); 02962 } 02963 02970 inline Ast::IfElseStatement& createIfElseStatement(const Ast::Expr& cond, const Ast::StatementList& tlist, const Ast::StatementList& flist) { 02971 return _unit.addNode(new Ast::IfElseStatement(cond, tlist, flist)); 02972 } 02973 02980 inline Ast::IfElseStatement& createIfElseIfStatement(const Ast::Expr& cond, const Ast::StatementList& tlist, Ast::Statement& fstmt) { 02981 Ast::StatementList& flist = enterStatementList(fstmt); 02982 Ast::IfElseStatement& rv = createIfElseStatement(cond, tlist, flist); 02983 leaveStatementList(flist); 02984 return rv; 02985 } 02986 02991 inline Ast::SelectStatement& createSelectStatement(const Ast::SwitchLabelList& list) { 02992 return _unit.addNode(new Ast::SelectStatement(list)); 02993 } 02994 03000 inline Ast::SwitchStatement& createSwitchStatement(const Ast::Expr& expr, const Ast::SwitchLabelList& list) { 03001 return _unit.addNode(new Ast::SwitchStatement(expr, list)); 03002 } 03003 03007 inline Ast::SwitchLabelList& createSwitchLabelList() { 03008 return _unit.addNode(new Ast::SwitchLabelList()); 03009 } 03010 03016 inline Ast::CaseLabel& createCaseLabel(const Ast::Expr& expr, const Ast::StatementList& list) { 03017 return _unit.addNode(new Ast::CaseLabel(expr, list)); 03018 } 03019 03024 inline Ast::DefaultLabel& createDefaultLabel(const Ast::StatementList& list) { 03025 return _unit.addNode(new Ast::DefaultLabel(list)); 03026 } 03027 03035 inline Ast::ForStatement& createForStatement(const Ast::InitVariableDef& init, const Ast::Expr& cond, const Ast::Expr& incx, const Ast::StatementList& list) { 03036 return _unit.addNode(new Ast::ForStatement(init, cond, incx, list)); 03037 } 03038 03044 inline Ast::ForeachStatement& createForeachStatement(const Ast::InitVariableDef& init, const Ast::StatementList& list) { 03045 return _unit.addNode(new Ast::ForeachStatement(init, list)); 03046 } 03047 03053 inline Ast::WhileStatement& createWhileStatement(const Ast::Expr& cond, const Ast::StatementList& list) { 03054 return _unit.addNode(new Ast::WhileStatement(cond, list)); 03055 } 03056 03062 inline Ast::DoWhileStatement& createDoWhileStatement(const Ast::Expr& cond, const Ast::StatementList& list) { 03063 return _unit.addNode(new Ast::DoWhileStatement(cond, list)); 03064 } 03065 03071 inline Ast::LogStatement& createLogStatement(const z::string& name, const Ast::ExprList& list) { 03072 return _unit.addNode(new Ast::LogStatement(name, list)); 03073 } 03074 03078 inline Ast::BreakStatement& createBreakStatement() { 03079 return _unit.addNode(new Ast::BreakStatement()); 03080 } 03081 03085 inline Ast::ContinueStatement& createContinueStatement() { 03086 return _unit.addNode(new Ast::ContinueStatement()); 03087 } 03088 03092 inline Ast::EmptyStatement& createEmptyStatement() { 03093 return _unit.addNode(new Ast::EmptyStatement()); 03094 } 03095 03100 inline Ast::RoutineReturnStatement& createRoutineReturnStatement(const Ast::Expr& expr) { 03101 return _unit.addNode(new Ast::RoutineReturnStatement(expr)); 03102 } 03103 03108 inline Ast::FunctionReturnStatement& createFunctionReturnStatement(const Ast::ExprList& list) { 03109 Ast::FunctionDef& fdef = getFunctionDef(); 03110 return _unit.addNode(new Ast::FunctionReturnStatement(fdef, list)); 03111 } 03112 03117 inline Ast::TypeSpecStatement& createTypeSpecStatement(const Ast::TypeSpec& typeSpec) { 03118 return _unit.addNode(new Ast::TypeSpecStatement(typeSpec)); 03119 } 03120 03125 inline Ast::TypeSpecStatement& createFunctionImplStatement(const Ast::ImplItem& item) { 03126 return createTypeSpecStatement(item.getFunctionDef()); 03127 } 03128 03129 private: 03134 inline Ast::Scope& enterScope(const Ast::Scope::Type& type) { 03135 Ast::Scope& scope = _unit.addNode(new Ast::Scope(type)); 03136 _scopeStack.push(ptr(scope)); 03137 return scope; 03138 } 03139 03143 inline void leaveScope(const Ast::Scope::Type& type) { 03144 assert(_scopeStack.size() > 0); 03145 Ast::Scope& scope = ref(_scopeStack.top()); 03146 if(scope.getType() != type) { 03147 throw z::exception(z::string::creator("%{err} Internal error: Scope type mismatch: %{name} != %{scope}").arg(z::any("err"), z::any(err())).arg(z::any("name"), z::any((int)type)).arg(z::any("scope"), z::any((int)scope.getType())).value()); 03148 } 03149 _scopeStack.pop(); 03150 } 03151 03152 public: 03156 inline Ast::Scope& enterInParamScope() { 03157 return enterScope(Ast::Scope::InParam); 03158 } 03159 03162 inline void leaveInParamScope() { 03163 return leaveScope(Ast::Scope::InParam); 03164 } 03165 03166 public: 03170 inline Ast::Scope& enterBlockScope() { 03171 return enterScope(Ast::Scope::Block); 03172 } 03173 03176 inline void leaveBlockScope() { 03177 return leaveScope(Ast::Scope::Block); 03178 } 03179 03180 public: 03184 inline Ast::Scope& enterContinuation() { 03185 return enterScope(Ast::Scope::Continuation); 03186 } 03187 03192 inline Ast::ContinuationImplItem& leaveContinuation(Ast::ContinuationImplItem& continuation) { 03193 leaveScope(Ast::Scope::Continuation); 03194 return continuation; 03195 } 03196 03197 private: 03200 inline void resetCurrentVDef() { 03201 if(_curr_vdef) { 03202 ref(_scopeStack.top()).addDef(ref(_curr_vdef)); 03203 _curr_vdef = 0; 03204 } 03205 } 03206 03207 public: 03212 inline Ast::StatementList& enterStatementList(Ast::Statement& stmt) { 03213 enterScope(Ast::Scope::Block); 03214 Ast::StatementList& list = _unit.addNode(new Ast::StatementList()); 03215 resetCurrentVDef(); 03216 list.addStatement(stmt); 03217 return list; 03218 } 03219 03224 inline Ast::StatementList& leaveStatementList(Ast::StatementList& list) { 03225 leaveScope(Ast::Scope::Block); 03226 return list; 03227 } 03228 03229 public: 03233 inline Ast::StatementList& createEmptyStatementList() { 03234 return _unit.addNode(new Ast::StatementList()); 03235 } 03236 03242 inline Ast::StatementList& addStatement(Ast::StatementList& list, Ast::Statement& stmt) { 03243 resetCurrentVDef(); 03244 list.addStatement(stmt); 03245 return list; 03246 } 03247 03248 public: 03252 inline void setProjectDef(const Ast::StructInitExpr& expr) {_unit.setProjectDef(expr);} 03253 03254 private: 03256 zbl::Compiler& _compiler; 03257 03259 Ast::Unit& _unit; 03260 03261 private: 03263 typedef z::stack<Ast::Scope*> ScopeStack; 03264 03266 ScopeStack _scopeStack; 03267 03268 private: 03270 typedef z::stack<Ast::GrammarLexer*> GrammarLexerStack; 03271 03273 GrammarLexerStack _grammarLexerStack; 03274 03275 private: 03277 Ast::InitVariableDef* _curr_vdef; 03278 03279 private: 03281 Token _nullToken; 03282 }; 03283 }