Пример #1
0
        public override void GenCpp()
        {
            var header = @"
#include ""ASTToCoords.h""
//#include <g3log/g3log.hpp>

#include <iostream>
#include <exception>
#include <memory>
#include <string>
#include <memory>

#include ""llvm/Support/Casting.h""
/*
Create Coords object for given AST node and update AST-to_Coords
mappings. Currently this means just the ast2coords unorderedmaps,
one for Clang AST objects inheriting from Stmt, and one for Clang
AST objects inheriting from Decl. We maintain both forward and
backwards maps. See AST.h for the translations.
*/
using namespace ast2coords;

void ASTToCoords::setASTState(coords::Coords* coords, clang::Stmt* stmt, clang::ASTContext* c)
{
    
    if(auto dc = clang::dyn_cast<clang::CXXUnresolvedConstructExpr>(stmt)){

        auto begin = c->getFullLoc(dc->getLParenLoc());
        auto end = c->getFullLoc(dc->getRParenLoc());
        clang::LangOptions lopt;
        clang::SourceLocation b = c->getSourceManager().getSpellingLoc(dc->getLParenLoc());//(d->getLocStart()), _e(d->getLocEnd());
        clang::SourceLocation e = c->getSourceManager().getSpellingLoc(dc->getRParenLoc());
        //auto sm = c->getSourceManager();
        auto code = std::string(c->getSourceManager().getCharacterData(b),
        c->getSourceManager().getCharacterData(e)-c->getSourceManager().getCharacterData(b));
        //std::cout<<code<<""\n"";
        code = code == """" ? ""No Source Snip Available"" : code;

        if (auto dc = clang::dyn_cast<clang::DeclRefExpr>(stmt))
        {
            code = dc->getFoundDecl()->getNameAsString();
        }
        
        code = ""INJECTED : "" + code;

        coords->state_ = new coords::ASTState(
            """",
            """",
            """",
            (clang::dyn_cast<clang::DeclRefExpr>(stmt)) ? (clang::dyn_cast<clang::DeclRefExpr>(stmt))->getDecl()->getNameAsString() : """",
            code,
            begin.getSpellingLineNumber(),
            begin.getSpellingColumnNumber(),
            end.getSpellingLineNumber(),
            end.getSpellingColumnNumber()
        );
        return;
    }
    auto range = stmt->getSourceRange();
    auto begin = c->getFullLoc(range.getBegin());
    auto end = c->getFullLoc(range.getEnd());
    clang::LangOptions lopt;
    clang::SourceLocation b = c->getSourceManager().getSpellingLoc(range.getBegin());//(d->getLocStart()), _e(d->getLocEnd());
    clang::SourceLocation e = c->getSourceManager().getSpellingLoc(range.getEnd());
    //auto sm = c->getSourceManager();
    auto code = std::string(c->getSourceManager().getCharacterData(b),
        c->getSourceManager().getCharacterData(e)-c->getSourceManager().getCharacterData(b));
    //std::cout<<code<<""\n"";
    code = code == """" ? ""No Source Snip Available"" : code;

    if(auto dc = clang::dyn_cast<clang::DeclRefExpr>(stmt))
    {
        code = dc->getFoundDecl()->getNameAsString();
    }

    coords->state_ = new coords::ASTState(
        """",
        """",
        """",
        (clang::dyn_cast<clang::DeclRefExpr>(stmt)) ? (clang::dyn_cast<clang::DeclRefExpr>(stmt))->getDecl()->getNameAsString() : """",
        code,
        begin.getSpellingLineNumber(),
        begin.getSpellingColumnNumber(),
        end.getSpellingLineNumber(),
        end.getSpellingColumnNumber()
    );
    /*
    coords->state_.file_id_ = new std::string("""");
    coords->state_.file_name_ = """";
    coords->state_.file_path_ = """";

    coords->state_.name_ = 
        ((clang::DeclRefExpr*) stmt) ? ((clang::DeclRefExpr*) stmt)->getDecl()->getNameAsString() : """";


    coords->state_.begin_line_no_ = begin.getSpellingLineNumber();
    coords->state_.begin_col_no_ = begin.getSpellingColumnNumber();
    coords->state_.end_line_no_ = end.getSpellingLineNumber();
    coords->state_.end_col_no_ = end.getSpellingColumnNumber();
    */
}

void ASTToCoords::setASTState(coords::Coords* coords, clang::Decl* decl, clang::ASTContext* c)
{ 
    auto parent = c->getParents(*decl)[0].get<clang::Stmt>();
    clang::SourceRange range;
    if(parent) range = parent->getSourceRange();
    else range = decl->getSourceRange();
    auto begin = c->getFullLoc(range.getBegin());
    auto end = c->getFullLoc(range.getEnd());
    clang::LangOptions lopt;
    clang::SourceLocation b = c->getSourceManager().getSpellingLoc(range.getBegin());//(d->getLocStart()), _e(d->getLocEnd());
    clang::SourceLocation e = c->getSourceManager().getSpellingLoc(range.getEnd());//(clang::Lexer::getLocForEndOfToken(_e, 0, c->getSourceManager(), lopt));
    //auto sm = c->getSourceManager();
    auto code = std::string(c->getSourceManager().getCharacterData(b),
        c->getSourceManager().getCharacterData(e)-c->getSourceManager().getCharacterData(b));
    //std::cout<<code<<""\n"";
    code = code == """" ? ""No Source Snip Available"" : code;
    coords->state_ = new coords::ASTState(
        """",
        """",
        """",
        (clang::dyn_cast<clang::NamedDecl>(decl)) ? (clang::dyn_cast<clang::NamedDecl>(decl))->getNameAsString() : """",
        code,
        begin.getSpellingLineNumber(),
        begin.getSpellingColumnNumber(),
        end.getSpellingLineNumber(),
        end.getSpellingColumnNumber()
    );
    /*
    coords->state_.file_id_ = """";
    coords->state_.file_name_ = """";
    coords->state_.file_path_ = """";

    coords->state_.name_ = ((clang::NamedDecl*) decl) ? ((clang::NamedDecl*) decl)->getNameAsString() : """";

    coords->state_.begin_line_no_ = begin.getSpellingLineNumber();
    coords->state_.begin_col_no_ = begin.getSpellingColumnNumber();
    coords->state_.end_line_no_ = end.getSpellingLineNumber();
    coords->state_.end_col_no_ = end.getSpellingColumnNumber();
    */
}

ASTToCoords::ASTToCoords() {
   this->stmt_coords = new std::unordered_map<const clang::Stmt*, coords::Coords*>();
   this->decl_coords = new std::unordered_map<const clang::Decl*, coords::Coords*>();
   this->coords_stmt = new std::unordered_map<coords::Coords*,const clang::Stmt*>();
   this->coords_decl = new std::unordered_map<coords::Coords*,const clang::Decl*>();
}

";

            var file = header;

            foreach (var prod in ParsePeirce.Instance.Grammar.Productions)
            {
                foreach (var pcase in prod.Cases)
                {
                    if (pcase.CaseType == Grammar.CaseType.Passthrough || pcase.CaseType == Grammar.CaseType.Inherits)
                    {
                        continue;
                    }

                    int i = 0, j = 0;

                    if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                    {
                        var mkStr = @"
coords::" + prod.Name + @"* ASTToCoords::mk" + prod.Name + "(const ast::" + prod.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                                                                                                                         string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") +
                                    (prod.HasValueContainer() ? "," +
                                     Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + @"){
    coords::" + prod.Name + @"* coord = new coords::" + prod.Name + @"(" + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++j))
                                    + (prod.HasValueContainer() ? (pcase.Productions.Count > 0 ? "," : "") +
                                       Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => " value" + v) : "")
                                    + @");
    ast::" + prod.Name + "* unconst_ast = const_cast<ast::" + prod.Name + @"*>(ast);" +
                                    (prod.HasValueContainer() ? Peirce.Join("", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "\n\t//coord->setValue(value" + v + "," + v + ");") : "")
                                    + @"


    if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
        clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
    }
    /*if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
        clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?  
    }*/
    return coord;
}
";
                        file += mkStr;
                        break;
                    }
                    else
                    {
                        switch (pcase.CaseType)
                        {
                        case Grammar.CaseType.Ident:
                        {
                            break;
                        }

                        case Grammar.CaseType.Op:
                        case Grammar.CaseType.Hidden:
                        case Grammar.CaseType.Pure:
                        {
                            if (!(pcase.IsFuncDeclare || pcase.IsTranslationDeclare || pcase.IsVarDeclare))
                            {
                                var mkStr = @"
coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                                                                                                                            string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") +
                                            (prod.HasValueContainer() ? "," +
                                             Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + @"){
    coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(" + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++j))
                                            + (prod.HasValueContainer() ? (pcase.Productions.Count > 0 ? "," : "") +
                                               Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => " value" + v) : "") + @");
    ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);"
                                            +
                                            (prod.HasValueContainer() ? Peirce.Join("", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "\n\t//coord->setValue(value" + v + "," + v + ");") : "")

                                            + @"
    /*if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
        clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
    }*/
    if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
        clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?  
    }
    return coord;
}
";
                                file += mkStr;
                            }
                            else
                            {
                                var mkStr = @"
coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                                                                                                                            string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") +
                                            (prod.HasValueContainer() ? "," +
                                             Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + @"){
    coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(" + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++j))
                                            + (prod.HasValueContainer() ? "," +
                                               Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => " value" + v) : "") + @");
    ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);"
                                            +
                                            (prod.HasValueContainer() ? Peirce.Join("", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "\n\t//coord->setValue(value" + v + "," + v + ");") : "")

                                            + @"
 
    if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
        clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
    }
    /*if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
        clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?  
    }*/
    return coord;
}
";
                                file += mkStr;
                            }
                            break;
                        }

                        /*case Grammar.CaseType.Pure://fix this!!
                         *  {
                         *      if (!(pcase.IsFuncDeclare || pcase.IsTranslationDeclare || pcase.IsVarDeclare))
                         *      {
                         *          var mkStr = @"
                         * coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                         * string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") + @"){
                         * coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(" + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++j)) + @");
                         * ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);
                         *
                         * /*if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
                         * clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
                         * setASTState(coord, unconst_dc, c);
                         * overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses?
                         * overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
                         * }
                         * if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
                         * clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
                         * setASTState(coord, unconst_dc, c);
                         * overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses?
                         * overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?
                         * }
                         * return coord;
                         * }
                         * ";
                         *          file += mkStr;
                         *      }
                         *      else
                         *      {
                         *
                         *          var mkStr = @"
                         * coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                         * string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") + @"){
                         * coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(" + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++j)) + @");
                         * ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);
                         *
                         * if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
                         * clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
                         * setASTState(coord, unconst_dc, c);
                         * overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses?
                         * overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
                         * }
                         * /*if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
                         * clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
                         * setASTState(coord, unconst_dc, c);
                         * overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses?
                         * overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?
                         * }
                         * return coord;
                         * }
                         * ";
                         *          file += mkStr;
                         *      }
                         *      break;
                         *  }*/
                        case Grammar.CaseType.ArrayOp:
                        {
                            if (!(pcase.IsFuncDeclare || pcase.IsTranslationDeclare || pcase.IsVarDeclare))
                            {
                                var mkStr = @"
coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c, std::vector<coords::" + pcase.Productions[0].Name + @"*> operands ){
    coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(operands);
    ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);

    /*if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
        clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
    }*/
    if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
        clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?  
    }
    return coord;
}
";
                                file += mkStr;
                            }
                            else if (pcase.IsTranslationDeclare)
                            {
                                var mkStr = @"
coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c, std::vector<coords::" + pcase.Productions[0].Name + @"*> operands ){
    coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(operands);
    //ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);

    coord->state_ = new coords::ASTState(
        """",
        """",
        """",
        """",
        """",
        0,
        0,
        0,
        0
    );

    return coord;
}
";
                                file += mkStr;
                            }
                            else
                            {
                                var mkStr = @"
coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c, std::vector<coords::" + pcase.Productions[0].Name + @"*> operands ){
    coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(operands);
    ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);

    if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
        clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
    }
    /*if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
        clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
        setASTState(coord, unconst_dc, c);
        overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses? 
        overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?  
    }*/
    return coord;
}
";
                                file += mkStr;
                            }

                            break;
                        }

                            /* case Grammar.CaseType.Value:
                             *   {
                             *       var mkStr = @"
                             * coords::" + pcase.Name + @"* ASTToCoords::mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.ValueCount > 0 ? "," +
                             * Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType + " operand" + v) : "") + @"){
                             * coords::" + pcase.Name + @"* coord = new coords::" + pcase.Name + @"(" + Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => " operand" + v) + @");
                             * ast::" + pcase.Name + "* unconst_ast = const_cast<ast::" + pcase.Name + @"*>(ast);
                             * //bad Clang! bad!
                             * /*if (auto dc = clang::dyn_cast<clang::NamedDecl>(unconst_ast)){
                             * clang::NamedDecl* unconst_dc = const_cast<clang::NamedDecl*>(dc);
                             * setASTState(coord, unconst_dc, c);
                             * overrideDecl2Coords(dc, coord);     // Use Clang canonical addresses?
                             * overrideCoords2Decl(coord, dc);     // Use Clang canonical addresses?
                             * }
                             * if (auto dc = clang::dyn_cast<clang::Stmt>(unconst_ast)){
                             * clang::Stmt* unconst_dc = const_cast<clang::Stmt*>(dc);
                             * setASTState(coord, unconst_dc, c);
                             * overrideStmt2Coords(dc, coord);     // Use Clang canonical addresses?
                             * overrideCoords2Stmt(coord, dc);     // Use Clang canonical addresses?
                             * }
                             * return coord;
                             * }
                             * ";
                             *       file += mkStr;
                             *       break;
                             *   }*/
                        }
                    }
                }
            }

            file += @"
//using namespace std;
void ASTToCoords::overrideStmt2Coords(const clang::Stmt *s, coords::Coords *c) {
    stmt_coords->insert(std::make_pair(s, c));
}



void ASTToCoords::overrideDecl2Coords(const clang::Decl *d, coords::Coords *c) {
    
    decl_coords->insert(std::make_pair(d, c));
}



void ASTToCoords::overrideCoords2Stmt(coords::Coords *c, const clang::Stmt *s) {
    
    coords_stmt->insert(std::make_pair(c, s));
}



void ASTToCoords::overrideCoords2Decl(coords::Coords *c, const clang::Decl *d) {
    
    coords_decl->insert(std::make_pair(c, d));
}
";


            this.CppFile = file;
        }
Пример #2
0
        public override void GenHeader()
        {
            var header = @"
#ifndef ASTTOCOORDS_H
#define ASTTOCOORDS_H

#include ""AST.h""
#include ""clang/AST/AST.h""
#include ""Coords.h""

#include <memory>

#include <iostream>

/*
This relational class maps Clang AST nodes to code coordinates
in our ontology. We want a single base type for all coordinates. 
Clang does not have a single base type for all AST nodes. This is
a special case of the broader reality that we will want to have
code coordinates for diverse types of code elements. So we will
need multiple function types, from various code element types to
our uniform (base class for) code coordinates. Coords subclasses
add specialized state and behavior corresponding to their concrete
code element types.

Note: At present, the only kind of Clang AST nodes that we need
are Stmt nodes. Stmt is a deep base class for Clang AST nodes,
including clang::Expr, clang::DeclRefExpr, clang:MemberCallExpr,
and so forth. So the current class is overbuilt in a sense; but
we design it as we have to show the intended path to generality.

To use this class, apply the mk methods to Clang AST nodes of 
the appropriate types. These methods create Coord objects of the
corresponding types, wrape the AST nodes in the Coords objects,
update the relational map, and return the constructed Coords. 
Client code is responsible for deleting (TBD).

Also note that Vector_Lit doesn't have a sub-expression.
*/

namespace ast2coords {

/*
When generating interpretation, we know subtypes of vector expressions
(literal, variable, function application), and so do not need and should
not use a generic putter. So here there are no superclass mkVecExpr or
Vector mk oprations. 
*/

class ASTToCoords
{
public:

    ASTToCoords();

    void setASTState(coords::Coords* coords, clang::Stmt* stmt, clang::ASTContext* c);
    void setASTState(coords::Coords* coords, clang::Decl* decl, clang::ASTContext* c);

";
            var file   = header;

            foreach (var prod in ParsePeirce.Instance.Grammar.Productions)
            {
                foreach (var pcase in prod.Cases)
                {
                    if (pcase.CaseType == Grammar.CaseType.Passthrough || pcase.CaseType == Grammar.CaseType.Inherits)
                    {
                        continue;
                    }
                    else if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                    {
                        int i     = 0;
                        var mkStr = "\tcoords::" + prod.Name + "* mk" + prod.Name + "(const ast::" + prod.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                                                                                                                                                  string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") + (prod.HasValueContainer() ? "," +
                                                                                                                                                                                                                                                      Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + ");";
                        file += "\n" + mkStr + "\n";
                    }
                    else
                    {
                        switch (pcase.CaseType)
                        {
                        case Grammar.CaseType.Ident:
                        {
                            break;
                        }

                        case Grammar.CaseType.Pure:
                        /*{
                         *  int i = 0;
                         *  var mkStr = "\tcoords::" + pcase.Name + "* mk" + pcase.Name + "(clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                         *      string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") + ");";
                         *  file += "\n" + mkStr + "\n";
                         *  break;
                         *
                         * }*/
                        case Grammar.CaseType.Hidden:
                        case Grammar.CaseType.Op:
                        {
                            int i     = 0;
                            var mkStr = "\tcoords::" + pcase.Name + "* mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.Productions.Count > 0 ? "," +
                                                                                                                                                         string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + "* operand" + ++i)) : "") + (prod.HasValueContainer() ? "," +
                                                                                                                                                                                                                                                             Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + ");";
                            file += "\n" + mkStr + "\n";
                            break;
                        }

                        case Grammar.CaseType.ArrayOp:
                        {
                            //int i = 0;
                            var mkStr = "\tcoords::" + pcase.Name + "* mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c, std::vector<coords::" + pcase.Productions[0].Name + @"*> operands );";
                            file += "\n" + mkStr + "\n";
                            break;
                        }

                            /*case Grammar.CaseType.Value:
                             *  {
                             *      int i = 0;
                             *      var mkStr = "\tcoords::" + pcase.Name + "* mk" + pcase.Name + "(const ast::" + pcase.Name + "* ast, clang::ASTContext* c" + (pcase.ValueCount > 0 ? "," +
                             * Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType + " operand" + v) : "") + ");";
                             *      file += "\n" + mkStr + "\n";
                             *      break;
                             *  }*/
                        }
                    }
                }
            }


            var footer = @"
    // TODO -- Have these routines return more specific subclass objects
    coords::Coords *getStmtCoords(const clang::Stmt *s) {
        return stmt_coords->find(s)->second;
    }

    coords::Coords *getDeclCoords(const clang::Decl *d) {
        return decl_coords->find(d)->second;
    }


	bool existsStmtCoords(const clang::Stmt* s) {
		return stmt_coords->find(s) != stmt_coords->end();
	}

	bool existsDeclCoords(const clang::Decl *d) {
		return decl_coords->find(d) != decl_coords->end();
	}



    /*
    !!!! I NEED THESE BADLY. MOVING TO PUBLIC !!!!
    */
    std::unordered_map<const clang::Stmt *, coords::Coords *> *stmt_coords;
    std::unordered_map<const clang::Decl *, coords::Coords *> *decl_coords;
    std::unordered_map<coords::Coords *,const clang::Stmt *> *coords_stmt;
    std::unordered_map<coords::Coords *,const clang::Decl *> *coords_decl;

 private:
    void overrideStmt2Coords(const clang::Stmt *s, coords::Coords *c);
    void overrideDecl2Coords(const clang::Decl*, coords::Coords *c);
    void overrideCoords2Stmt(coords::Coords *c, const clang::Stmt *s);
    void overrideCoords2Decl(coords::Coords *c, const clang::Decl *d);
    /*
    std::unordered_map<const clang::Stmt *, coords::Coords *> stmt_coords;
    std::unordered_map<const clang::Decl *, coords::Coords *> decl_coords;
    std::unordered_map<coords::Coords *,const clang::Stmt *> coords_stmt;
    std::unordered_map<coords::Coords *,const clang::Decl *> coords_decl;
    */
    
};
";

            footer += @"

} // namespace

#endif


";
            file   += footer;

            this.HeaderFile = file;
        }
Пример #3
0
        public override void GenHeader()
        {
            var header = @"
#ifndef COORDS_H
#define COORDS_H

#include ""clang/AST/AST.h""
#include ""clang/ASTMatchers/ASTMatchFinder.h""
#include <cstddef>
#include <iostream> // for cheap logging only
#include <string>
#include <memory>

#include ""AST.h""


/*
Code coordinate objects wrap AST 
objects to provide inherited behavior
necessary and appropriate for each
referenced code object. They give
AST objects types in our domain's
ontology. 

We maintain a bijection betwen AST and 
Coord objects: specifically between the
memory addresses of these objects. It is
thus critical not to map one AST node
address to more than one Coord object.

Code coordinates provide for ontology 
translation, between the Clang's AST 
types and our domain elements (id, 
var expr, function application expr, 
constructed vector, and definition).
*/

namespace coords
{

    // Ontology of Clang object types that can be 
    // coordinatized. We do not currently use 
    // clang::Decl but we include it here to 
    // establish a path togeneralizability
    //
    //enum ast_type { CLANG_AST_STMT, CLANG_AST_DECL }; 

    struct ASTState
    {
    public:
        ASTState(
        std::string file_id,
        std::string file_name,
        std::string file_path,
        std::string name,
        int begin_line_no,
        int begin_col_no,
        int end_line_no,
        int end_col_no
        );

        std::string file_id_;
        std::string file_name_;
        std::string file_path_;

        std::string name_; //only used for Decl. possibly subclass this, or else this property is unused elsewhere

        int begin_line_no_;
        int begin_col_no_;
        int end_line_no_;
        int end_col_no_;

        bool operator ==(const ASTState& other) const {
return 
    file_id_ == other.file_id_ and
            file_name_ == other.file_name_ and
            file_path_ == other.file_path_ and
            begin_line_no_ == other.begin_line_no_ and
            begin_col_no_ == other.begin_col_no_ and
            end_line_no_ == other.end_line_no_ and
            end_col_no_ == other.end_col_no_;
}
};

class Coords
{
public:
    Coords() {};

    virtual bool operator ==(const Coords &other) const;
    virtual std::string toString() const;
    virtual std::string getSourceLoc() const;
    int getIndex() const { return index_; };
    void setIndex(int index);
    
    virtual bool codegen() const {
        return false;
    }

    ASTState* state_; //maybe  change this to a constructor argument
protected:
    int index_;
};
template <class ValueType, int ValueCount>
class ValueCoords
{
public: 
   // ValueCoords() {};
    ValueCoords() {
        for(int i = 0; i<ValueCount;i++){
            this->values_[i] = nullptr;
        }
    };//, value_len_(len) { this->values_ = new ValueType[value_len_]; };
    //ValueCoords(ValueType* values, int len) : values_(values), value_len_(len) {};
    ValueCoords(std::shared_ptr<ValueType> values...)  {
        
        int i = 0;
        for(auto val : {values}){
            if(i == ValueCount)
                throw ""Out of Range"";
            this->values_[i++] = val ? std::make_shared<ValueType>(*val) : nullptr;
            
        }
    }

    ValueCoords(std::initializer_list<std::shared_ptr<ValueType>> values){
        
        int i = 0;
        for(auto val : values){
            if(i == ValueCount)
                throw ""Out of Range"";
            this->values_[i++] = val ? std::make_shared<ValueType>(*val) : nullptr;
            
        }
    }

    std::shared_ptr<ValueType> getValue(int index) const {
        if(index< 0 or index >= ValueCount)
            throw ""Invalid Index"";
        return this->values_[index];
    };


    void setValue(ValueType value, int index)
    {
        if (index < 0 or index >= ValueCount)
            throw ""Invalid Index"";
        if (this->values_[index])
            *this->values_[index] = value;
        else
            this->values_[index] = std::make_shared<ValueType>(value);
        //this->values_[index] = new ValueType(value)
    };

    void setValue(std::shared_ptr<ValueType> value, int index)
    {
        if (index < 0 or index >= ValueCount)
            throw ""Invalid Index"";
        if (this->values_[index])
            if(value)
                *this->values_[index] = *value;
            else{
                this->values_[index] = std::make_shared<ValueType>(*value);
            }
        else
            this->values_[index] = value ? std::make_shared<ValueType>(*value) : nullptr;
        //this->values_[index] = value ? new ValueType(*value) : nullptr;
    };

    std::shared_ptr<ValueType>* getValues() const {
        return (std::shared_ptr<ValueType>*)this->values_;
    }

protected:
    std::shared_ptr<ValueType> values_[ValueCount];
    //int value_len_;
    //std::Vector<ValueType*> values_;

};


";

            var grammar = ParsePeirce.Instance.Grammar;

            var file = header;

            foreach (var prod in grammar.Productions)
            {
                if (true)
                {
                    file += "\n";
                    file += "class " + prod.Name + ";";
                }

                if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                {
                    continue;
                }

                foreach (var pcase in prod.Cases)
                {
                    if (pcase.CaseType == Grammar.CaseType.Passthrough || pcase.CaseType == Grammar.CaseType.Inherits)
                    {
                        continue;
                    }

                    file += "\n";
                    file += "class " + pcase.Name + ";";
                }
            }


            foreach (var prod in grammar.Productions)
            {
                if (prod.ProductionType != Grammar.ProductionType.Single && prod.ProductionType != Grammar.ProductionType.CaptureSingle)
                {
                    var prodStr =
                        @"

class " + prod.Name + @" : public "
                        + (prod.Passthrough is Grammar.Production ? prod.Passthrough.Name : prod.Inherits is Grammar.Production ? prod.Inherits.Name : "Coords")
                        + (prod.HasValueContainer() && !prod.InheritsContainer() ?
                           ", public ValueCoords<" + prod.GetPriorityValueContainer().ValueType + "," + prod.GetPriorityValueContainer().ValueCount + ">" : "")
                        + @" {
public:
    " + prod.Name + @"(" + (prod.HasValueContainer() ?
                            Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + @") : "
                        + (prod.HasValueContainer() && !prod.InheritsContainer() ? "ValueCoords < " + prod.GetPriorityValueContainer().ValueType + ", " + prod.GetPriorityValueContainer().ValueCount + " >::ValueCoords" :
                           prod.Passthrough is Grammar.Production ? prod.Passthrough.Name : prod.Inherits is Grammar.Production ? prod.Inherits.Name : "Coords") +
                        @"(" + (prod.HasValueContainer() ? "{" +
                                Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "value" + v) + "}" : "") + @") {};
    std::string virtual toString() const override { return ""Do not call this""; };
    bool operator==(const " + prod.Name + @" &other) const {
        return ((Coords*)this)->state_ == ((Coords)other).state_;
    };
    virtual bool codegen() const override {
        return " + (prod.ProductionType != Grammar.ProductionType.Hidden ? "true" : "false") + @";
    }
};

    ";

                    file += prodStr;
                }
                else if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                {
                    var prodStr =
                        @"

class " + prod.Name + @" : public "
                        + (prod.Passthrough is Grammar.Production ? prod.Passthrough.Name : prod.Inherits is Grammar.Production ? prod.Inherits.Name : "Coords")
                        + (prod.HasValueContainer() && !prod.InheritsContainer() ?
                           ", public ValueCoords<" + prod.GetPriorityValueContainer().ValueType + "," + prod.GetPriorityValueContainer().ValueCount + ">" : "")
                        + @" {
public:
    " + prod.Name
                        + @"(" + Peirce.Join(",", Enumerable.Range(0, prod.Cases[0].Productions.Count), v => "coords::" + prod.Cases[0].Productions[v].Name + " * operand" + v)
                        + (prod.HasValueContainer() ?
                           (prod.Cases[0].Productions.Count > 0 ? "," : "") + Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "")
                        + @") : "
                        + (prod.HasValueContainer() ? "ValueCoords < " + prod.GetPriorityValueContainer().ValueType + ", " + prod.GetPriorityValueContainer().ValueCount + " >::ValueCoords" :
                           prod.Passthrough is Grammar.Production ? prod.Passthrough.Name :
                           prod.Inherits is Grammar.Production ? prod.Inherits.Name : "Coords") + @"(" + (prod.HasValueContainer() ? "{" +
                                                                                                          Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "value" + v) + "}" : "") + @")
        " + (prod.Cases[0].Productions.Count > 0 ? "," :"") + Peirce.Join(",", Enumerable.Range(0, prod.Cases[0].Productions.Count), v => " operand_" + v + "(operand" + v + ")") + @"{};
    std::string virtual toString() const override;
    " + Peirce.Join("\n\t", Enumerable.Range(0, prod.Cases[0].Productions.Count), v => "coords::" + prod.Cases[0].Productions[v].Name + " * getOperand" + v + "(){ return this->operand_" + v + @";};") + @"
    bool operator==(const " + prod.Name + @" &other) const {
        return ((Coords*)this)->state_ == ((Coords)other).state_;
    };
    virtual bool codegen() const override {
        return " + (prod.ProductionType != Grammar.ProductionType.Hidden ? "true" : "false") + @";
    }
protected:
    " + Peirce.Join("\n\t", Enumerable.Range(0, prod.Cases[0].Productions.Count), v => "coords::" + prod.Cases[0].Productions[v].Name + " * operand_" + v + ";") + @"
};

    ";

                    file += prodStr;
                    continue;
                }

                foreach (var pcase in prod.Cases)
                {
                    switch (pcase.CaseType)
                    {
                    case Grammar.CaseType.Passthrough:
                        continue;

                    case Grammar.CaseType.Inherits:
                        continue;

                    case Grammar.CaseType.Ident:
                    {
                        break;

                        /*int i = 0, j = 0, k = 0;
                         * var caseStr =
                         * @"
                         *
                         * class " + prod.Name + "_"+ pcase.Name + @" : public Coords {
                         * public:
                         * " + prod.Name + @"(" + string.Join(", ", pcase.Productions.Select(p_ => "coords::" + p_.Name + " * operand_" + ++k)) + @");
                         * virtual std::string toString() const;
                         * bool operator==(const " + prod.Name + @" &other) const {
                         * return this->state_ == other.state_;
                         * };" + "\n\t" +
                         * string.Join("\n\t", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *getOperand" + ++i + "(); ").ToList())
                         +
                         + "\nprotected:\n\t" +
                         + string.Join("\n\t", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *operand" + ++j + ";"))
                         +
                         + @"
                         + };
                         +
                         + ";
                         + break;*/
                    }

                    case Grammar.CaseType.Op:
                    case Grammar.CaseType.Hidden:
                    case Grammar.CaseType.Pure:
                    {
                        int i = 0, j = 0, k = 0;
                        var caseStr =
                            @"

class " + pcase.Name + @" : public " + prod.Name + @" {
public:
    " + pcase.Name + @"(" + string.Join(", ", pcase.Productions.Select(p_ => "coords::" + p_.Name + " * operand_" + ++k)) +
                            (prod.HasValueContainer() ? (pcase.Productions.Count > 0 ? "," : "") +
                             Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") +
                            @");
    virtual std::string toString() const override;
    bool operator==(const " + prod.Name + @" &other) const {
        return ((Coords*)this)->state_ == ((Coords)other).state_;
    };" + "\n\t" +
                            string.Join("\n\t", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *getOperand" + ++i + "(); ").ToList())
                            +
                            "\nprotected:\n\t" +
                            string.Join("\n\t", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *operand" + ++j + ";"))
                            +
                            @"
};

";
                        file += caseStr;
                        break;
                    }

                    case Grammar.CaseType.ArrayOp:
                    {
                        //int i = 0, j = 0;//, k = 0;
                        var caseStr =
                            @"

class " + pcase.Name + @" : public " + prod.Name + @" {
public:
    " + pcase.Name + @"(std::vector<" + pcase.Productions[0].Name + @"*> operands);
    virtual std::string toString() const override;
    bool operator==(const " + prod.Name + @" &other) const {
        return ((Coords*)this)->state_ == ((Coords)other).state_;
    };

    std::vector<" + pcase.Productions[0].Name + @"*> getOperands() const { return this->operands_; };

    coords::" + pcase.Productions[0].Name + @"* getOperand(int i) const {
        return ((int)this->operands_.size()) >= i ? this->operands_[i-1] : nullptr;
    }" +

                            "\nprotected:\n\t" + @"
    std::vector<" + pcase.Productions[0].Name + @"*> operands_;

};

";
                        file += caseStr;
                        break;
                    }

                        /* case Grammar.CaseType.Value:
                         * {
                         *   int i = 0, j = 0, k = 0;
                         *   var caseStr =
                         * @"
                         *
                         * class " + pcase.Name + @" : public " + prod.Name +  @" {
                         * public:
                         * " + pcase.Name + @"(" + (pcase.ValueCount > 0 ?
                         * Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType + " value" + v ) : "") + @");
                         * virtual std::string toString() const;
                         * bool operator==(const " + prod.Name + @" &other) const {
                         * return this->state_ == other.state_;
                         * }" + "\n" +
                         *
                         * (pcase.ValueCount > 0 ?
                         * Peirce.Join("\n", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType + " getOperand" + v + "() const { return this->value_" + v + "; }") : "")
                         +
                         + @"
                         + protected:" + "\n\t" +
                         + (pcase.ValueCount > 0 ?
                         + Peirce.Join("\n\t", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType + " value_" + v+";") : "")
                         +
                         + @"
                         + };
                         +
                         + ";
                         +       file += caseStr;
                         +   break;
                         + }*/
                    }
                }
            }
            file           += @"
} // namespace coords

#endif";
            this.HeaderFile = file;
        }
Пример #4
0
        public override void GenCpp()
        {
            var header = @"
#include ""Coords.h""

#include <g3log/g3log.hpp>
#include <memory>


namespace coords {

/*
Code coordinates provide for ontology translation, between the 
concrete types used to represent pertinent code elements in a 
given programming language and system (code language), and the 
abstract terms of a domain language. Here the code language is
Clang as used to map applications built on our simple vector
class (Vec). The domain language is one of simple vector space
expressions and objects. 
*/

// Ontology of code object types that can be coordinatized
// clang::Decl unused by Peirce, here for generalizability
//


ASTState::ASTState(
    std::string file_id,
    std::string file_name,
    std::string file_path,
    std::string name,
    int begin_line_no,
    int begin_col_no,
    int end_line_no,
    int end_col_no) 
    : file_id_{file_id}, file_name_{file_name}, file_path_{file_path}, name_{name}, begin_line_no_{begin_line_no}, begin_col_no_{begin_col_no}, end_line_no_{end_line_no}, end_col_no_{end_col_no} {}

//Coords::Coords(){
//}

void Coords::setIndex(int index){
    this->index_ = index;
}

bool Coords::operator==(const Coords &other) const {
    return this->state_ == other.state_;
}

std::string Coords::toString() const {
    LOG(FATAL) << ""Coords::toString. Error. Should not be called. Abstract.\n"";
    return NULL;
}

std::string Coords::getSourceLoc() const {
    /*clang::FullSourceLoc FullLocation;
    if (ast_type_tag_ == CLANG_AST_STMT)
    {
      FullLocation = context_->getFullLoc(clang_stmt_->getSourceRange().getEnd());
    } else {
      FullLocation = context_->getFullLoc(clang_decl_->getLocation());
    }*/
    //std::cout<<this->toString()<<std::endl;
    std::string retval = ""Begin: line "";
    retval += std::to_string(this->state_->begin_line_no_);
    retval +=  "", column "";
    retval +=  std::to_string(this->state_->begin_col_no_);
    retval += "" End: line "";
    retval += std::to_string(this->state_->end_line_no_);
    retval += "", column "";
    retval += std::to_string(this->state_->end_col_no_);

    return retval;
}

/*************************************************************
* Coordinate subclasses, for type checking, override behaviors
*************************************************************/

";
            var file   = header;


            foreach (var prod in ParsePeirce.Instance.Grammar.Productions)
            {
                // var prodcons = "\n" + prod.Name + "::" + prod.Name + "() : " + (prod.Passthrough is Grammar.Production ? prod.Passthrough.Name : "Coords") + "(){}\n";

                //file += prodcons;
                if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                {
                    file += "\nstd::string " + prod.Name + "::toString() const{ return " + prod.Cases[0].CoordsToString(prod) + @";}";
                    continue;
                }


                foreach (var pcase in prod.Cases)
                {
                    if (pcase.CaseType == Grammar.CaseType.Passthrough || pcase.CaseType == Grammar.CaseType.Inherits)
                    {
                        continue;
                    }
                    switch (pcase.CaseType)
                    {
                    case Grammar.CaseType.Passthrough:
                        continue;

                    case Grammar.CaseType.Inherits:
                        continue;

                    case Grammar.CaseType.Ident:
                        break;

                    case Grammar.CaseType.Op:
                    case Grammar.CaseType.Hidden:
                    case Grammar.CaseType.Pure:
                    {
                        int i = 0, j = 0;        //, k = 0;
                        var cons = "\n" + pcase.Name + "::" + pcase.Name + "("
                                   + string.Join(",", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *operand_" + ++j)) +
                                   (prod.HasValueContainer() ? (pcase.Productions.Count > 0 ? "," : "") +
                                    Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => "std::shared_ptr<" + prod.GetPriorityValueContainer().ValueType + "> value" + v) : "") + ") : ";

                        cons += "\n\t\t" + prod.Name + "(" +
                                (prod.HasValueContainer() ?
                                 Peirce.Join(",", Enumerable.Range(0, prod.GetPriorityValueContainer().ValueCount), v => " value" + v) : "") + ")" + (pcase.Productions.Count > 0 ? "," + string.Join(",", pcase.Productions.Select(p_ => "operand" + ++i + "(operand_" + i + ")")) : "") + "{}";

                        file += cons;
                        i     = 0; j = 0;
                        foreach (var casep in pcase.Productions)
                        {
                            var opgetter = "\n" + "coords::" + casep.Name + "* " + pcase.Name + "::getOperand" + ++i + "() { return this->operand" + i + ";}";
                            file += opgetter;
                        }
                        file += "\nstd::string " + pcase.Name + "::toString() const{ return " + (prod.ProductionType == Grammar.ProductionType.Hidden ? "\"\"" : pcase.CoordsToString(prod)) + @";}";
                        file += "\n\n";
                        break;
                    }
                    //case Grammar.CaseType.Ident:
                    //{

                    //}
                    case Grammar.CaseType.ArrayOp:
                    {
                        /*
                         * var caseStr =
                         *  @"
                         *
                         * class " + pcase.Name + @" : public " + prod.Name + @" {
                         * public:
                         *  " + pcase.Name + @"(std::vector<"+pcase.Productions[0].Name + @"*> operands);
                         *  virtual std::string toString() const;
                         *  bool operator==(const " + prod.Name + @" &other) const {
                         *      return this->state_ == other.state_;
                         *  };" + "\n\t" +
                         *      string.Join("\n\t", pcase.Productions.Select(p_ => "coords::" + p_.Name + " *getOperand" + ++i + "(); ").ToList())
                         +
                         +  "\nprotected:\n\t" + @"
                         +  std::vector<" + pcase.Name + @"*> operands_;
                         +
                         + };
                         +
                         + ";
                         */


                        //int i = 0, j = 0;//, k = 0;
                        var cons = "\n" + pcase.Name + "::" + pcase.Name + "(std::vector<" + pcase.Productions[0].Name + @"*> operands) :" + prod.Name + "()" + @" {
    for(auto& op : operands){
        this->operands_.push_back(op);
    }

};";

                        file += cons;
                        //i = 0; j = 0;
                        //foreach (var casep in pcase.Productions)
                        //{
                        //   var opgetter = "\n" + "coords::" + casep.Name + "* " + pcase.Name + "::getOperand" + ++i + "() { return this->operand" + i + ";}";
                        //  file += opgetter;
                        //}
                        file += "\nstd::string " + pcase.Name + "::toString() const{ return " + pcase.CoordsToString(prod) + @";}";
                        file += "\n\n";
                        break;
                    }

                        /*case Grammar.CaseType.Value:
                         *  {
                         *
                         *      int i = 0, j = 0, k = 0;
                         *      var cons = "\n" + pcase.Name + "::" + pcase.Name + "(" + Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => pcase.ValueType+ " operand" + v) + ") : ";
                         *
                         *      //if (pcase.CaseType == Grammar.CaseType.Real)
                         *      //   cons = @"(" + string.Join(", ", pcase.ProductionRefs.Select(p_ => "double value_" + ++k)) + @");";
                         *
                         *      cons += "\n\t\t" + prod.Name + "()" + (pcase.ValueCount > 0 ? "," +
                         * Peirce.Join(",", Enumerable.Range(0, pcase.ValueCount), v => "value_" + v + "(operand" + v + ")") : "") + "{}";
                         *
                         *      file += cons;
                         *      i = 0; j = 0;
                         *      foreach (var casep in pcase.Productions)
                         *      {
                         *          var opgetter = "\n" + "coords::" + casep.Name + "* " + pcase.Name + "::getOperand" + ++i + "() { return this->operand" + i + ";}";
                         *          file += opgetter;
                         *      }
                         *      file += "\nstd::string " + pcase.Name + "::toString() const{ return " + pcase.CoordsToString(prod) + @";}";
                         *      file += "\n\n";
                         *      break;
                         *  }*/
                    }
                }
            }

            file += "\n} // namespace codecoords";

            this.CppFile = file;
        }
Пример #5
0
        public override void GenHeader()
        {
            var header = @"#ifndef INTERPTODOMAIN_H
#define INTERPTODOMAIN_H

#include <iostream>
#include ""Domain.h""

namespace interp
{
    class Space;
    class MeasurementSystem;
    class AxisOrientation;
    class Frame;
    "
                         +
                         Peirce.Join("\n", ParsePeirce.Instance.Grammar.Productions, p => "class " + p.Name + ";")
                         +
                         Peirce.Join("\n", ParsePeirce.Instance.Grammar.Productions.SelectMany(p_ => p_.Cases), p => "class " + p.Name + ";")
                         +
                         @"
} // namespace

#ifndef INTERP_H
#include ""Interp.h""
#endif

#include <unordered_map>

namespace interp2domain{

class InterpToDomain
{
    public:";


            var file = header;

            var putspace    = @"void putSpace(interp::Space* key, domain::Space* val);";
            var getdomspace = @"domain::Space* getSpace(interp::Space* c) const;";
            var getintspace = @"interp::Space* getSpace(domain::Space* d) const;";

            var putms  = @"void putMeasurementSystem(interp::MeasurementSystem* key, domain::MeasurementSystem* val);";
            var getms  = @"domain::MeasurementSystem* getMeasurementSystem(interp::MeasurementSystem* c) const;";
            var getms2 = @"interp::MeasurementSystem* getMeasurementSystem(domain::MeasurementSystem* d) const;";

            var putax  = @"void putAxisOrientation(interp::AxisOrientation* key, domain::AxisOrientation* val);";
            var getax  = @"domain::AxisOrientation* getAxisOrientation(interp::AxisOrientation* c) const;";
            var getax2 = @"interp::AxisOrientation* getAxisOrientation(domain::AxisOrientation* d) const;";

            file += "\n\t" + putspace + "\n\t" + getdomspace + "\n\t" + getintspace + "\n";
            file += "\n\t" + putms + "\n\t" + getms + "\n\t" + getms2 + "\n";
            file += "\n\t" + putax + "\n\t" + getax + "\n\t" + getax2 + "\n";
            var putFrame    = @"void putFrame(interp::Frame* key, domain::Frame* val);";
            var getdomFrame = @"domain::Frame* getFrame(interp::Frame* c) const;";
            var getintFrame = @"interp::Frame* getFrame(domain::Frame* d) const;";

            file += "\n\t" + putFrame + "\n\t" + getdomFrame + "\n\t" + getintFrame + "\n";

            foreach (var prod in ParsePeirce.Instance.Grammar.Productions)
            {
                if (prod.ProductionType != Grammar.ProductionType.Single && prod.ProductionType != Grammar.ProductionType.CaptureSingle)
                {
                    var getdomprod = @"domain::DomainObject* get" + prod.Name + "(interp::" + prod.Name + "* c) const;";
                    var getintprod = @"interp::" + prod.Name + "* get" + prod.Name + "(domain::DomainObject* d) const;";

                    file += "\n\t" + getdomprod + "\n\t" + getintprod + "\n\t";
                }
                else
                {
                    var put    = @"void put" + prod.Name + "(interp::" + prod.Name + "* key, domain::DomainObject* val);";
                    var erase  = @"void erase" + prod.Name + "(interp::" + prod.Name + "* key, domain::DomainObject* val);";
                    var getdom = @"domain::DomainObject* get" + prod.Name + "(interp::" + prod.Name + "* c) const;";
                    var getint = @"interp::" + prod.Name + "* get" + prod.Name + "(domain::DomainObject* d) const;";

                    file += "\n\t" + put + "\n\t" + getdom + "\n\t" + getint + "\n" + erase + "\n";

                    continue;
                }

                foreach (var pcase in prod.Cases)
                {
                    if (pcase.CaseType == Grammar.CaseType.Passthrough || pcase.CaseType == Grammar.CaseType.Inherits)
                    {
                        continue;
                    }
                    else if (pcase.CaseType == Grammar.CaseType.Ident)
                    {
                        break;/*
                               * var put = @"void put" + prod.Name + "(interp::" + prod.Name + "* key, domain::DomainObject* val);";
                               * var erase = @"void erase" + prod.Name + "(interp::" + prod.Name + "* key, domain::DomainObject* val);";
                               * var getdom = @"domain::DomainObject* get" + prod.Name + "(interp::" + prod.Name + "* c) const;";
                               * var getint = @"interp::" + prod.Name + "* get" + prod.Name + "(domain::DomainObject* d) const;";
                               *
                               * file += "\n\t" + put + "\n\t" + getdom + "\n\t" + getint + "\n" + erase + "\n";*/
                    }
                    else
                    {
                        var put    = @"void put" + pcase.Name + "(interp::" + pcase.Name + "* key, domain::DomainObject* val);";
                        var erase  = @"void erase" + pcase.Name + "(interp::" + pcase.Name + "* key, domain::DomainObject* val);";
                        var getdom = @"domain::DomainObject* get" + pcase.Name + "(interp::" + pcase.Name + "* c) const;";
                        var getint = @"interp::" + pcase.Name + "* get" + pcase.Name + "(domain::DomainObject* d) const;";

                        file += "\n\t" + put + "\n\t" + getdom + "\n\t" + getint + "\n" + erase + "\n";
                    }
                }
            }

            file += "\nprivate:\n";

            file += "\nstd::unordered_map<interp::Space*, domain::Space*> interp2dom_Spaces;\n";
            file += "\nstd::unordered_map<domain::Space*, interp::Space*> dom2interp_Spaces;\n";
            file += "\nstd::unordered_map<interp::MeasurementSystem*, domain::MeasurementSystem*> interp2dom_MeasurementSystems;\n";
            file += "\nstd::unordered_map<domain::MeasurementSystem*, interp::MeasurementSystem*> dom2interp_MeasurementSystems;\n";
            file += "\nstd::unordered_map<interp::AxisOrientation*, domain::AxisOrientation*> interp2dom_AxisOrientations;\n";
            file += "\nstd::unordered_map<domain::AxisOrientation*, interp::AxisOrientation*> dom2interp_AxisOrientations;\n";
            file += "\nstd::unordered_map<interp::Frame*, domain::Frame*> interp2dom_Frames;\n";
            file += "\nstd::unordered_map<domain::Frame*, interp::Frame*> dom2interp_Frames;\n";

            foreach (var prod in ParsePeirce.Instance.Grammar.Productions)
            {
                //foreach (var pcase in prod.Cases)
                // {
                var mapi2d = @"std::unordered_map <interp::" + prod.Name + "*,	domain::DomainObject*	> 	interp2dom_"+ prod.Name + ";";
                var mapd2i = @"std::unordered_map <domain::DomainObject*,	interp::"+ prod.Name + "*	> 	dom2interp_"+ prod.Name + ";";

                file += "\n\t" + mapi2d + "\n\t" + mapd2i + "\n";
                //}
            }

            file           += @"};

} // namespace

#endif";
            this.HeaderFile = file;
        }
Пример #6
0
        public void GenCpp()
        {
            var file = @"
#include ""clang/ASTMatchers/ASTMatchFinder.h""
#include ""clang/ASTMatchers/ASTMatchers.h""
"
                       +
                       this.Production.GetIncludes()
                       +
                       @"


#include <string>
#include <unordered_map>
#include <functional>


void " + this.Production.ClassName + @"::setup(){"/* +
                                                   * Peirce.Join("\n",
                                                   * this.Production.Cases,
                                                   * pcase => "\n\t\tStatementMatcher " +
                                                   * pcase.LocalName + "=" + pcase.BuildMatcher(this.Production)
                                                   + ";\n\t\tlocalFinder_.addMatcher(" + pcase.LocalName + ",this);")
                                                   +
                                                   */
                       +
                       Peirce.Join("", new List <MatcherProduction>()
            {
                this.Production
            }.Select(cowboycode =>
            {
                var distinctcases = this.Production.Cases.GroupBy(pcase => pcase.ClangName).Select(grp => grp.First()).ToList();



                // Peirce.Join("\n\t", distinctcases, pcase => "\n\tauto " + pcase.LocalName + " = Result.Nodes.getNodeAs<clang::" + pcase.ClangName + ">(\"" + pcase.ClangName + "\");");


                return(Peirce.Join("\n\t", distinctcases, pcase => "\n\t\tStatementMatcher " +
                                   pcase.LocalName + "=" + pcase.BuildMatcher(this.Production)
                                   + ";\n\t\tlocalFinder_.addMatcher(" + pcase.LocalName + ",this);"));
            }).ToList(), p => p)
                       +
                       @"
};

void " + this.Production.ClassName + @"::run(const MatchFinder::MatchResult &Result){" +
                       Peirce.Join("", new List <MatcherProduction>()
            {
                this.Production
            }.Select(cowboycode =>
            {
                var distinctcases = this.Production.Cases.GroupBy(pcase => pcase.ClangName).Select(grp => grp.First()).ToList();



                // Peirce.Join("\n\t", distinctcases, pcase => "\n\tauto " + pcase.LocalName + " = Result.Nodes.getNodeAs<clang::" + pcase.ClangName + ">(\"" + pcase.ClangName + "\");");


                return(Peirce.Join("\n\t", distinctcases, pcase => "\n\tauto " + pcase.LocalName + " = Result.Nodes.getNodeAs<clang::" + pcase.ClangName + ">(\"" + pcase.ClangName + "\");"));
            }).ToList(), p => p)
                       +
                       @"
    std::unordered_map<std::string,std::function<bool(std::string)>> arg_decay_exist_predicates;
    std::unordered_map<std::string,std::function<std::string(std::string)>> arg_decay_match_predicates;
    this->childExprStore_ = nullptr;
"
                       +
                       Peirce.Join("", new List <MatcherProduction>()
            {
                this.Production
            }.Select(cowboycode =>
            {
                var distinctcases = this.Production.Cases.GroupBy(pcase => pcase.ClangName).Select(grp => grp.First()).ToList();



                Peirce.Join("\n\t", distinctcases, pcase => pcase.BuildCallbackHandler(this.Production));


                return(Peirce.Join("\n\t", this.Production.Cases, pcase => pcase.BuildCallbackHandler(this.Production)));
            }).ToList(), p => p)
                       + ""
                       + @"


};

";

            this.CppFile = file;
        }
Пример #7
0
        public static void GenStatementCpp()
        {
            GenMatcher.StatementCppFile = @"
#include ""clang/ASTMatchers/ASTMatchFinder.h""
#include ""clang/ASTMatchers/ASTMatchers.h""
#include <vector>

#include ""../Interpretation.h""

#include ""ROSStatementMatcher.h""
"
                                          +
                                          Peirce.Join("\n", ParsePeirce.Instance.MatcherProductions, p_ => "#include \"" + p_.ClassName + ".h\"")
                                          +
                                          @"

#include <string>


#include <iostream>

#include <memory>

#include ""../ASTToCoords.h""
/*
This manages all statements in Clang.
*/


void ROSStatementMatcher::setup(){

    StatementMatcher exprWithCleanups_ =
        exprWithCleanups(has(expr().bind(""UsefulExpr""))).bind(""ExprWithCleanupsDiscard"");//fluff node to discard

    StatementMatcher
        decl_ = declStmt().bind(""DeclStmt"");
    StatementMatcher
        assign_ = anyOf(
            cxxOperatorCallExpr(
                hasOverloadedOperatorName(""="")).bind(""Assign""),
            binaryOperator(
                hasOperatorName(""="")).bind(""Assign"")
        );

    StatementMatcher
        ifStmt_ = ifStmt().bind(""IfStmt"");

    StatementMatcher
        cmpdStmt_ = compoundStmt().bind(""CompoundStmt"");

    StatementMatcher
        expr_ = expr().bind(""ExprStmt"");

    StatementMatcher
        returnStmt_ = returnStmt().bind(""ReturnStmt"");

    StatementMatcher 
        whileStmt_ = whileStmt().bind(""WhileStmt"");

    localFinder_.addMatcher(decl_, this);
    localFinder_.addMatcher(assign_, this);
    localFinder_.addMatcher(expr_, this);
    localFinder_.addMatcher(ifStmt_,this);
    localFinder_.addMatcher(cmpdStmt_, this);
    localFinder_.addMatcher(returnStmt_, this);
    localFinder_.addMatcher(whileStmt_, this);
};

void ROSStatementMatcher::run(const MatchFinder::MatchResult &Result){

    this->childExprStore_ = nullptr;

    const auto declStmt = Result.Nodes.getNodeAs<clang::DeclStmt>(""DeclStmt"");

    const auto assignStmt = Result.Nodes.getNodeAs<clang::Expr>(""Assign"");

    const auto exprStmt = Result.Nodes.getNodeAs<clang::Expr>(""ExprStmt"");

    const auto exprWithCleanupsDiscard = Result.Nodes.getNodeAs<clang::ExprWithCleanups>(""ExprWithCleanupsDiscard"");

    //const auto ifStmt_ = Result.Nodes.getNodeAs<clang::IfStmt>(""IfStmt"");

    const auto cmpdStmt_ = Result.Nodes.getNodeAs<clang::CompoundStmt>(""CompoundStmt"");

    //const auto returnStmt_ = Result.Nodes.getNodeAs<clang::ReturnStmt>(""ReturnStmt"");

    //const auto whileStmt_ = Result.Nodes.getNodeAs<clang::WhileStmt>(""WhileStmt"");

    /*
        if(declStmt)
            declStmt->dump();
        else if(assignStmt)
            assignStmt->dump();
        else if(exprStmt)
            exprStmt->dump();
        */
    /*
    if(whileStmt_){
        auto wcond = whileStmt_->getCond();
        auto wbody = whileStmt_->getBody();
        
        ROSBooleanMatcher condm{ this->context_, this->interp_};
        condm.setup();
        condm.visit(*wcond);

        if(!condm.getChildExprStore()){
            std::cout<<""Unable to parse If condition!!\n"";
            wcond->dump();
            throw ""Broken Parse"";
        }

        ROSStatementMatcher bodym{ this->context_, this->interp_};
        bodym.setup();
        bodym.visit(*wbody);

        if(!bodym.getChildExprStore()){
            std::cout<<""Unable to parse If block!!\n"";
            wbody->dump();
            throw ""Broken Parse"";
        }

        this->interp_->mkWHILE_BOOL_EXPR_STMT(whileStmt_, condm.getChildExprStore(), bodym.getChildExprStore());
        this->childExprStore_ = (clang::Stmt*)whileStmt_;
        return;

    }*/

    /*
    if(returnStmt_){
        auto _expr = returnStmt_->getRetValue();
        auto typestr = ((clang::QualType)_expr->getType()).getAsString();
        if(false){}
        "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)

                return(@"
        else if (typestr.find(""" + p_.TypeName + @""") != string::npos){
            " + p_.ClassName + @" m{ this->context_, this->interp_};
            m.setup();
            m.visit(*_expr);
            if(m.getChildExprStore()){
                this->childExprStore_ = (clang::Stmt*)_expr;
            }
            return;
        }
            ");
            })
                                          + @"
    }*/

    if(cmpdStmt_){
        std::vector<const clang::Stmt*> stmts;

        for(auto st : cmpdStmt_->body()){
            ROSStatementMatcher stmti{this->context_,this->interp_};
            stmti.setup();
            stmti.visit(*st);
            if(stmti.getChildExprStore()){
                stmts.push_back(stmti.getChildExprStore());
            }
        }
        this->interp_->mkCOMPOUND_STMT(cmpdStmt_, stmts);
        this->childExprStore_ = (clang::Stmt*)cmpdStmt_;
        return;
        
    }

    " + Peirce.Join("", new string[] { "hi" }, (prod) =>
            {
                //var callexpr = prod.GrammarType.Cases.Single(pcase => pcase.Name.Contains("CALL"));

                /*
                 *
                 * bool     hasInitStorage () const
                 *  True if this IfStmt has the storage for an init statement. More...
                 *
                 * bool     hasVarStorage () const
                 *  True if this IfStmt has storage for a variable declaration. More...
                 *
                 * bool     hasElseStorage () const
                 *  True if this IfStmt has storage for an else statement. More...
                 *
                 * Expr *   getCond ()
                 *
                 * const Expr *     getCond () const
                 *
                 * void     setCond (Expr *Cond)
                 *
                 * Stmt *   getThen ()
                 *
                 * const Stmt *     getThen () const
                 *
                 * void     setThen (Stmt *Then)
                 *
                 * Stmt *   getElse ()
                 *
                 * const Stmt *     getElse () const
                 *
                 * */
                var ifProd = ParsePeirce.Instance.Grammar.Productions.SingleOrDefault(p_ => p_.Name.StartsWith("IF"));

                if (ifProd == null)
                {
                    return("");
                }

                /*
                 * _IFCOND :=
                 * IFTHEN +BOOL_EXPR +STMT | ~An If-Then Statement
                 * IFTHENELSEIF +BOOL_EXPR +STMT +IFCOND | ~An If-Then-Else-If Statement
                 * IFTHENELSE +BOOL_EXPR +STMT +STMT ~An If-Then-Else Statement
                 *
                 * */
                var ifthen       = ifProd.Cases.Single(c => c.Productions.Count == 2);
                var ifthenelseif = ifProd.Cases.Single(c => c.Productions.Count > 2 && c.Productions[2].Name.StartsWith("IF"));
                var ifthenelse   = ifProd.Cases.Single(c => c.Productions.Count > 2 && c.Productions[2].Name.StartsWith("STMT"));

                return(@"
    if(ifStmt_){
        auto cond = ifStmt_->getCond();
        auto thens = ifStmt_->getThen();

        ROSBooleanMatcher condm{ this->context_, this->interp_};
        condm.setup();
        condm.visit(*cond);

        if(!condm.getChildExprStore()){
            std::cout<<""Unable to parse If condition!!\n"";
            cond->dump();
            throw ""Broken Parse"";
        }

        ROSStatementMatcher thenm{ this->context_, this->interp_};
        thenm.setup();
        thenm.visit(*thens);

        if(!thenm.getChildExprStore()){
            std::cout<<""Unable to parse If block!!\n"";
            thens->dump();
            throw ""Broken Parse"";
        }

        if(ifStmt_->getElse()){
            auto elses = ifStmt_->getElse();

            ROSStatementMatcher elsem{ this->context_, this->interp_};
            elsem.setup();
            elsem.visit(*elses);
            if(!elsem.getChildExprStore()){
                std::cout<<""Unable to parse Then block!!\n"";
                elses->dump();
                throw ""Broken Parse"";
            }
            if(auto dc = clang::dyn_cast<clang::IfStmt>(ifStmt_->getElse())){
                interp_->mk" + ifthenelseif.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore(), elsem.getChildExprStore());
                this->childExprStore_ = (clang::Stmt*)ifStmt_;
                return;
            }
            else{
                interp_->mk" + ifthenelse.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore(), elsem.getChildExprStore());
                this->childExprStore_ = (clang::Stmt*)ifStmt_;
                return;
            }
        }
        else{
            interp_->mk" + ifthen.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore());
            this->childExprStore_ = (clang::Stmt*)ifStmt_;
            return;

        }
    }
");
            }) + @"
    if (declStmt)
    {
        if (declStmt->isSingleDecl())
        {
            if (auto vd = clang::dyn_cast<clang::VarDecl>(declStmt->getSingleDecl()))
             {
                auto typestr = ((clang::QualType)vd->getType()).getAsString();
                if(false){}
"
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)

                return(@"
                else if (typestr.find(""" + p_.TypeName + @""") != string::npos){
                    interp_->mk" + p_.SearchForIdent().Production.Name + @"(vd);
                    if (vd->hasInit())
                    {
                        " + p_.ClassName + @" m{ this->context_, this->interp_};
                        m.setup();
                        m.visit((*vd->getInit()));
                        if (m.getChildExprStore())
                        {
                            interp_->mk" + p_.SearchForDecl(true).Name + @"(declStmt, vd, m.getChildExprStore());
                            this->childExprStore_ =  (clang::Stmt*)declStmt;
                            return;
                        }
                        else
                        {
                            interp_->mk" + p_.SearchForDecl(false).Name + @"(declStmt, vd);
                            this->childExprStore_ =  (clang::Stmt*)declStmt;
                            return;
                        }
                    }
                    else
                    {
                        interp_->mk" + p_.SearchForDecl(false).Name + @"(declStmt, vd);
                        this->childExprStore_ = (clang::Stmt*)declStmt;
                        return;
                    }
                }
            ");
            })
                                          + @"
            }
        }
        else
        {
            bool anyfound = false;
            for (auto it = declStmt->decl_begin(); it != declStmt->decl_end(); it++)
            {
                if (auto vd = clang::dyn_cast<clang::VarDecl>(declStmt->getSingleDecl()))
                {
                    auto typestr = ((clang::QualType)vd->getType()).getAsString();
                    if(false){}
                "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                return(@"
                    else if(typestr.find(""" + p_.TypeName + @""") != string::npos){
                        interp_->mk" + p_.SearchForIdent().Production.Name + @"(vd);
                        if (vd->hasInit())
                        {
                            " + p_.ClassName + @" m{ this->context_, this->interp_};
                            m.setup();
                            m.visit((*vd->getInit()));
                            if (m.getChildExprStore())
                            {
                                interp_->mk" + p_.SearchForDecl(true).Name + @"(declStmt, vd, m.getChildExprStore());
                            }
                            else
                            {
                                interp_->mk" + p_.SearchForDecl(false).Name + @"(declStmt, vd);
                            }
                        }
                        else
                        {
                            interp_->mk" + p_.SearchForDecl(false).Name + @"(declStmt, vd);
                        }
                        anyfound = true;
                    }");
            })
                                          + @"
                }
            }
            if (anyfound)
            {
                this->childExprStore_ = const_cast<clang::DeclStmt*>(declStmt);
                return;
            }
        }
    }
    else if (assignStmt)
    {
        //not implemented!!
    }
    else if (exprStmt)
    {
        auto typestr = ((clang::QualType)exprStmt->getType()).getAsString();
        "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                return(@"
        if(typestr.find(""" + p_.TypeName + @""") != string::npos){
            " + p_.ClassName + @" m{ this->context_, this->interp_};
            m.setup();
            m.visit(*exprStmt);
            if (m.getChildExprStore())
                this->childExprStore_ = const_cast<clang::Stmt*>(m.getChildExprStore());
                return;
                
        }");
            }) + @"
    }


    else if (exprWithCleanupsDiscard)
    {//matches fluff node to discard
        ROSStatementMatcher innerMatcher{ this->context_, this->interp_};
        innerMatcher.setup();
        innerMatcher.visit(*exprWithCleanupsDiscard->getSubExpr());
        if (innerMatcher.getChildExprStore())
            this->childExprStore_ = const_cast<clang::Stmt*>(innerMatcher.getChildExprStore());
            return;
    }
    else
    {
        //log error
    }

};

";
        }
Пример #8
0
        public static void GenFunctionCpp()
        {
            GenMatcher.FunctionCppFile = @"

#include ""clang/ASTMatchers/ASTMatchFinder.h""
#include ""clang/ASTMatchers/ASTMatchers.h""
#include ""clang/AST/Decl.h""
#include <vector>
#include <iostream>

#include ""ROS1ProgramMatcher.h""
#include ""ROSStatementMatcher.h""

//#include ""../ASTToCoords.h""

int TUDCount;

using namespace clang::ast_matchers;

void ROS1ProgramMatcher::setup()
    {
        //valid without pointers!
        /*  DeclarationMatcher root =//isMain() <-- certain __important__ matchers like this are missing. find them.
              functionDecl(has(compoundStmt().bind(""MainCompoundStatement"")
              )).bind(""MainCandidate"");
      */
        DeclarationMatcher roott =
            translationUnitDecl().bind(""MainProg"");

        //localFinder_.addMatcher(root, this);
        localFinder_.addMatcher(roott, this);
    };

    /*
    This is a callback method that gets called when Clang matches on a pattern set up in the search method above.
    */
    void ROS1ProgramMatcher::run(const MatchFinder::MatchResult &Result)
    {
        //auto mainCompoundStatement = Result.Nodes.getNodeAs<clang::CompoundStmt>(""MainCompoundStatement"");
        //auto mainCandidate = Result.Nodes.getNodeAs<clang::FunctionDecl>(""MainCandidate"");

        auto tud = Result.Nodes.getNodeAs<clang::TranslationUnitDecl>(""MainProg"");

        auto srcs = this->interp_->getSources();
        /*
            std::cout<<""Sources:\n"";
            for(auto src:srcs)
            {
                std::cout<<src<<""\n"";
            }*/

        if (tud)
        {
            std::cout << ""TranslationUnitDeclCounter:"" << std::to_string(TUDCount++) << ""\n"";
            if (TUDCount > 1)
            {
                std::cout << ""WARNING : UPDATE  LOGIC TO HANDLE MULTIPLE TRANSLATION UNITS."";
                throw ""Bad Code!"";
            }
        }
        std::vector <const clang::FunctionDecl*> globals;
        if (tud)
        {
            //auto tud = clang::TranslationUnitDecl::castFromDeclContext(mainCandidate->getParent());
            auto & srcm = this->context_->getSourceManager();
            for (auto d : tud->decls())
            {

                if (auto fn = clang::dyn_cast<clang::FunctionDecl>(d))
            {
                auto loc = fn->getLocation();

                auto srcloc = srcm.getFileLoc(loc);
                auto locstr = srcloc.printToString(srcm);

                for (auto & src: srcs)
                {
                    if (locstr.find(src) != string::npos)
                    {
                        std::vector <const clang::Stmt*> stmts;
                        if (fn->isMain())
                        {
                            if (auto cmpd = clang::dyn_cast<clang::CompoundStmt>(fn->getBody())){

                                for (auto it = cmpd->body_begin(); it != cmpd->body_end(); it++)
                                {
                                    ROSStatementMatcher rootMatcher{ this->context_, this->interp_};
                                    rootMatcher.setup();
                                    //std::cout<<""dumping\n"";
                                    //(*it)->dump();
                                    //std::cout<<""dumped\n"";
                                    rootMatcher.visit(**it);
                                    if (rootMatcher.getChildExprStore())
                                    {
                                        //std::cout<<""child!!!\n"";
                                        //rootMatcher.getChildExprStore()->dump();
                                        stmts.push_back(rootMatcher.getChildExprStore());
                                    }
                                }
                                this->interp_->buffer_body(stmts);
                                this->interp_->mkNode(""COMPOUND_STMT"", cmpd, false);
                                this->interp_->buffer_body(cmpd);
                                this->interp_->mkNode(""FUNCTION_MAIN"", fn, false);
                                globals.push_back(fn);

                            }
                            else
                            {
                                std::cout << ""Warning : Unable to parse main function? \n"";
                                fn->getBody()->dump();
                            }
                        }
                        else{
                            auto retType = (clang::QualType)fn->getReturnType();
        
                            auto fbody = fn->getBody();
                            /*
                            auto typeDetector = [=](std::string typenm){
                                if(false){return false;}
                        " +
                                         Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length), a_ =>
                                                     "\n\t\t\telse if(" + GoNext.GetTypeMatchCondition("typenm", a_.TypeName) + @"){ return true; }")
                                         + @"
                                else { return false;}
                            };*/

                            ROSStatementMatcher bodym{ this->context_, this->interp_};
                            bodym.setup();
                            bodym.visit(*fbody);

                            if(!bodym.getChildExprStore()){
                                std::cout<<""No detected nodes in body of function\n"";
                                return;
                            }

                            std::vector<const clang::ParmVarDecl*> valid_params_;
                            auto params_ = fn->parameters();
                            if(params_.size() > 0){
                                for(auto param_ : params_){
                                    auto typestr = param_->getType().getAsString();
                                    if(false){}
                                 "
                                         +
                                         Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                     p_ =>
            {
                return(@"
                                    else if(" + GoNext.GetTypeMatchCondition("typestr", p_.TypeName) + @"){
                                        //interp_->mkFunctionParam(""" + p_.RefName + @""", param_);

                                        if(auto dc = clang::dyn_cast<clang::ParmVarDecl>(param_)){
                                            interp_->mkNode(""FUNCTION_PARAM"", param_,false);
                                            valid_params_.push_back(const_cast<clang::ParmVarDecl*>(param_));
                                        }
                                        else
                                        {
                                            std::cout << ""Warning : Param is not a ParmVarDecl\n"";
                                            param_->dump();
                                        }
                                        valid_params_.push_back(param_);
                                    }");
            }) + @"
                                }
                            }
                            bool hasReturn = false;
                            auto nodePrefix = std::string("""");
                            auto typenm = retType.getAsString();
                            if(false){}
                        " +
                                         Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length), a_ =>
                                                     "\n\t\t\t\t\t\t\telse if(" + GoNext.GetTypeMatchCondition("typenm", a_.TypeName) + @"){ hasReturn = true; nodePrefix = """ + a_.RefName + @"""; }")
                                         + @"
                            else {}
        

                            if(valid_params_.size()>0){
                                interp_->buffer_operands(valid_params_);
            
                            }
                            interp_->buffer_body(bodym.getChildExprStore());
                            if(hasReturn){
                                interp_->mkFunctionWithReturn(nodePrefix, fn);
                            }
                            else{
                                interp_->mkFunction(fn);
                            }
                            globals.push_back(fn);
                                    
                        }
                    }
                }
            }
        }

        //this->interp_->mkSEQ_GLOBALSTMT(tud, globals);
        this->interp_->buffer_body(globals);
        this->interp_->mkNode(""COMPOUND_GLOBAL"", tud, false, true);
    }
};
";
        }
Пример #9
0
        public static void GenStatementCpp()
        {
            GenMatcher.StatementCppFile = @"
#include ""clang/ASTMatchers/ASTMatchFinder.h""
#include ""clang/ASTMatchers/ASTMatchers.h""
#include <vector>

#include ""../Interpretation.h""

#include ""ROSStatementMatcher.h""
"
                                          +
                                          Peirce.Join("\n", ParsePeirce.Instance.MatcherProductions, p_ => "#include \"" + p_.ClassName + ".h\"")
                                          +
                                          @"

#include <string>


#include <iostream>

#include <memory>

#include ""../maps/ASTToCoords.h""
/*
This manages all statements in Clang.
*/


void ROSStatementMatcher::setup(){

    StatementMatcher exprWithCleanups_ =
        exprWithCleanups(has(expr().bind(""UsefulExpr""))).bind(""ExprWithCleanupsDiscard"");//fluff node to discard

    StatementMatcher
        decl_ = declStmt().bind(""DeclStmt"");
    StatementMatcher
        assign_ = anyOf(
            cxxOperatorCallExpr(
                hasOverloadedOperatorName(""="")).bind(""Assign""),
            binaryOperator(
                hasOperatorName(""="")).bind(""Assign"")
        );

    StatementMatcher
        ifStmt_ = ifStmt().bind(""IfStmt"");

    StatementMatcher
        cmpdStmt_ = compoundStmt().bind(""CompoundStmt"");

    StatementMatcher
        expr_ = expr().bind(""ExprStmt"");

    StatementMatcher
        returnStmt_ = returnStmt().bind(""ReturnStmt"");

    StatementMatcher 
        whileStmt_ = whileStmt().bind(""WhileStmt"");

    StatementMatcher
        forStmt_ = forStmt().bind(""ForStmt"");

    StatementMatcher
        tryStmt_ = cxxTryStmt().bind(""TryStmt"");

    StatementMatcher
        cxxMemberCallExpr_ = cxxMemberCallExpr().bind(""CXXMemberCallExpr"");

    //StatementMatcher
    //    functionDecl_ = functionDecl().bind(""FunctionDecl"");

    localFinder_.addMatcher(exprWithCleanups_,this);
    localFinder_.addMatcher(cxxMemberCallExpr_,this);
    localFinder_.addMatcher(decl_, this);
    localFinder_.addMatcher(assign_, this);
    localFinder_.addMatcher(expr_, this);
    localFinder_.addMatcher(ifStmt_,this);
    localFinder_.addMatcher(cmpdStmt_, this);
    localFinder_.addMatcher(returnStmt_, this);
    localFinder_.addMatcher(whileStmt_, this);
    localFinder_.addMatcher(forStmt_, this);
    localFinder_.addMatcher(tryStmt_, this);
    //localFinder_.addMatcher(functionDecl_, this);
    this->childExprStore_ = nullptr;
};

void ROSStatementMatcher::run(const MatchFinder::MatchResult &Result){
    if(this->childExprStore_ != nullptr){
        return;
    }

    const auto declStmt = Result.Nodes.getNodeAs<clang::DeclStmt>(""DeclStmt"");

    const auto assignStmt = Result.Nodes.getNodeAs<clang::Expr>(""Assign"");

    const auto exprStmt = Result.Nodes.getNodeAs<clang::Expr>(""ExprStmt"");

    const auto exprWithCleanupsDiscard = Result.Nodes.getNodeAs<clang::ExprWithCleanups>(""ExprWithCleanupsDiscard"");

    //const auto ifStmt_ = Result.Nodes.getNodeAs<clang::IfStmt>(""IfStmt"");

    const auto cmpdStmt_ = Result.Nodes.getNodeAs<clang::CompoundStmt>(""CompoundStmt"");

    //const auto returnStmt_ = Result.Nodes.getNodeAs<clang::ReturnStmt>(""ReturnStmt"");

    const auto whileStmt_ = Result.Nodes.getNodeAs<clang::WhileStmt>(""WhileStmt"");

    const auto forStmt_ = Result.Nodes.getNodeAs<clang::ForStmt>(""ForStmt"");

    const auto tryStmt_ = Result.Nodes.getNodeAs<clang::CXXTryStmt>(""TryStmt"");

    const auto cxxMemberCallExpr_ = Result.Nodes.getNodeAs<clang::CXXMemberCallExpr>(""CXXMemberCallExpr"");
    
    //const auto functionDecl_ = Result.Nodes.getNodeAs<clang::FunctionDecl>(""FunctionDecl"");

    if(whileStmt_){
        auto wcond = whileStmt_->getCond();
        auto wbody = whileStmt_->getBody();
        
        ROSBooleanMatcher condm{ this->context_, this->interp_};
        condm.setup();
        condm.visit(*wcond);

        if(!condm.getChildExprStore()){
            std::cout<<""Unable to parse While condition!!\n"";
            wcond->dump();
            throw ""Broken Parse"";
        }

        ROSStatementMatcher bodym{ this->context_, this->interp_};
        bodym.setup();
        bodym.visit(*wbody);

        if(!bodym.getChildExprStore()){
            std::cout<<""Unable to parse While block!!\n"";
            wbody->dump();
            throw ""Broken Parse"";
        }

        //this->interp_->mkWHILE_BOOL_EXPR_STMT(whileStmt_, condm.getChildExprStore(), bodym.getChildExprStore());
        interp_->buffer_operand(condm.getChildExprStore());
        interp_->buffer_operand(bodym.getChildExprStore());
        interp_->mkNode(""WHILE_STMT"", whileStmt_, false);
        
        this->childExprStore_ = (clang::Stmt*)whileStmt_;
        return;

    }

    if(forStmt_){
        auto wcond = forStmt_->getCond();
        auto wbody = forStmt_->getBody();
        
        ROSBooleanMatcher condm{ this->context_, this->interp_};
        condm.setup();
        condm.visit(*wcond);

        if(!condm.getChildExprStore()){
            std::cout<<""Unable to parse For condition!!\n"";
            wcond->dump();
            throw ""Broken Parse"";
        }

        ROSStatementMatcher bodym{ this->context_, this->interp_};
        bodym.setup();
        bodym.visit(*wbody);

        if(!bodym.getChildExprStore()){
            std::cout<<""Unable to parse For block!!\n"";
            wbody->dump();
            throw ""Broken Parse"";
        }

        //this->interp_->mkFOR_BOOL_EXPR_STMT(forStmt_, condm.getChildExprStore(), bodym.getChildExprStore());
        interp_->buffer_operand(condm.getChildExprStore());
        interp_->buffer_operand(bodym.getChildExprStore());
        interp_->mkNode(""FOR_STMT"",forStmt_,false); 
        this->childExprStore_ = (clang::Stmt*)forStmt_;
        return;
    }

    //if(functionDecl_){
        

    /*
    if(returnStmt_){
        auto _expr = returnStmt_->getRetValue();
        auto typestr = ((clang::QualType)_expr->getType()).getAsString();
        if(false){}
        "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)

                return(@"
        else if (typestr == """ + p_.TypeName + @""" or typestr == ""const " + p_.TypeName + @"""  or typestr == ""class " + p_.TypeName + @"""  or typestr == ""const class " + p_.TypeName + @"""/*typestr.find(""" + p_.TypeName + @""") != string::npos) != string::npos){
            " + p_.ClassName + @" m{ this->context_, this->interp_};
            m.setup();
            m.visit(*_expr);
            if(m.getChildExprStore()){
                this->childExprStore_ = (clang::Stmt*)_expr;
            }
            return;
        }
            ");
            })
                                          + @"
    }*/

    if(cmpdStmt_){
        std::vector<const clang::Stmt*> stmts;

        for(auto st : cmpdStmt_->body()){
            ROSStatementMatcher stmti{this->context_,this->interp_};
            stmti.setup();
            stmti.visit(*st);
            if(stmti.getChildExprStore()){
                stmts.push_back(stmti.getChildExprStore());
            }
            else{
                //auto current = st;
                std::vector<std::vector<clang::Stmt*>> stack;
                std::vector<int> recptr;

                /*search up to depth 3 for now. this is not sound, but a sound approach may lead to other issues
                */
                for(auto c1 : st->children()){
                    ROSStatementMatcher i1{this->context_,this->interp_};
                    i1.setup();
                    i1.visit(*c1);
                    if(i1.getChildExprStore()){
                        stmts.push_back(i1.getChildExprStore());
                    }
                    else{
                        for(auto c2 : c1->children()){
                            ROSStatementMatcher i2{this->context_,this->interp_};
                            i2.setup();
                            i2.visit(*c2);
                            if(i2.getChildExprStore()){
                                stmts.push_back(i2.getChildExprStore());
                            }
                            else{
                                for(auto c3 : c2->children()){
                                    ROSStatementMatcher i3{this->context_,this->interp_};
                                    i3.setup();
                                    i3.visit(*c3);
                                    if(i3.getChildExprStore()){
                                        stmts.push_back(i3.getChildExprStore());
                                    }
                                    else{
                                        for(auto c4 : c3->children()){
                                            ROSStatementMatcher i4{this->context_,this->interp_};
                                            i4.setup();
                                            i4.visit(*c4);
                                            if(i4.getChildExprStore()){
                                                stmts.push_back(i4.getChildExprStore());
                                            }
                                            else{
                                                
                                            }
                                        } 
                                    }
                                }
                            }
                        }
                    }
                }

                /*
                restart:
                std::vector<clang::Stmt*> current_stack;
                for(auto c : current->children()) current_stack.push_back(c);
                stack.push_back(current_stack);
                recptr.push_back(0);
                while(!stack.empty()){
                    for(int i = 0; i<stack.back().size();i++){
                        if(recptr.back() > i) continue;
                        auto c = 
                            ROSStatementMatcher inner{this->context_,this->interp_};
                        inner.setup();
                        inner.visit(*c);
                        if(inner.getChildExprStore()){
                            stmts.push_back(inner.getChildExprStore());
                            recptr.back()++;
                        }
                        else if(c->child_begin() != c->child_end()){
                            current = c;
                            goto restart;
                        }
                    }
                }
                */
                    
                    
                
            }
        }
        //this->interp_->mkCOMPOUND_STMT(cmpdStmt_, stmts);
        if(stmts.size()>0){
            interp_->buffer_body(stmts);
            interp_->mkNode(""COMPOUND_STMT"", cmpdStmt_);
            this->childExprStore_ = (clang::Stmt*)cmpdStmt_;
        }
        return;
        
    }

    " + Peirce.Join("", new string[] { "hi" }, (prod) =>
            {
                //var callexpr = prod.GrammarType.Cases.Single(pcase => pcase.Name.Contains("CALL"));

                /*
                 *
                 * bool     hasInitStorage () const
                 *  True if this IfStmt has the storage for an init statement. More...
                 *
                 * bool     hasVarStorage () const
                 *  True if this IfStmt has storage for a variable declaration. More...
                 *
                 * bool     hasElseStorage () const
                 *  True if this IfStmt has storage for an else statement. More...
                 *
                 * Expr *   getCond ()
                 *
                 * const Expr *     getCond () const
                 *
                 * void     setCond (Expr *Cond)
                 *
                 * Stmt *   getThen ()
                 *
                 * const Stmt *     getThen () const
                 *
                 * void     setThen (Stmt *Then)
                 *
                 * Stmt *   getElse ()
                 *
                 * const Stmt *     getElse () const
                 *
                 * */
                var ifProd = ParsePeirce.Instance.Grammar.Productions.SingleOrDefault(p_ => p_.Name.StartsWith("IF"));

                if (ifProd == null)
                {
                    return("");
                }

                /*
                 * _IFCOND :=
                 * IFTHEN +BOOL_EXPR +STMT | ~An If-Then Statement
                 * IFTHENELSEIF +BOOL_EXPR +STMT +IFCOND | ~An If-Then-Else-If Statement
                 * IFTHENELSE +BOOL_EXPR +STMT +STMT ~An If-Then-Else Statement
                 *
                 * */
                var ifthen       = ifProd.Cases.Single(c => c.Productions.Count == 2);
                var ifthenelseif = ifProd.Cases.Single(c => c.Productions.Count > 2 && c.Productions[2].Name.StartsWith("IF"));
                var ifthenelse   = ifProd.Cases.Single(c => c.Productions.Count > 2 && c.Productions[2].Name.StartsWith("STMT"));

                return(@"
    if(ifStmt_){
        auto cond = ifStmt_->getCond();
        auto thens = ifStmt_->getThen();

        ROSBooleanMatcher condm{ this->context_, this->interp_};
        condm.setup();
        condm.visit(*cond);

        if(!condm.getChildExprStore()){
            std::cout<<""Unable to parse If condition!!\n"";
            cond->dump();
            throw ""Broken Parse"";
        }

        ROSStatementMatcher thenm{ this->context_, this->interp_};
        thenm.setup();
        thenm.visit(*thens);

        if(!thenm.getChildExprStore()){
            std::cout<<""Unable to parse If block!!\n"";
            thens->dump();
            throw ""Broken Parse"";
        }

        if(ifStmt_->getElse()){
            auto elses = ifStmt_->getElse();

            ROSStatementMatcher elsem{ this->context_, this->interp_};
            elsem.setup();
            elsem.visit(*elses);
            if(!elsem.getChildExprStore()){
                std::cout<<""Unable to parse Then block!!\n"";
                elses->dump();
                throw ""Broken Parse"";
            }

            interp_->buffer_operand(condm.getChildExprStore());
            interp_->buffer_operand(thenm.getChildExprStore());
            interp_->buffer_operand(elsem.getChildExprStore());
            interp_->mkNode(""IF_THEN_ELSE_STMT"",ifStmt_,false);
            
            //no need, redundant case
            /*if(auto dc = clang::dyn_cast<clang::IfStmt>(ifStmt_->getElse())){
                interp_->mk" + ifthenelseif.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore(), elsem.getChildExprStore());
                this->childExprStore_ = (clang::Stmt*)ifStmt_;
                return;
            }
            else{
                interp_->mk" + ifthenelse.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore(), elsem.getChildExprStore());
                this->childExprStore_ = (clang::Stmt*)ifStmt_;
                return;
            }*/
        }
        else{
            //interp_->mk" + ifthen.Name + @"(ifStmt_, condm.getChildExprStore(), thenm.getChildExprStore());
            interp_->buffer_operand(condm.getChildExprStore());
            interp_->buffer_operand(thenm.getChildExprStore());
            interp_->mkNode(""IF_THEN_ELSE_STMT"",ifStmt_,false);

            this->childExprStore_ = (clang::Stmt*)ifStmt_;
            return;

        }
    }
");
            }) + @"
    auto vec_str = std::string(""std::vector<"");
    if (declStmt)
    {
        if (declStmt->isSingleDecl())
        {
            if (auto vd = clang::dyn_cast<clang::VarDecl>(declStmt->getSingleDecl()))
             {
                auto typestr = ((clang::QualType)vd->getType()).getAsString();
                if(false){}
                else if(typestr.substr(0,vec_str.length())==vec_str){
                    //std::cout<<typestr.substr(vec_str.length(), typestr.length()-vec_str.length()-1)<<""\n"";
                    std::string param_type = typestr.substr(vec_str.length(), typestr.length()-vec_str.length()-1);
                    if(false){}                
"
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)
                //if (p_.SearchForDecl(true) == null)
                //    return "";
                return(@"
                        else if(" + GoNext.GetTypeMatchCondition("param_type", p_.TypeName) + @"){
                            
                            interp_->mkNode(""IDENT_LIST_" + p_.RefName + @""",vd, true);
                            if (vd->hasInit()){
                                //" + p_.ClassName + @" argm{this->context_,this->interp_};
                                //argm.setup();
                               // argm.visit(*vd->getInit());
                               // auto argstmt = argm.getChildExprStore();
                               //interp_->buffer_operand(argstmt);
                                interp_->buffer_operand(vd);
                                interp_->mkNode(""DECL_LIST_" + p_.RefName + @""",declStmt, false);
                                this->childExprStore_= (clang::Stmt*) declStmt;
                                return;
                            }
                            else{
                                interp_->buffer_operand(vd);
                                interp_->mkNode(""DECL_LIST_" + p_.RefName + @""",declStmt, false);
                                this->childExprStore_ = (clang::Stmt*) declStmt;
                                return;
                            }
                        }
                    ");
            }) + @"
                }
"
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)
                //if (p_.SearchForDecl(true) == null)
                //    return "";


                return(@"
                else if (" + GoNext.GetTypeMatchCondition("typestr", p_.TypeName) + @"){
                    //interp_->mk" + @"(vd);
                    interp_->mkNode(""IDENT_" + p_.RefName + @""",vd, true);
                    if (vd->hasInit())
                    {
                        " + p_.ClassName + @" m{ this->context_, this->interp_};
                        m.setup();
                        m.visit((*vd->getInit()));
                        if (m.getChildExprStore())
                        {
                            //interp_->mk" + @"(declStmt, vd, m.getChildExprStore());
                            interp_->buffer_operand(vd);
                            interp_->buffer_operand(m.getChildExprStore());
                            interp_->mkNode(""DECL_INIT_" + p_.RefName + @""", declStmt);
                            this->childExprStore_ =  (clang::Stmt*)declStmt;
                            return;
                        }
                        else
                        {
                            //interp_->mk" + @"(declStmt, vd);
                            interp_->buffer_operand(vd);
                            interp_->mkNode(""DECL_" + p_.RefName + @""", declStmt);
                            this->childExprStore_ =  (clang::Stmt*)declStmt;
                            return;
                        }
                    }
                    else
                    {
                        //interp_->mk" + @"(declStmt, vd);
                        interp_->buffer_operand(vd);
                        interp_->mkNode(""DECL_" + p_.RefName + @""", declStmt);
                        this->childExprStore_ = (clang::Stmt*)declStmt;
                        return;
                    }
                }
            ");
            }
                                                      )
                                          + @"
            }
        }
        else
        {
            bool anyfound = false;
            for (auto it = declStmt->decl_begin(); it != declStmt->decl_end(); it++)
            {
                if (auto vd = clang::dyn_cast<clang::VarDecl>(declStmt->getSingleDecl()))
                {
                    auto typestr = ((clang::QualType)vd->getType()).getAsString();
                    if(false){}
                "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //if (p_.SearchForDecl(true) == null) return "";

                return(@"
                    else if(" + GoNext.GetTypeMatchCondition("typestr", p_.TypeName) + @"){
                        //interp_->mk" + @"(vd);
                        
                        interp_->mkNode(""IDENT_" + p_.RefName + @""",vd, true);
                        if (vd->hasInit())
                        {
                            " + p_.ClassName + @" m{ this->context_, this->interp_};
                            m.setup();
                            m.visit((*vd->getInit()));
                            if (m.getChildExprStore())
                            {
                                //interp_->mk" + @"(declStmt, vd, m.getChildExprStore());
                                interp_->buffer_operand(vd);
                                interp_->buffer_operand(m.getChildExprStore());
                                interp_->mkNode(""DECL_INIT_" + p_.RefName + @""", declStmt);
                                this->childExprStore_ =  (clang::Stmt*)declStmt;
                            }
                            else
                            {
                                //interp_->mk" + @"(declStmt, vd);
                                interp_->buffer_operand(vd);
                                interp_->mkNode(""DECL_" + p_.RefName + @""", declStmt);
                                this->childExprStore_ =  (clang::Stmt*)declStmt;
                            }
                        }
                        else
                        {
                            //interp_->mk" + @"(declStmt, vd);
                            interp_->buffer_operand(vd);
                            interp_->mkNode(""DECL_" + p_.RefName + @""", declStmt);
                            this->childExprStore_ =  (clang::Stmt*)declStmt;
                        }
                        anyfound = true;
                    }");
            })
                                          + @"
                }
            }
            if (anyfound)
            {
                this->childExprStore_ = const_cast<clang::DeclStmt*>(declStmt);
                return;
            }
        }
    }
    else if (assignStmt)
    {
        //not implemented!!
    }
    else if (exprWithCleanupsDiscard)
    {//matches fluff node to discard
        ROSStatementMatcher innerMatcher{ this->context_, this->interp_};
        innerMatcher.setup();
        innerMatcher.visit(*exprWithCleanupsDiscard->getSubExpr());
        if (innerMatcher.getChildExprStore()){
            this->childExprStore_ = const_cast<clang::Stmt*>(innerMatcher.getChildExprStore());
            return;
        }
    }
    else if (cxxMemberCallExpr_)
    {
        auto decl_ = cxxMemberCallExpr_->getMethodDecl();
        if(auto dc = clang::dyn_cast<clang::NamedDecl>(decl_)){
            auto name = dc->getNameAsString();
            auto obj= cxxMemberCallExpr_->getImplicitObjectArgument();
            auto objstr = ((clang::QualType)obj->getType()).getAsString();
            if(objstr.substr(0,vec_str.length())==vec_str and name.find(""push_back"") != string::npos){
                if(auto dc2 = clang::dyn_cast<clang::DeclRefExpr>(obj)){
                    auto objdecl = clang::dyn_cast<clang::VarDecl>(dc2->getDecl());
                    //interp_->buffer_link(objdecl);
                    //interp_->mkNode(""APPEND_LIST_R1"",cxxMemberCallExpr_,false);
                    std::string param_type = objstr.substr(vec_str.length(), objstr.length()-vec_str.length()-1);
                    if(false){}                
"
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                //var withInit = p_.SearchForDecl(true);
                //var woInit = p_.SearchForDecl(t)
                //if (p_.SearchForDecl(true) == null)
                //    return "";
                return(@"
                    else if(" + GoNext.GetTypeMatchCondition("param_type", p_.TypeName) + @"){
                        
                        auto arg_=cxxMemberCallExpr_->getArg(0);
                        " + p_.ClassName + @" argm{this->context_,this->interp_};
                        argm.setup();
                        argm.visit(*arg_);
                        auto argstmt = argm.getChildExprStore();
                        interp_->buffer_link(objdecl);
                        interp_->buffer_operand(argstmt);
                        interp_->mkNode(""APPEND_LIST_" + p_.RefName + @""",cxxMemberCallExpr_, false);
                        this->childExprStore_ = (clang::Stmt*)cxxMemberCallExpr_;
                        return;
                    }
                    ");
            }) + @"
                }
                else {
                    std::cout<<""Warning : Not a DeclRefExpr"";
                }
            }
        }
    }
    else if (exprStmt)
    {
        auto typestr = ((clang::QualType)exprStmt->getType()).getAsString();
        "
                                          +
                                          Peirce.Join("", ParsePeirce.Instance.MatcherProductions.OrderByDescending(p_ => p_.TypeName.Length),
                                                      p_ =>
            {
                return(@"
        if(" + GoNext.GetTypeMatchCondition("typestr", p_.TypeName) + @"){
            " + p_.ClassName + @" m{ this->context_, this->interp_};
            m.setup();
            m.visit(*exprStmt);
            if (m.getChildExprStore()){
                this->childExprStore_ = const_cast<clang::Stmt*>(m.getChildExprStore());
                return;
            }
                
        }");
            }) + @"
    }
    else if(tryStmt_){
        auto tryBlock = tryStmt_->getTryBlock();
        ROSStatementMatcher innerMatcher{ this->context_, this->interp_};
        innerMatcher.setup();
        innerMatcher.visit(*tryBlock);
        if (innerMatcher.getChildExprStore()){
            this->childExprStore_ = (clang::Stmt*)tryStmt_;//const_cast<clang::Stmt*>(innerMatcher.getChildExprStore());
            interp_->buffer_operand(innerMatcher.getChildExprStore());
            interp_->mkNode(""TRY_STMT"",tryStmt_);//,innerMatcher.getChildExprStore());
            return;
        }
    }
    else
    {
        //log error
    }

};

";
        }