Merge branch 'script'

actorid
Marc Zinnschlag 12 years ago
commit 5bfa691f14

@ -22,7 +22,7 @@ opencs_units (model/world
opencs_units_noqt (model/world opencs_units_noqt (model/world
universalid data record idcollection commands columnbase universalid data record idcollection commands columnbase scriptcontext
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world
@ -55,11 +55,11 @@ opencs_hdrs_noqt (view/doc
opencs_units (view/world opencs_units (view/world
table tablesubview table tablesubview scriptsubview
) )
opencs_units_noqt (view/world opencs_units_noqt (view/world
dialoguesubview util subviews enumdelegate vartypedelegate dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter
) )

@ -35,7 +35,8 @@ namespace CSMWorld
Display_Specialisation, Display_Specialisation,
Display_Attribute, Display_Attribute,
Display_Boolean, Display_Boolean,
Display_SpellType Display_SpellType,
Display_Script
}; };
std::string mTitle; std::string mTitle;

@ -723,6 +723,31 @@ namespace CSMWorld
return true; return true;
} }
}; };
template<typename ESXRecordT>
struct ScriptColumn : public Column<ESXRecordT>
{
ScriptColumn() : Column<ESXRecordT> ("Script", ColumnBase::Display_Script, 0) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return QString::fromUtf8 (record.get().mScriptText.c_str());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mScriptText = data.toString().toUtf8().constData();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
} }
#endif #endif

@ -33,11 +33,13 @@ CSMWorld::Data::Data()
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>); mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>); mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst)); mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType)); mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>); mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
mSkills.addColumn (new StringIdColumn<ESM::Skill>); mSkills.addColumn (new StringIdColumn<ESM::Skill>);
mSkills.addColumn (new RecordStateColumn<ESM::Skill>); mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
mSkills.addColumn (new FixedRecordTypeColumn<ESM::Skill> (UniversalId::Type_Skill));
mSkills.addColumn (new AttributeColumn<ESM::Skill>); mSkills.addColumn (new AttributeColumn<ESM::Skill>);
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>); mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
@ -46,6 +48,7 @@ CSMWorld::Data::Data()
mClasses.addColumn (new StringIdColumn<ESM::Class>); mClasses.addColumn (new StringIdColumn<ESM::Class>);
mClasses.addColumn (new RecordStateColumn<ESM::Class>); mClasses.addColumn (new RecordStateColumn<ESM::Class>);
mClasses.addColumn (new FixedRecordTypeColumn<ESM::Class> (UniversalId::Type_Class));
mClasses.addColumn (new NameColumn<ESM::Class>); mClasses.addColumn (new NameColumn<ESM::Class>);
mClasses.addColumn (new AttributesColumn<ESM::Class> (0)); mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
mClasses.addColumn (new AttributesColumn<ESM::Class> (1)); mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
@ -59,6 +62,7 @@ CSMWorld::Data::Data()
mFactions.addColumn (new StringIdColumn<ESM::Faction>); mFactions.addColumn (new StringIdColumn<ESM::Faction>);
mFactions.addColumn (new RecordStateColumn<ESM::Faction>); mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction));
mFactions.addColumn (new NameColumn<ESM::Faction>); mFactions.addColumn (new NameColumn<ESM::Faction>);
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0)); mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1)); mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
@ -68,6 +72,7 @@ CSMWorld::Data::Data()
mRaces.addColumn (new StringIdColumn<ESM::Race>); mRaces.addColumn (new StringIdColumn<ESM::Race>);
mRaces.addColumn (new RecordStateColumn<ESM::Race>); mRaces.addColumn (new RecordStateColumn<ESM::Race>);
mRaces.addColumn (new FixedRecordTypeColumn<ESM::Race> (UniversalId::Type_Race));
mRaces.addColumn (new NameColumn<ESM::Race>); mRaces.addColumn (new NameColumn<ESM::Race>);
mRaces.addColumn (new DescriptionColumn<ESM::Race>); mRaces.addColumn (new DescriptionColumn<ESM::Race>);
mRaces.addColumn (new FlagColumn<ESM::Race> ("Playable", 0x1)); mRaces.addColumn (new FlagColumn<ESM::Race> ("Playable", 0x1));
@ -79,6 +84,7 @@ CSMWorld::Data::Data()
mSounds.addColumn (new StringIdColumn<ESM::Sound>); mSounds.addColumn (new StringIdColumn<ESM::Sound>);
mSounds.addColumn (new RecordStateColumn<ESM::Sound>); mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
mSounds.addColumn (new FixedRecordTypeColumn<ESM::Sound> (UniversalId::Type_Sound));
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume)); mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange)); mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange)); mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
@ -86,21 +92,26 @@ CSMWorld::Data::Data()
mScripts.addColumn (new StringIdColumn<ESM::Script>); mScripts.addColumn (new StringIdColumn<ESM::Script>);
mScripts.addColumn (new RecordStateColumn<ESM::Script>); mScripts.addColumn (new RecordStateColumn<ESM::Script>);
mScripts.addColumn (new FixedRecordTypeColumn<ESM::Script> (UniversalId::Type_Script));
mScripts.addColumn (new ScriptColumn<ESM::Script>);
mRegions.addColumn (new StringIdColumn<ESM::Region>); mRegions.addColumn (new StringIdColumn<ESM::Region>);
mRegions.addColumn (new RecordStateColumn<ESM::Region>); mRegions.addColumn (new RecordStateColumn<ESM::Region>);
mRegions.addColumn (new FixedRecordTypeColumn<ESM::Region> (UniversalId::Type_Region));
mRegions.addColumn (new NameColumn<ESM::Region>); mRegions.addColumn (new NameColumn<ESM::Region>);
mRegions.addColumn (new MapColourColumn<ESM::Region>); mRegions.addColumn (new MapColourColumn<ESM::Region>);
mRegions.addColumn (new SleepListColumn<ESM::Region>); mRegions.addColumn (new SleepListColumn<ESM::Region>);
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>); mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>); mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
mBirthsigns.addColumn (new FixedRecordTypeColumn<ESM::BirthSign> (UniversalId::Type_Birthsign));
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>); mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>); mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>); mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
mSpells.addColumn (new StringIdColumn<ESM::Spell>); mSpells.addColumn (new StringIdColumn<ESM::Spell>);
mSpells.addColumn (new RecordStateColumn<ESM::Spell>); mSpells.addColumn (new RecordStateColumn<ESM::Spell>);
mSpells.addColumn (new FixedRecordTypeColumn<ESM::Spell> (UniversalId::Type_Spell));
mSpells.addColumn (new NameColumn<ESM::Spell>); mSpells.addColumn (new NameColumn<ESM::Spell>);
mSpells.addColumn (new SpellTypeColumn<ESM::Spell>); mSpells.addColumn (new SpellTypeColumn<ESM::Spell>);
mSpells.addColumn (new CostColumn<ESM::Spell>); mSpells.addColumn (new CostColumn<ESM::Spell>);

