// variable (parameter, keyword-value) reference void DCompiler::Var(RefDNode n) { string V=n->getText(); int i=pro->FindVar(V); if( i != -1) { n->SetVarIx(i); return; } DVar *c=pro->FindCommonVar(V); if( c != NULL) { n->setType(VARPTR); n->SetVar(c); return; } SizeT u=pro->AddVar(V); if( env != NULL) { SizeT e=env->AddEnv(); if( u != e) throw GDLException("env and pro out of sync."); } n->SetVarIx(static_cast<int>(u)); // cout << "Added Var "<<V<<" as #" << u << endl; }
BreakableNode( const RefDNode& refNode): ProgNode( refNode) { if( refNode->GetFirstChild() != RefDNode(antlr::nullAST)) { down = NewProgNode( refNode->GetFirstChild()); } if( refNode->GetNextSibling() != RefDNode(antlr::nullAST)) { right = NewProgNode( refNode->GetNextSibling()); } }
BLOCKNode( const RefDNode& refNode): ProgNode( refNode) { if( refNode->GetFirstChild() != RefDNode(antlr::nullAST)) { down = NewProgNode( refNode->GetFirstChild()); } if( refNode->GetNextSibling() != RefDNode(antlr::nullAST)) { right = NewProgNode( refNode->GetNextSibling()); // first statement if( down != NULL) down->GetLastSibling()->KeepRight( right); else this->KeepDown( right); } }
SizeT getLine() const { if( line != 0) return line; if( errorNodeP != NULL) return errorNodeP->getLine(); if( errorNode != static_cast<RefDNode>(antlr::nullAST)) return errorNode->getLine(); return 0; }
IFNode( const RefDNode& refNode): ProgNode( refNode) { if( refNode->GetFirstChild() != RefDNode(antlr::nullAST)) { down = NewProgNode( refNode->GetFirstChild()); } if( refNode->GetNextSibling() != RefDNode(antlr::nullAST)) { right = NewProgNode( refNode->GetNextSibling()); } assert( down != NULL); // first alternative if( right != NULL) { ProgNodeP s1 = down->GetNextSibling(); // skip expr s1->GetLastSibling()->KeepRight( right); } }
IF_ELSENode( const RefDNode& refNode): ProgNode( refNode) { // std::cout << "IF_ELSENode" << std::endl; if( refNode->GetFirstChild() != RefDNode(antlr::nullAST)) { down = NewProgNode( refNode->GetFirstChild()); } if( refNode->GetNextSibling() != RefDNode(antlr::nullAST)) { right = NewProgNode( refNode->GetNextSibling()); } assert( down != NULL); // IF expr s1 s2 // first alternative // s1 is always a BLOCK (gdlc.tree.g, if_statement) // right MUST be set here even if NULL as it IS set to 2nd alternative ProgNodeP s1 = down->GetNextSibling(); // skip expr if( s1->GetFirstChild() == NULL || s1->KeepDown()) { s1->KeepDown( right); } else { s1->GetFirstChild()->GetLastSibling()->KeepRight( right); } if( right != NULL) { // 2nd alternative ProgNodeP s2 = s1->GetNextSibling(); s2->GetLastSibling()->KeepRight( right); // disconnect s2 } }
void DCompiler::Label(RefDNode n) { LabelListT& ll = pro->LabelList(); string lab=n->getText(); int ix = ll.Find( lab); if( ix != -1) { throw( GDLException(n, "Label "+lab+" defined more than once.")); } else { ll.Add( lab, NULL); // insert first without node } }
void AddLineOffset( SizeT lineOffset, RefDNode astR) { astR->SetLine( astR->getLine() + lineOffset); if( astR->getFirstChild() != NULL) AddLineOffset( lineOffset, (RefDNode)astR->getFirstChild() ); if( astR->getNextSibling() != NULL) AddLineOffset( lineOffset, (RefDNode)astR->getNextSibling() ); }
void DCompiler::SysVar(RefDNode n) { n->SetVar(NULL); }
RefDNode DCompiler::ByReference(RefDNode nIn) { static RefDNode null = static_cast<RefDNode>(antlr::nullAST); // #ifdef GDL_DEBUG // cout << "ByReference: in:" << endl; // antlr::print_tree pt; // pt.pr_tree(static_cast<antlr::RefAST>( nIn)); // cout << endl; // #endif RefDNode n = nIn; // APRO,++(a=2) is passed like APRO,a // APRO,(((a=2))=3) // forbidden in GDL // Makes IDL segfault: APRO,++(((a=2))=3) int t=n->getType(); // expressions (braces) are ignored do { while( n->getType() == EXPR) n = n->getFirstChild(); t = n->getType(); if( t == DEC || t == INC) // only preinc can be reference { n = n->getFirstChild(); t = n->getType(); } } while( t == DEC || t == INC || t == EXPR); // // expressions (braces) are ignored // while( n->getType() == EXPR) n = n->getFirstChild(); // t=n->getType(); bool assignReplace = false; if( t == ASSIGN_REPLACE) { assignReplace = true; n = n->getFirstChild()->getNextSibling(); t=n->getType(); } // expressions (braces) are ignored while( n->getType() == EXPR) n = n->getFirstChild(); t=n->getType(); // only var, common block var and deref ptr are passed by reference // note: trinary op is REF_CHECK // *** see AssignReplace(...) if( !assignReplace && t != VAR && t != VARPTR && t != DEREF && !GDLTreeParser::IsREF_CHECK(t)) // && t != QUESTION) return null; // #ifdef GDL_DEBUG // cout << "ByReference: out:" << endl; // pt.pr_tree(static_cast<antlr::RefAST>( n)); // cout << endl; // #endif return n; }