// Parse expression void FunctionNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end, Parser::size_type v1) { Parser::size_type pos, last; int plevel = 0; // Sanity check (start/end are function parenthesis) if(start >= end) throw(SyntaxException()); // Look last = start + 1; for(pos = start + 1; pos <= end && start + 1 != end; pos++) { switch(parser[pos].GetType()) { case Token::TypeOpenParenthesis: { plevel++; break; }; case Token::TypeComma: case Token::TypeCloseParenthesis: { // Handle Close parenthesis for all but the last one at the end if(parser[pos].GetType() == Token::TypeCloseParenthesis && pos != end) { plevel--; if(plevel < 0) { UnmatchedParenthesisException e; e.SetStart(parser[pos].GetStart()); e.SetEnd(parser[pos].GetEnd()); throw(e); } break; } // Handle comma, or if it was the ending parenthesis treat it like comma if(plevel == 0) { if(pos > last) { // reference parameter? if(parser[last].GetType() == Token::TypeAmpersand) { // Reference parameter, check position and type of next parameter if(last == pos - 2 && parser[last + 1].GetType() == Token::TypeIdentifier) { // Get value list ValueList *vlist = m_expr->GetValueList(); if(vlist == 0) { NoValueListException e; e.SetStart(parser[last + 1].GetStart()); e.SetEnd(parser[last + 1].GetEnd()); throw(e); } // Get name string ident = parser[last + 1].GetIdentifier(); // Make sure it is not a constant if(vlist->IsConstant(ident)) { ConstantReferenceException e(ident); e.SetStart(parser[last + 1].GetStart()); e.SetEnd(parser[last + 1].GetEnd()); throw(e); } // Get address double *vaddr = vlist->GetAddress(ident); if(vaddr == 0) { // Try to add it and get again vlist->Add(ident); vaddr = vlist->GetAddress(ident); } if(vaddr == 0) { NotFoundException e(ident); e.SetStart(parser[last + 1].GetStart()); e.SetEnd(parser[last + 1].GetEnd()); throw(e); } // Add it m_refs.push_back(vaddr); } else { SyntaxException e; e.SetStart(parser[last].GetStart()); e.SetEnd(parser[pos].GetEnd()); throw(e); } } // TypeAmpersand else { // Create node aptr(Node) n(parser.ParseRegion(last, pos - 1)); m_nodes.push_back(n.get()); n.release(); } } else { SyntaxException e; e.SetStart(parser[pos].GetStart()); e.SetEnd(parser[pos].GetEnd()); throw(e); } last = pos + 1; } break; } default: break; } } // plevel should be zero if(plevel != 0) { UnmatchedParenthesisException e; e.SetStart(parser[end].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } // Check argument count if(m_argMin != -1 && m_nodes.size() < (vector<Node*>::size_type)m_argMin) { InvalidArgumentCountException e(GetName()); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } if(m_argMax != -1 && m_nodes.size() > (vector<Node*>::size_type)m_argMax) { InvalidArgumentCountException e(GetName()); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } if(m_refMin != -1 && m_refs.size() < (vector<double*>::size_type)m_refMin) { InvalidArgumentCountException e(GetName()); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } if(m_refMax != -1 && m_refs.size() > (vector<double*>::size_type)m_refMax) { InvalidArgumentCountException e(GetName()); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } }
// Parse void AssignNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end, Parser::size_type v1) { // Check some basic syntax if(v1 != start + 1 || v1 >= end) { SyntaxException e; e.SetStart(parser[start].GetStart()); e.SetEnd(parser[end].GetEnd()); throw(e); } // Get the value list ValueList *vlist = m_expr->GetValueList(); if(vlist == 0) { NoValueListException e; e.SetStart(parser[start].GetStart()); e.SetEnd(parser[start].GetEnd()); throw(e); } // Determine variable name string ident = parser[start].GetIdentifier(); // Make sure it is not a constant if(vlist->IsConstant(ident)) { ConstantAssignException e(ident); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[v1].GetEnd()); throw(e); } // Get address double *vaddr = vlist->GetAddress(ident); if(vaddr == 0) { // If it does not already exist, try to create it vlist->Add(ident); vaddr = vlist->GetAddress(ident); } if(vaddr == 0) { NotFoundException e(ident); e.SetStart(parser[start].GetStart()); e.SetEnd(parser[start].GetEnd()); throw(e); } // Parse the node (will throw if it can not parse) aptr(Node) n(parser.ParseRegion(v1 + 1, end)); // Set data m_var = vaddr; m_rhs = n.release(); }