@ -0,0 +1,22 @@
#include "scriptcontext.hpp"
bool CSMWorld::ScriptContext::canDeclareLocals() const
{
return false;
}
char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const
{
return ' ';
}
char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std::string& id) const
{
return ' ';
}
bool CSMWorld::ScriptContext::isId (const std::string& name) const
{
return false;
}

@ -0,0 +1,26 @@
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
#define CSM_WORLD_SCRIPTCONTEXT_H
#include <components/compiler/context.hpp>
namespace CSMWorld
{
class ScriptContext : public Compiler::Context
{
public:
virtual bool canDeclareLocals() const;
///< Is the compiler allowed to declare local variables?
virtual char getGlobalType (const std::string& name) const;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual char getMemberType (const std::string& name, const std::string& id) const;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual bool isId (const std::string& name) const;
///< Does \a name match an ID, that can be referenced?
};
}
#endif

@ -0,0 +1,118 @@
#include "scripthighlighter.hpp"
#include <sstream>
#include <components/compiler/scanner.hpp>
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner)
{
highlight (loc, Type_Int);
return true;
}
bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner)
{
highlight (loc, Type_Float);
return true;
}
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner)
{
highlight (loc, Type_Name);
return true;
}
bool CSVWorld::ScriptHighlighter::parseKeyword (int keyword, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner)
{
highlight (loc, Type_Keyword);
return true;
}
bool CSVWorld::ScriptHighlighter::parseSpecial (int code, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner)
{
highlight (loc, Type_Special);
return true;
}
bool CSVWorld::ScriptHighlighter::parseComment (const std::string& comment,
const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight (loc, Type_Comment);
return true;
}
void CSVWorld::ScriptHighlighter::parseEOF (Compiler::Scanner& scanner)
{}
void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type type)
{
int length = static_cast<int> (loc.mLiteral.size());
int index = loc.mColumn;
// compensate for bug in Compiler::Scanner (position of token is the character after the token)
index -= length;
setFormat (index, length, mScheme[type]);
}
CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext)
{
/// \ŧodo replace this with user settings
{
QTextCharFormat format;
format.setForeground (Qt::darkMagenta);
mScheme.insert (std::make_pair (Type_Int, format));
}
{
QTextCharFormat format;
format.setForeground (Qt::magenta);
mScheme.insert (std::make_pair (Type_Float, format));
}
{
QTextCharFormat format;
format.setForeground (Qt::gray);
mScheme.insert (std::make_pair (Type_Name, format));
}
{
QTextCharFormat format;
format.setForeground (Qt::red);
mScheme.insert (std::make_pair (Type_Keyword, format));
}
{
QTextCharFormat format;
format.setForeground (Qt::darkYellow);
mScheme.insert (std::make_pair (Type_Special, format));
}
{
QTextCharFormat format;
format.setForeground (Qt::green);
mScheme.insert (std::make_pair (Type_Comment, format));
}
}
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
{
std::istringstream stream (text.toUtf8().constData());
Compiler::Scanner scanner (mErrorHandler, stream, mContext.getExtensions());
try
{
scanner.scan (*this);
}
catch (...) {} // ignore syntax errors
}

