Zen
A cross-platform functional programming language

/home/renji/Data/projects/zenlang/sources/zbl/ParseContext.hpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines