예제 #1
0
파일: cpp.c 프로젝트: rui314/8cc-old
/*
 * Reads a token from a given preprocessing context, expands it if macro, and
 * returns it.
 */
static Token *expand_one(CppContext *ctx) {
    Token *tok = read_cpp_token(ctx);
    if (!tok) return NULL;
    if (tok->toktype != TOKTYPE_IDENT)
        return tok;
    String *name = tok->val.str;
    Macro *macro = dict_get(ctx->defs, name);
    if (!macro)
        return tok;
    if (list_in(tok->hideset, name))
        return tok;

    switch (macro->type) {
    case MACRO_OBJ: {
        List *ts = subst(ctx, macro, make_list(), list_union1(tok->hideset, name));
        pushback(ctx, ts);
        return expand_one(ctx);
    }
    case MACRO_FUNC: {
        List *args = read_args(ctx, macro);
        Token *rparen = read_cpp_token(ctx);
        List *hideset = list_union1(list_intersect(tok->hideset, rparen->hideset), name);
        List *ts = subst(ctx, macro, args, hideset);
        pushback(ctx, ts);
        return expand_one(ctx);
    }
    case MACRO_SPECIAL:
        macro->fn(ctx, tok);
        return expand_one(ctx);
    }
    panic("should not reach here");
}
예제 #2
0
void CornerSequence::placeFixedMacros() {
    for (int i = 0; i < fixedMacros->size(); ++i) {
        Macro *macro = fixedMacros->at(i);
        for (int iRectangle = 0; iRectangle < macro->getRectangles()->size(); ++iRectangle) {
            Rectangle *rectangle = macro->getRectangles()->at(iRectangle);
            int tileXStart = rectangle->getXStart();
            int tileYStart = rectangle->getYStart();
            int tileXEnd = rectangle->getXEnd();
            int tileYEnd = rectangle->getYEnd();
            Tile *horizontalTile = new Tile(tileXStart, tileYStart, tileXEnd, tileYEnd, true);
            Tile *verticalTile = new Tile(tileXStart, tileYStart, tileXEnd, tileYEnd, true);
            Tile *startHorizontalTile = cornerHorizontalTilePlane->findTile(tileXStart, tileYStart,
                cornerHorizontalTilePlane->getTopLeftMostTile());
            Tile *startVerticalTile = cornerVerticalTilePlane->findTile(tileXStart, tileYStart,
                cornerVerticalTilePlane->getTopLeftMostTile());
            cornerHorizontalTilePlane->placeSolidTileGivenBothStartTiles(horizontalTile,
                startHorizontalTile, startVerticalTile);
            startHorizontalTile = horizontalTile;
            cornerVerticalTilePlane->placeSolidTileGivenBothStartTiles(verticalTile,
                startVerticalTile, startHorizontalTile);

            cornerHorizontalTilePlane->calculateCurrentCornersWidthAndHeight();
            cornerVerticalTilePlane->calculateCurrentCornersWidthAndHeight();
            updateQuadtrees();
        }
    }
}
예제 #3
0
int main() {
	Macro macro;
	macro.add(new Hello);
	macro.add(new World);
	macro.add(new IAm);
	macro.run();
}
예제 #4
0
// CppMacro
CppMacro::CppMacro(const Macro &macro) : CppElement()
{
    setHelpCategory(TextEditor::HelpItem::Macro);
    setHelpIdCandidates(QStringList(macro.name()));
    setHelpMark(macro.name());
    setLink(CPPEditorWidget::Link(macro.fileName(), macro.line()));
    setTooltip(macro.toStringWithLineBreaks());
}
예제 #5
0
void Driver::removeAllMacrosInFile( const QString& fileName )
{
    QMap<QString, Macro>::Iterator it = m_macros.begin();
    while( it != m_macros.end() ){
        Macro m = *it++;
        if( m.fileName() == fileName )
            removeMacro( m.name() );
    }
}
예제 #6
0
 explicit CppMacro(const Macro &macro)
 {
     helpCategory = Core::HelpItem::Macro;
     const QString macroName = QString::fromUtf8(macro.name(), macro.name().size());
     helpIdCandidates = QStringList(macroName);
     helpMark = macroName;
     link = Utils::Link(macro.fileName(), macro.line());
     tooltip = macro.toStringWithLineBreaks();
 }
// CppMacro
CppMacro::CppMacro(const Macro &macro)
{
    helpCategory = TextEditor::HelpItem::Macro;
    const QString macroName = QLatin1String(macro.name());
    helpIdCandidates = QStringList(macroName);
    helpMark = macroName;
    link = CPPEditorWidget::Link(macro.fileName(), macro.line());
    tooltip = macro.toStringWithLineBreaks();
}
예제 #8
0
   bool
   SQLScriptRunner::ExecuteScript(shared_ptr<DALConnection> connectionObject, const String &sFile, String &sErrorMessage)
   {
      SQLScriptParser oParser(connectionObject->GetSettings(), sFile);
      if (!oParser.Parse(sErrorMessage))
      {
         sErrorMessage = "Parsing of SQL script failed: " + sFile + "\r\nError:" + sErrorMessage;
         return false;
      }

      if (oParser.GetNoOfCommands() == 0)
      {
         sErrorMessage = "Found no SQL commands in file : " + sFile;
         return false;
      }

      // 30 minute timeout per statement. Should hopefully never be needed.
      connectionObject->SetTimeout(60 * 30);

      for (int i = 0; i < oParser.GetNoOfCommands(); i++)
      {
         String sCommand = oParser.GetCommand(i);

         if (sCommand.StartsWith(_T("@@@")))
         {
            // Remove leading @@@.
            sCommand = sCommand.Mid(3);

            // Remove trailing @@@
            sCommand = sCommand.Mid(0, sCommand.Find(_T("@@@")));

            MacroParser parser(sCommand);
            Macro macro = parser.Parse();

            if (macro.GetType() == Macro::Unknown)
            {
               sErrorMessage = "Parsing of SQL script failed. Unknown macro. " + sFile + "\r\nMacro:" + sCommand;
               return false;
            }

            shared_ptr<IMacroExpander> macroExpander = connectionObject->CreateMacroExpander();
            if (!macroExpander->ProcessMacro(connectionObject, macro, sErrorMessage))
               return false;
         }
         else
         {
            if (connectionObject->TryExecute(SQLCommand(sCommand), sErrorMessage, 0, 0) != DALConnection::DALSuccess)
            {
               return false;
            }
         }
      }

      connectionObject->SetTimeout(30);

      return true;
   }
예제 #9
0
void Driver::removeAllMacrosInFile( const QString& fileName ) {
  MacroMap::iterator it = m_macros.begin();
  while ( it != m_macros.end() ) {
    Macro m = ( *it ).second;
    if ( m.fileName() == fileName ) {
      m_macros.erase( it++ );
    } else {
      ++it;
    }
  }
}
예제 #10
0
int main(int argc, char* argv[]) {

	cout << argc << endl;
	for (int h = 0; h<argc; h++)
		cout << argv[h] << endl;

	cout << endl;

	Recorder* rec = Recorder::GetInstance();

	//One of each device
	TestDevice* dev = new TestDevice("dev");
	Relay* rel = new Relay();
	SpeedController* ctrl = new SpeedController();
	Servo* serv = new Servo();
	DoubleSolenoid* ds = new DoubleSolenoid();
	Solenoid* sol = new Solenoid();

	//Add all devices to recorder
	rec->AddDevice("Relay",rel);
	rec->AddDevice("Speed Controller",ctrl);
	rec->AddDevice("Servo",serv);
	rec->AddDevice("Double Solenoid",ds);
	rec->AddDevice("Solenoid",sol);
	rec->AddDevice(dev);

	//Creates macro
	cout << dev->GetName() << endl;

	Macro* mac = rec -> macro();


	int iterations = 5;


	for (int i = 0; i<iterations; i++) {
		mac->Record();
	}

	mac->WriteFile("auto.csv");
	mac->Reset();

	mac->ReadFile("auto.csv");
	while (!mac->IsFinished())
	{
		mac->PlayBack();
	}

	cout << "plz work" << endl;

	mac->Reset();
	Command* recCom = mac->NewRecordFileCommand("auto2.csv");
	recCom->Initialize();
	for (int i = 0; i < 30; i ++) recCom->Execute();
	recCom->End();

	return 0;
}
예제 #11
0
void MainWindow::handleTimClick(QTreeWidgetItem* item,int) {

    ui->currentMacroTE->clear();
    QString selectedMacro = item->text(0);
    Macro macro = guiMacro->getStorage().getMacro(selectedMacro);
    const ParameterStorage& params=macro.getParameterStorage();
    ui->parametersTextEdit->setText(params.toString());

    foreach(const QStringList& line, macro.getContent()) {
        ui->currentMacroTE->insertPlainText(line.join("\t") + "\n");
    }

}
예제 #12
0
void MacroManager::MacroManagerPrivate::initialize()
{
    macros.clear();
    QDir dir(q->macrosDirectory());
    QStringList filter;
    filter << QString("*.")+Constants::M_EXTENSION;
    QStringList files = dir.entryList(filter, QDir::Files);

    foreach (const QString &name, files) {
        QString fileName = dir.absolutePath() + '/' + name;
        Macro *macro = new Macro;
        macro->loadHeader(fileName);
        addMacro(macro);
    }
예제 #13
0
FullSourceRef
SourceManager::getOrigin(const FullMacroRef &ref)
{
  Macro *macro = ref.macro;
  if (!macro->definedAt.isSet())
    return FullSourceRef();

  assert(!macro->start().isInMacro());
  size_t loc_index;
  if (!findLocation(macro->start(), &loc_index))
    return FullSourceRef();

  FullSourceRef origin = fullSourceRef(locations_[loc_index], macro->start());
  origin.col += ref.offset;
  return origin;
}
예제 #14
0
static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s,
                                   const Macro &macro)
{
    Macro newMacro(macro);
    newMacro.setFileRevision(s.get(macro.fileName()).second);
    return newMacro;
}
예제 #15
0
void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro &macro)
{
    if (!m_currentDoc)
        return;

    m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
                              QVector<MacroArgumentReference>());
}
예제 #16
0
bool
MySQLMacroExpander::ProcessMacro(std::shared_ptr<DALConnection> connection, const Macro &macro, String &sErrorMessage)
{
    switch (macro.GetType())
    {
    case Macro::DropColumnKeys:
        // MySQL4 doesn't support WHERE clauses in SHOW INDEX so
        // we must manually sort the result below.
        String sql;
        sql.Format(_T("SHOW INDEX IN %s"), macro.GetTableName().c_str());

        MySQLRecordset rec;
        if (!rec.Open(connection, SQLCommand(sql)))
        {
            sErrorMessage = "It was not possible to execute the below SQL statement. Please see hMailServer error log for details.\r\n" + sql;
            return false;
        }

        while (!rec.IsEOF())
        {
            String columnName = rec.GetStringValue("Column_name");

            if (columnName.CompareNoCase(macro.GetColumnName()) != 0)
            {
                // Wrong column
                rec.MoveNext();
                continue;
            }

            String constraintName = rec.GetStringValue("Key_name");

            String sqlUpdate;
            sqlUpdate.Format(_T("ALTER TABLE %s DROP INDEX %s"), macro.GetTableName().c_str(), constraintName.c_str());

            DALConnection::ExecutionResult execResult = connection->TryExecute(SQLCommand(sqlUpdate), sErrorMessage, 0, 0);

            if (execResult != DALConnection::DALSuccess)
                return false;

            rec.MoveNext();
        }
        break;
    }

    return true;
}
예제 #17
0
void Driver::addMacro( const Macro & macro ) {
  std::pair< MacroMap::iterator, MacroMap::iterator > range = m_macros.equal_range( macro.name() );

  if ( range.first == range.second ) {
      m_macros.insert( std::make_pair( deepCopy( macro.name() ), macro ) );
  } else {
    ///Insert behind the other macros
      m_macros.insert( range.second, std::make_pair( deepCopy( macro.name() ), macro ) );
    Macro cp = this->macro( macro.name() );
    assert( macro == cp );
  }

#ifdef CACHELEXER
  if( m_currentLexerCache )
    m_currentLexerCache->addDefinedMacro( macro );
#endif
}
예제 #18
0
void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line,
                                          const Macro &macro,
                                          const QVector<MacroArgumentReference> &actuals)
{
    if (!m_currentDoc)
        return;

    m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line,
                              actuals);
}
예제 #19
0
파일: a_all.cpp 프로젝트: BigEd/Cores
	/* ---------------------------------------------------------------
			Second part of macro definiton. Actually store the
		macro in the table. To this point lines for the macro have
		been collected in macrobuf.
	--------------------------------------------------------------- */
	void Assembler::endm()
	{
		String bdy2;
		char *bdy;
		Macro *mac;
		int ii;

		// First check if in the macro definition process
		if (!CollectingMacro) {
			Err(E_ENDM);
			return;
		}
		CollectingMacro = false;
		if (pass < 2)
		{
			try {
				mac = new Macro;
				if (mac == NULL)
					throw Err(E_MEMORY);
				macrobuf.rtrim();
				// Strip out spaces on the first line because these will be
				// supplied where the macro is to be substituted.
	//			ltrim(macrobuf.buf()+1);
				macrobuf += "\r\n";
				//printf("macrobuf:%s|\r\n",macrobuf.buf());
				mac->setBody(macrobuf);
				mac->setArgCount(gMacro.Nargs());
				mac->setName(gMacro.getName().buf());
				mac->setFileLine(gMacro.getFile(), gMacro.getLine());
				bdy = mac->initBody(parmlist);   // put parameter markers into body
				bdy2 = bdy;
				mac->setBody(bdy2);              // save body with markers
			}
			catch (char *msg) {
				printf(":%s\r\n", msg);
				getchar();
			}
		}
		// we don't need parms any more so free them up
		for (ii = 0; ii < MAX_MACRO_PARMS; ii++) {
			delete parmlist[ii];
			parmlist[ii] = NULL;
		}
		// Reset macro buffer
		macrobuf = "";
		if (pass < 2)
			macroTbl->insert(mac);
	}