@ -0,0 +1,80 @@
#ifndef CSV_WORLD_SCRIPTHIGHLIGHTER_H
#define CSV_WORLD_SCRIPTHIGHLIGHTER_H
#include <map>
#include <QSyntaxHighlighter>
#include <components/compiler/nullerrorhandler.hpp>
#include <components/compiler/parser.hpp>
#include "../../model/world/scriptcontext.hpp"
namespace CSVWorld
{
class ScriptHighlighter : public QSyntaxHighlighter, private Compiler::Parser
{
public:
enum Type
{
Type_Int,
Type_Float,
Type_Name,
Type_Keyword,
Type_Special,
Type_Comment
};
private:
Compiler::NullErrorHandler mErrorHandler;
CSMWorld::ScriptContext mContext;
std::map<Type, QTextCharFormat> mScheme;
private:
virtual bool parseInt (int value, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner);
///< Handle an int token.
/// \return fetch another token?
virtual bool parseFloat (float value, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner);
///< Handle a float token.
/// \return fetch another token?
virtual bool parseName (const std::string& name,
const Compiler::TokenLoc& loc, Compiler::Scanner& scanner);
///< Handle a name token.
/// \return fetch another token?
virtual bool parseKeyword (int keyword, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner);
///< Handle a keyword token.
/// \return fetch another token?
virtual bool parseSpecial (int code, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner);
///< Handle a special character token.
/// \return fetch another token?
virtual bool parseComment (const std::string& comment, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner);
///< Handle comment token.
/// \return fetch another token?
virtual void parseEOF (Compiler::Scanner& scanner);
///< Handle EOF token.
void highlight (const Compiler::TokenLoc& loc, Type type);
public:
ScriptHighlighter (QTextDocument *parent);
virtual void highlightBlock (const QString& text);
};
}
#endif

@ -0,0 +1,99 @@
#include "scriptsubview.hpp"
#include <stdexcept>
#include <QTextEdit>
#include "../../model/doc/document.hpp"
#include "../../model/world/universalid.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/columnbase.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/idtable.hpp"
#include "scripthighlighter.hpp"
CSVWorld::ScriptSubView::ChangeLock::ChangeLock (ScriptSubView& view) : mView (view)
{
++mView.mChangeLocked;
}
CSVWorld::ScriptSubView::ChangeLock::~ChangeLock()
{
--mView.mChangeLocked;
}
CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id), mDocument (document), mColumn (-1), mChangeLocked (0)
{
setWidget (mEditor = new QTextEdit (this));
mEditor->setAcceptRichText (false);
mEditor->setLineWrapMode (QTextEdit::NoWrap);
mEditor->setTabStopWidth (4);
mEditor->setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead
mModel = &dynamic_cast<CSMWorld::IdTable&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts));
for (int i=0; i<mModel->columnCount(); ++i)
if (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display)==
CSMWorld::ColumnBase::Display_Script)
{
mColumn = i;
break;
}
if (mColumn==-1)
throw std::logic_error ("Can't find script column");
mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString());
connect (mEditor, SIGNAL (textChanged()), this, SLOT (textChanged()));
connect (mModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
new ScriptHighlighter (mEditor->document());
}
void CSVWorld::ScriptSubView::setEditLock (bool locked)
{
mEditor->setReadOnly (locked);
}
void CSVWorld::ScriptSubView::textChanged()
{
ChangeLock lock (*this);
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
mModel->getModelIndex (getUniversalId().getId(), mColumn), mEditor->toPlainText()));
}
void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (mChangeLocked)
return;
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
index.column()>=topLeft.column() && index.column()<=bottomRight.column())
{
QTextCursor cursor = mEditor->textCursor();
mEditor->setPlainText (mModel->data (index).toString());
mEditor->setTextCursor (cursor);
}
}
void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end)
{
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
if (!parent.isValid() && index.row()>=start && index.row()<=end)
deleteLater();
}

