Exemple #1
0
// 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);
    }
}    
Exemple #2
0
// 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();
}