예제 #20
0
Bool* comparison(Variable* A, Variable* B, OperatorEnum oper)
{
    if(A == NULL || B == NULL)
    {
        interpreter.error("Error: Void variable in assignment.\n");
        return NULL;
    }
    TypeEnum a = A->getType();
    TypeEnum b = B->getType();


    bool mismatch = false;
    if(a == STRING)
    {
        if(b != STRING)
            mismatch = true;
        else
        {
            String* C = static_cast<String*>(A);
            String* D = static_cast<String*>(B);
            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }
    else if(a == INT)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Int* C = static_cast<Int*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
        }
    }
    else if(a == FLOAT)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Float* C = static_cast<Float*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
        }
    }
    else if(a == BOOL)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Bool* C = static_cast<Bool*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                switch(oper)
                {
                    case EQUALS:
                        return new Bool(C->getValue() == D->getValue());
                    case NOT_GREATER:
                    case LESS_EQUAL:
                        return new Bool(C->getValue() <= D->getValue());
                    case NOT_LESS:
                    case GREATER_EQUAL:
                        return new Bool(C->getValue() >= D->getValue());
                    case LESS:
                        return new Bool(C->getValue() < D->getValue());
                    case GREATER:
                        return new Bool(C->getValue() > D->getValue());
                    case AND:
                        return new Bool(C->getValue() && D->getValue());
                    case OR:
                        return new Bool(C->getValue() || D->getValue());
                    case NOT_EQUALS:
                        return new Bool(C->getValue() != D->getValue());
                    default:
                        UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                        return NULL;
                }
            }
        }
    }
    else if(a == MACRO)
    {
        if(b != MACRO)
            mismatch = true;
        else
        {
            Macro* C = static_cast<Macro*>(A);
            Macro* D = static_cast<Macro*>(B);
            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }
    else if(a == ARRAY)
    {
        if(b != ARRAY)
            mismatch = true;
        else
        {
            Array* C = static_cast<Array*>(A);
            Array* D = static_cast<Array*>(B);
            a = C->getValueType();
            b = C->getValueType();
            if(a != b)
            {
                interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str());
                return NULL;
            }

            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }
    else if(a == LIST)
    {
        if(b != LIST)
            mismatch = true;
        else
        {
            List* C = static_cast<List*>(A);
            List* D = static_cast<List*>(B);
            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }
    else if(a == FUNCTION)
    {
        if(b != FUNCTION)
            mismatch = true;
        else
        {
            Function* C = static_cast<Function*>(A);
            Function* D = static_cast<Function*>(B);
            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }
    else if(a == PROCEDURE)
    {
        if(b != PROCEDURE)
            mismatch = true;
        else
        {
            Procedure* C = static_cast<Procedure*>(A);
            Procedure* D = static_cast<Procedure*>(B);
            switch(oper)
            {
                case EQUALS:
                    return new Bool(C->getValue() == D->getValue());
                case NOT_GREATER:
                case LESS_EQUAL:
                    return new Bool(C->getValue() <= D->getValue());
                case NOT_LESS:
                case GREATER_EQUAL:
                    return new Bool(C->getValue() >= D->getValue());
                case LESS:
                    return new Bool(C->getValue() < D->getValue());
                case GREATER:
                    return new Bool(C->getValue() > D->getValue());
                case NOT_EQUALS:
                    return new Bool(C->getValue() != D->getValue());
                default:
                    UI_debug_pile("Pile Error: Bad operator passed to comparison().\n");
                    return NULL;
            }
        }
    }

    //if(mismatch)
    {
        interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str());
        return NULL;
    }
    return NULL;
}
예제 #21
0
파일: macro.cpp 프로젝트: damorinCan/cscout
/*
 * Substitute the arguments args appearing in the input sequence is
 * Result is created in the output sequence os and finally has the specified
 * hide set added to it, before getting returned.
 */
static PtokenSequence
subst(const Macro &m, dequePtoken is, const mapArgval &args, HideSet hs, bool skip_defined, const Macro *caller)
{
	PtokenSequence os;	// output sequence

	while (!is.empty()) {
		if (DP())
			cout << "subst: is=" << is << " os=" << os << endl;
		const Ptoken head(is.front());
		is.pop_front();		// is is now the tail
		dequePtoken::iterator ti, ti2;
		mapArgval::const_iterator ai;
		switch (head.get_code()) {
		case '#':		// Stringizing operator
			ti = find_nonspace(is.begin(), is.end());
			if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) {
				is.erase(is.begin(), ++ti);
				os.push_back(stringize(ai->second));
				continue;
			}
			break;
		case CPP_CONCAT:
			ti = find_nonspace(is.begin(), is.end());
			if (ti != is.end()) {
				if ((ai = find_formal_argument(args, *ti)) != args.end()) {
					is.erase(is.begin(), ++ti);
					if (ai->second.size() != 0)	// Only if actuals can be empty
						os = glue(os, ai->second);
				} else {
					PtokenSequence t(ti, ti + 1);
					is.erase(is.begin(), ++ti);
					os = glue(os, t);
				}
				continue;
			}
			break;
		default:
			ti = find_nonspace(is.begin(), is.end());
			if (ti != is.end() && ti->get_code() == CPP_CONCAT) {
				/*
				 * Implement the following gcc extension:
				 *  "`##' before a
				 *   rest argument that is empty discards the preceding sequence of
				 *   non-whitespace characters from the macro definition.  (If another macro
				 *   argument precedes, none of it is discarded.)"
				 * Otherwise, break to process a non-formal argument in the default way
				 */
				if ((ai = find_formal_argument(args, head)) == args.end()) {
					if (m.get_is_vararg()) {
						ti2 = find_nonspace(ti + 1, is.end());
						if (ti2 != is.end() && (ai = find_formal_argument(args, *ti2)) != args.end() && ai->second.size() == 0) {
							// All conditions satisfied; discard elements:
							// <non-formal> <##> <empty-formal>
							is.erase(is.begin(), ++ti2);
							continue;
						}
					}
					break;	// Non-formal arguments don't deserve special treatment
				}
				// Paste but not expand LHS, RHS
				if (ai->second.size() == 0) {	// Only if actuals can be empty
					is.erase(is.begin(), ++ti);	// Erase including ##
					ti = find_nonspace(is.begin(), is.end());
					if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) {
						is.erase(is.begin(), ++ti);	// Erase the ## RHS
						PtokenSequence actual(ai->second);
						os.splice(os.end(), actual);
					}
				} else {
					is.erase(is.begin(), ti);	// Erase up to ##
					PtokenSequence actual(ai->second);
					os.splice(os.end(), actual);
				}
				continue;
			}
			if ((ai = find_formal_argument(args, head)) == args.end())
				break;
			// Othewise expand head
			PtokenSequence expanded(macro_expand(ai->second, false, skip_defined, caller));
			os.splice(os.end(), expanded);
			continue;
		}
		os.push_back(head);
	}
	return (hsadd(hs, os));
}
예제 #22
0
void Lexer::processDefine( Macro& m )
{
    m.setFileName( m_driver->currentFileName() );
    m.setLine( m_currentLine );
    m.setColumn( m_currentColumn );
    readWhiteSpaces( false );

    int startMacroName = currentPosition();
    readIdentifier();
    QString macroName = m_source.mid( startMacroName, int(currentPosition()-startMacroName) );
    m.setName( macroName );

    if( currentChar() == '(' ){
	m.setHasArguments( true );
	nextChar();

        readWhiteSpaces( false );

	while( currentChar() && currentChar() != ')' ){
	    readWhiteSpaces( false );

	    int startArg = currentPosition();

            if( currentChar() == '.' && peekChar() == '.' && peekChar(2) == '.' )
                nextChar( 3 );
            else
	        readIdentifier();

	    QString arg = m_source.mid( startArg, int(currentPosition()-startArg) );

	    m.addArgument( Macro::Argument(arg) );

	    readWhiteSpaces( false );
	    if( currentChar() != ',' )
		break;

	    nextChar(); // skip ','
	}

	if( currentChar() == ')' )
	    nextChar(); // skip ')'
    }

    setPreprocessorEnabled( true );

    QString body;
    while( currentChar() && currentChar() != '\n' ){

        if( currentChar().isSpace() ){
	    readWhiteSpaces( false );
	    body += " ";
	} else {

	    Token tk(m_source);
	    nextToken( tk, true );

    //Do not ignore c-style comments, those may be useful in the body, and ignoring them using this check causes problems
    if( tk.type() != -1 && (tk.type() != Token_comment || ( tk.text().length() >= 2 && tk.text()[1] == '*') ) ){
                QString s = tk.text();
		body += s;
	    }
	}
    }

    m.setBody( body );
    m_driver->addMacro( m );
}
예제 #23
0
void DirectiveParser::parseDefine(Token *token)
{
    assert(getDirective(token) == DIRECTIVE_DEFINE);

    mTokenizer->lex(token);
    if (token->type != Token::IDENTIFIER)
    {
        mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                             token->location, token->text);
        return;
    }
    if (isMacroPredefined(token->text, *mMacroSet))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
                             token->location, token->text);
        return;
    }
    if (isMacroNameReserved(token->text))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED,
                             token->location, token->text);
        return;
    }

    Macro macro;
    macro.type = Macro::kTypeObj;
    macro.name = token->text;

    mTokenizer->lex(token);
    if (token->type == '(' && !token->hasLeadingSpace())
    {
        // Function-like macro. Collect arguments.
        macro.type = Macro::kTypeFunc;
        do
        {
            mTokenizer->lex(token);
            if (token->type != Token::IDENTIFIER)
                break;
            macro.parameters.push_back(token->text);

            mTokenizer->lex(token);  // Get ','.
        }
        while (token->type == ',');

        if (token->type != ')')
        {
            mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                                 token->location,
                                 token->text);
            return;
        }
        mTokenizer->lex(token);  // Get ')'.
    }

    while ((token->type != '\n') && (token->type != Token::LAST))
    {
        // Reset the token location because it is unnecessary in replacement
        // list. Resetting it also allows us to reuse Token::equals() to
        // compare macros.
        token->location = SourceLocation();
        macro.replacements.push_back(*token);
        mTokenizer->lex(token);
    }
    if (!macro.replacements.empty())
    {
        // Whitespace preceding the replacement list is not considered part of
        // the replacement list for either form of macro.
        macro.replacements.front().setHasLeadingSpace(false);
    }

    // Check for macro redefinition.
    MacroSet::const_iterator iter = mMacroSet->find(macro.name);
    if (iter != mMacroSet->end() && !macro.equals(iter->second))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED,
                             token->location,
                             macro.name);
        return;
    }
    mMacroSet->insert(std::make_pair(macro.name, macro));
}
예제 #24
0
Macro *Macro::find(const String& n)
{
    for (Macro *it = next(); !it->isRoot(); it = it->next())
        if (it->_name == n) return it;
    return NULL;
}
const char *MacroExpander::expand(const char *__first, const char *__last,
                                  QByteArray *__result)
{
    const char *start = __first;
    __first = skip_blanks (__first, __last);
    lines = skip_blanks.lines;

    while (__first != __last)
    {
        if (*__first == '\n')
        {
            __result->append("\n# ");
            __result->append(QByteArray::number(env->currentLine));
            __result->append(' ');
            __result->append('"');
            __result->append(env->currentFile.toUtf8());
            __result->append('"');
            __result->append('\n');
            ++lines;

            __first = skip_blanks (++__first, __last);
            lines += skip_blanks.lines;

            if (__first != __last && *__first == '#')
                break;
        }
        else if (*__first == '#')
        {
            __first = skip_blanks (++__first, __last);
            lines += skip_blanks.lines;

            const char *end_id = skip_identifier (__first, __last);
            const QByteArray fast_name(__first, end_id - __first);
            __first = end_id;

            if (const QByteArray *actual = resolve_formal (fast_name))
            {
                __result->append('\"');

                const char *actual_begin = actual->constData ();
                const char *actual_end = actual_begin + actual->size ();

                for (const char *it = skip_whitespaces (actual_begin, actual_end);
                        it != actual_end; ++it)
                {
                    if (*it == '"' || *it == '\\')
                    {
                        __result->append('\\');
                        __result->append(*it);
                    }
                    else if (*it == '\n')
                    {
                        __result->append('"');
                        __result->append('\n');
                        __result->append('"');
                    }
                    else
                        __result->append(*it);
                }

                __result->append('\"');
            }
            else
                __result->append('#'); // ### warning message?
        }
        else if (*__first == '\"')
        {
            const char *next_pos = skip_string_literal (__first, __last);
            lines += skip_string_literal.lines;
            __result->append(__first, next_pos - __first);
            __first = next_pos;
        }
        else if (*__first == '\'')
        {
            const char *next_pos = skip_char_literal (__first, __last);
            lines += skip_char_literal.lines;
            __result->append(__first, next_pos - __first);
            __first = next_pos;
        }
        else if (comment_p (__first, __last))
        {
            __first = skip_comment_or_divop (__first, __last);
            int n = skip_comment_or_divop.lines;
            lines += n;

            while (n-- > 0)
                __result->append('\n');
        }
        else if (pp_isspace (*__first))
        {
            for (; __first != __last; ++__first)
            {
                if (*__first == '\n' || !pp_isspace (*__first))
                    break;
            }

            __result->append(' ');
        }
        else if (pp_isdigit (*__first))
        {
            const char *next_pos = skip_number (__first, __last);
            lines += skip_number.lines;
            __result->append(__first, next_pos - __first);
            __first = next_pos;
        }
        else if (pp_isalpha (*__first) || *__first == '_')
        {
            const char *name_begin = __first;
            const char *name_end = skip_identifier (__first, __last);
            __first = name_end; // advance

            // search for the paste token
            const char *next = skip_blanks (__first, __last);
            bool paste = false;
            if (next != __last && *next == '#')
            {
                paste = true;
                ++next;
                if (next != __last && *next == '#')
                    __first = skip_blanks(++next, __last);
            }

            const QByteArray fast_name(name_begin, name_end - name_begin);

            if (const QByteArray *actual = resolve_formal (fast_name))
            {
                const char *begin = actual->constData ();
                const char *end = begin + actual->size ();
                if (paste) {
                    for (--end; end != begin - 1; --end) {
                        if (! pp_isspace(*end))
                            break;
                    }
                    ++end;
                }
                __result->append(begin, end - begin);
                continue;
            }

            Macro *macro = env->resolve (fast_name);
            if (! macro || macro->isHidden() || env->hideNext)
            {
                if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined")
                    env->hideNext = true;
                else
                    env->hideNext = false;

                if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_')
                {
                    if (fast_name == "__LINE__")
                    {
                        __result->append(QByteArray::number(env->currentLine + lines));
                        continue;
                    }

                    else if (fast_name == "__FILE__")
                    {
                        __result->append('"');
                        __result->append(env->currentFile.toUtf8());
                        __result->append('"');
                        continue;
                    }

                    else if (fast_name == "__DATE__")
                    {
                        __result->append('"');
                        __result->append(QDate::currentDate().toString().toUtf8());
                        __result->append('"');
                        continue;
                    }

                    else if (fast_name == "__TIME__")
                    {
                        __result->append('"');
                        __result->append(QTime::currentTime().toString().toUtf8());
                        __result->append('"');
                        continue;
                    }

                }

                __result->append(name_begin, name_end - name_begin);
                continue;
            }

            if (! macro->isFunctionLike())
            {
                Macro *m = 0;

                if (! macro->definition().isEmpty())
                {
                    macro->setHidden(true);

                    QByteArray __tmp;
                    __tmp.reserve (256);

                    MacroExpander expand_macro (env);
                    expand_macro(macro->definition(), &__tmp);

                    if (! __tmp.isEmpty ())
                    {
                        const char *__tmp_begin = __tmp.constBegin();
                        const char *__tmp_end = __tmp.constEnd();
                        const char *__begin_id = skip_whitespaces (__tmp_begin, __tmp_end);
                        const char *__end_id = skip_identifier (__begin_id, __tmp_end);

                        if (__end_id == __tmp_end)
                        {
                            const QByteArray __id (__begin_id, __end_id - __begin_id);
                            m = env->resolve (__id);
                        }

                        if (! m)
                            *__result += __tmp;
                    }

                    macro->setHidden(false);
                }

                if (! m)
                    continue;

                macro = m;
            }

            // function like macro
            const char *arg_it = skip_whitespaces (__first, __last);

            if (arg_it == __last || *arg_it != '(')
            {
                __result->append(name_begin, name_end - name_begin);
                lines += skip_whitespaces.lines;
                __first = arg_it;
                continue;
            }

            QVector<QByteArray> actuals;
            QVector<MacroArgumentReference> actuals_ref;
            actuals.reserve (5);
            ++arg_it; // skip '('

            MacroExpander expand_actual (env, frame);

            const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
            if (arg_it != arg_end)
            {
                actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it));
                const QByteArray actual (arg_it, arg_end - arg_it);
                QByteArray expanded;
                expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
                actuals.push_back (expanded);
                arg_it = arg_end;
            }

            while (arg_it != __last && *arg_end == ',')
            {
                ++arg_it; // skip ','

                arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
                actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it));
                const QByteArray actual (arg_it, arg_end - arg_it);
                QByteArray expanded;
                expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
                actuals.push_back (expanded);
                arg_it = arg_end;
            }

            if (! (arg_it != __last && *arg_it == ')'))
                return __last;

            ++arg_it; // skip ')'
            __first = arg_it;

            pp_frame frame (macro, actuals);
            MacroExpander expand_macro (env, &frame);
            macro->setHidden(true);
            expand_macro (macro->definition(), __result);
            macro->setHidden(false);
        }
        else
            __result->append(*__first++);
    }

    return __first;
}
예제 #26
0
Variable* assign(Variable* A, Variable* B)
{
    if(A == NULL || B == NULL)
    {
        interpreter.error("Error: Void variable in assignment.\n");
        return NULL;
    }
    if(!A->reference)
    {
        interpreter.error("Error: Assigning value to a non-reference variable.\n");
        return NULL;
    }

    TypeEnum a = A->getType();
    TypeEnum b = B->getType();

    bool mismatch = false;
    if(a == STRING)
    {
        if(b != STRING)
            mismatch = true;
        else
        {
            String* C = static_cast<String*>(A);
            String* D = static_cast<String*>(B);
            C->setValue(D->getValue());
        }
    }
    else if(a == INT)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Int* C = static_cast<Int*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                C->setValue(D->getValue());
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                C->setValue(D->getValue());
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                C->setValue(D->getValue());
            }
        }
    }
    else if(a == FLOAT)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Float* C = static_cast<Float*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                C->setValue(D->getValue());
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                C->setValue(D->getValue());
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                C->setValue(D->getValue());
            }
        }
    }
    else if(a == BOOL)
    {
        if(b != BOOL && b != INT && b != FLOAT)
            mismatch = true;
        else
        {
            Bool* C = static_cast<Bool*>(A);
            if(b == BOOL)
            {
                Bool* D = static_cast<Bool*>(B);
                C->setValue(D->getValue());
            }
            else if(b == INT)
            {
                Int* D = static_cast<Int*>(B);
                C->setValue(D->getValue());
            }
            else
            {
                Float* D = static_cast<Float*>(B);
                C->setValue(D->getValue());
            }
        }
    }
    else if(a == MACRO)
    {
        if(b != MACRO)
            mismatch = true;
        else
        {
            Macro* C = static_cast<Macro*>(A);
            Macro* D = static_cast<Macro*>(B);
            C->setValue(D->getValue());
        }
    }
    else if(a == ARRAY)
    {
        if(b != ARRAY)
            mismatch = true;
        else
        {
            Array* C = static_cast<Array*>(A);
            Array* D = static_cast<Array*>(B);
            a = C->getValueType();
            b = D->getValueType();
            if(a != b)
            {
                interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str());
                return NULL;
            }
            C->setValue(D->getValue());
        }
    }
    else if(a == LIST)
    {
        if(b != LIST)
            mismatch = true;
        else
        {
            List* C = static_cast<List*>(A);
            List* D = static_cast<List*>(B);
            C->setValue(D->getValue());
        }
    }
    else if(a == FUNCTION)
    {
        if(b != FUNCTION)
            mismatch = true;
        else
        {
            Function* C = static_cast<Function*>(A);
            Function* D = static_cast<Function*>(B);
            C->setValue(D->getValue());
        }
    }
    else if(a == PROCEDURE)
    {
        if(b != PROCEDURE)
            mismatch = true;
        else
        {
            Procedure* C = static_cast<Procedure*>(A);
            Procedure* D = static_cast<Procedure*>(B);
            C->setValue(D->getValue());
        }
    }

    if(mismatch)
    {
        interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str());
        return NULL;
    }
    return A;
}
예제 #27
0
Variable* add(Variable* A, Variable* B)
{
    if(A == NULL || B == NULL)
    {
        interpreter.error("Error: Void variable in addition.\n");
        return NULL;
    }
    TypeEnum a = A->getType();
    TypeEnum b = B->getType();
    if(a != b && !(a == FLOAT && b == INT) && !(b == FLOAT && a == INT))
    {
        interpreter.error("Error: Types do not match in addition: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str());
        return NULL;
    }
    if(a == STRING)
    {
        String* C = static_cast<String*>(A);
        String* D = static_cast<String*>(B);
        String* R = new String("<temp>");
        R->setValue(C->getValue() + D->getValue());
        return R;
    }
    else if(a == INT)
    {
        Int* C = static_cast<Int*>(A);
        if(b == INT)
        {
            Int* D = static_cast<Int*>(B);
            Int* R = new Int;
            R->setValue(C->getValue() + D->getValue());
            return R;
        }
        else
        {
            Float* D = static_cast<Float*>(B);
            Float* R = new Float;
            R->setValue(C->getValue() + D->getValue());
            return R;
        }
    }
    else if(a == FLOAT)
    {
        Float* C = static_cast<Float*>(A);
        Float* R = new Float;

        if(b == INT)
        {
            Int* D = static_cast<Int*>(B);
            R->setValue(C->getValue() + D->getValue());
        }
        else
        {
            Float* D = static_cast<Float*>(B);
            R->setValue(C->getValue() + D->getValue());
        }
        return R;
    }
    else if(a == BOOL)
    {
        interpreter.error("Error: Addition operation not defined for type 'bool'.\n");
        return NULL;
    }
    else if(a == MACRO)
    {
        Macro* C = static_cast<Macro*>(A);
        Macro* D = static_cast<Macro*>(B);
        Macro* R = new Macro;
        R->setValue(C->getValue() + D->getValue());
        return R;
    }
    else if(a == ARRAY)
    {
        Array* C = static_cast<Array*>(A);
        Array* D = static_cast<Array*>(B);
        a = C->getValueType();
        b = D->getValueType();
        if(a != b)
        {
            interpreter.error("Error: Types do not match in addition: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str());
            return NULL;
        }

        vector<Variable*> va = C->getValue();
        vector<Variable*>& vb = D->getValue();

        for(vector<Variable*>::iterator e = vb.begin(); e != vb.end(); e++)
        {
            va.push_back(*e);
        }

        Array* arr = new Array("<temp>", va, a);

        return arr;
    }
    else if(a == LIST)
    {
        List* C = static_cast<List*>(A);
        List* D = static_cast<List*>(B);
        list<Variable*> va = C->getValue();
        list<Variable*>& vb = D->getValue();

        for(list<Variable*>::iterator e = vb.begin(); e != vb.end(); e++)
        {
            va.push_back(*e);
        }

        List* lst = new List("<temp>", va);

        return lst;
    }
    else if(a == FUNCTION)
    {
        Function* C = static_cast<Function*>(A);
        Function* D = static_cast<Function*>(B);
        Function* R = new Function("<temp>", FN_NONE);
        R->setValue(C->getValue() + D->getValue());
        return R;
    }
    else if(a == PROCEDURE)
    {
        Procedure* C = static_cast<Procedure*>(A);
        Procedure* D = static_cast<Procedure*>(B);
        Procedure* R = new Procedure("<temp>");
        R->setValue(C->getValue() + D->getValue());
        return R;
    }
    return A;
}
예제 #28
0
void Driver::addMacro( const Macro & macro )
{
    m_macros.insert( macro.name(), macro );
}
예제 #29
0
   Macro 
   MacroParser::Parse()
   {
      if (_macroString.StartsWith(_T("HM_DROP_COLUMN_OBJECTS")))
      {
         int pos = _macroString.Find(_T(" "));

         String columnSpecifier = _macroString.Mid(pos);

         int separator = columnSpecifier.Find(_T("."));

         String tableName = columnSpecifier.Mid(0, separator);
         String columnName = columnSpecifier.Mid(separator+1);

         tableName.Trim();
         columnName.Trim();

         Macro macro;
         macro.SetType(Macro::DropColumnKeys);
         macro.SetTableName(tableName);
         macro.SetColumnName(columnName);

         return macro;
      }
      else if (_macroString == _T("UPDATE_MESSAGES_SET_FOLDER_INBOX"))
      {
         Macro macro;
         macro.SetType(Macro::SQLCEUPDATE_MESSAGES_SET_FOLDER_INBOX);
         return macro;
      }
      else if (_macroString == _T("UPDATE_FOLDERS_SET_CURRENT_UID"))
      {
         Macro macro;
         macro.SetType(Macro::SQLCEUPDATE_FOLDERS_SET_CURRENT_UID);
         return macro;
      }
      else if (_macroString == _T("UPDATE_FOLDERS_SET_NEW_PARENTFOLDERID_WHERE_ZERO"))
      {
         Macro macro;
         macro.SetType(Macro::SQLCEUPDATE_FOLDERS_SET_NEW_PARENTFOLDERID_WHERE_ZERO);
         
         return macro;
      }
      else if (_macroString == _T("SQLCE_UPDATE_IMAP_HIERARCHY_DELIMITER"))
      {
         Macro macro;
         macro.SetType(Macro::SQLCE_UPDATE_IMAP_HIERARCHY_DELIMITER);

         return macro;
      }
      
      Macro unknownMacro;
      return unknownMacro;
   }
예제 #30
0
void DirectiveParser::parseDefine(Token *token)
{
    assert(getDirective(token) == DIRECTIVE_DEFINE);

    mTokenizer->lex(token);
    if (token->type != Token::IDENTIFIER)
    {
        mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                             token->location, token->text);
        return;
    }
    if (isMacroPredefined(token->text, *mMacroSet))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
                             token->location, token->text);
        return;
    }
    if (isMacroNameReserved(token->text))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED,
                             token->location, token->text);
        return;
    }
    // Using double underscores is allowed, but may result in unintended
    // behavior, so a warning is issued. At the time of writing this was
    // specified in ESSL 3.10, but the intent judging from Khronos
    // discussions and dEQP tests was that double underscores should be
    // allowed in earlier ESSL versions too.
    if (hasDoubleUnderscores(token->text))
    {
        mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location,
                             token->text);
    }

    Macro macro;
    macro.type = Macro::kTypeObj;
    macro.name = token->text;

    mTokenizer->lex(token);
    if (token->type == '(' && !token->hasLeadingSpace())
    {
        // Function-like macro. Collect arguments.
        macro.type = Macro::kTypeFunc;
        do
        {
            mTokenizer->lex(token);
            if (token->type != Token::IDENTIFIER)
                break;

            if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())
            {
                mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES,
                                     token->location, token->text);
                return;
            }

            macro.parameters.push_back(token->text);

            mTokenizer->lex(token);  // Get ','.
        }
        while (token->type == ',');

        if (token->type != ')')
        {
            mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                                 token->location,
                                 token->text);
            return;
        }
        mTokenizer->lex(token);  // Get ')'.
    }

    while ((token->type != '\n') && (token->type != Token::LAST))
    {
        // Reset the token location because it is unnecessary in replacement
        // list. Resetting it also allows us to reuse Token::equals() to
        // compare macros.
        token->location = SourceLocation();
        macro.replacements.push_back(*token);
        mTokenizer->lex(token);
    }
    if (!macro.replacements.empty())
    {
        // Whitespace preceding the replacement list is not considered part of
        // the replacement list for either form of macro.
        macro.replacements.front().setHasLeadingSpace(false);
    }

    // Check for macro redefinition.
    MacroSet::const_iterator iter = mMacroSet->find(macro.name);
    if (iter != mMacroSet->end() && !macro.equals(iter->second))
    {
        mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED,
                             token->location,
                             macro.name);
        return;
    }
    mMacroSet->insert(std::make_pair(macro.name, macro));
}