@ -0,0 +1,62 @@
#ifndef CSV_WORLD_SCRIPTSUBVIEW_H
#define CSV_WORLD_SCRIPTSUBVIEW_H
#include "../doc/subview.hpp"
class QTextEdit;
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
class IdTable;
}
namespace CSVWorld
{
class ScriptSubView : public CSVDoc::SubView
{
Q_OBJECT
QTextEdit *mEditor;
CSMDoc::Document& mDocument;
CSMWorld::IdTable *mModel;
int mColumn;
int mChangeLocked;
class ChangeLock
{
ScriptSubView& mView;
ChangeLock (const ChangeLock&);
ChangeLock& operator= (const ChangeLock&);
public:
ChangeLock (ScriptSubView& view);
~ChangeLock();
};
friend class ChangeLock;
public:
ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
virtual void setEditLock (bool locked);
private slots:
void textChanged();
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
};
}
#endif

@ -5,6 +5,7 @@
#include "tablesubview.hpp" #include "tablesubview.hpp"
#include "dialoguesubview.hpp" #include "dialoguesubview.hpp"
#include "scriptsubview.hpp"
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{ {
@ -32,6 +33,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i) for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i)
manager.add (sTableTypes[i], new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true)); manager.add (sTableTypes[i], new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>);
// manager.add (CSMWorld::UniversalId::Type_Global, // manager.add (CSMWorld::UniversalId::Type_Global,
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true)); // new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));

@ -21,6 +21,5 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index) void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
{ {
/// \todo re-enable, after dialogue sub views have been fixed up focusId (mTable->getUniversalId (index.row()));
// focusId (mTable->getUniversalId (index.row()));
} }

@ -54,7 +54,7 @@ add_component_dir (files
add_component_dir (compiler add_component_dir (compiler
context controlparser errorhandler exception exprparser extensions fileparser generator context controlparser errorhandler exception exprparser extensions fileparser generator
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
stringparser tokenloc stringparser tokenloc nullerrorhandler
) )
add_component_dir (interpreter add_component_dir (interpreter

@ -0,0 +1,6 @@
#include "nullerrorhandler.hpp"
void Compiler::NullErrorHandler::report (const std::string& message, const TokenLoc& loc, Type type) {}
void Compiler::NullErrorHandler::report (const std::string& message, Type type) {}

@ -0,0 +1,21 @@
#ifndef COMPILER_NULLERRORHANDLER_H_INCLUDED
#define COMPILER_NULLERRORHANDLER_H_INCLUDED
#include "errorhandler.hpp"
namespace Compiler
{
/// \brief Error handler implementation: Ignore all error messages
class NullErrorHandler : public ErrorHandler
{
virtual void report (const std::string& message, const TokenLoc& loc, Type type);
///< Report error to the user.
virtual void report (const std::string& message, Type type);
///< Report a file related error
};
}
#endif

@ -148,6 +148,11 @@ namespace Compiler
return false; return false;
} }
bool Parser::parseComment (const std::string& comment, const TokenLoc& loc, Scanner& scanner)
{
return true;
}
// Handle an EOF token. // Handle an EOF token.
// //
// - Default-implementation: Report an error. // - Default-implementation: Report an error.

@ -82,6 +82,13 @@ namespace Compiler
/// ///
/// - Default-implementation: Report an error. /// - Default-implementation: Report an error.
virtual bool parseComment (const std::string& comment, const TokenLoc& loc,
Scanner& scanner);
///< Handle comment token.
/// \return fetch another token?
///
/// - Default-implementation: ignored (and return true).
virtual void parseEOF (Scanner& scanner); virtual void parseEOF (Scanner& scanner);
///< Handle EOF token. ///< Handle EOF token.
/// ///

@ -88,6 +88,10 @@ namespace Compiler
} }
else if (c==';') else if (c==';')
{ {
std::string comment;
comment += c;
while (get (c)) while (get (c))
{ {
if (c=='\n') if (c=='\n')
@ -95,11 +99,14 @@ namespace Compiler
putback (c); putback (c);
break; break;
} }
else
comment += c;
} }
TokenLoc loc (mLoc);
mLoc.mLiteral.clear(); mLoc.mLiteral.clear();
return true; return parser.parseComment (comment, loc, *this);
} }
else if (isWhitespace (c)) else if (isWhitespace (c))
{ {

Loading…
Cancel
Save