From 5cf3264bd376edc77c2226bf585d85bd7e7acaaf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 28 Jun 2010 16:48:19 +0200 Subject: [PATCH] added literal container and reworked output container handling --- CMakeLists.txt | 3 +- components/compiler/fileparser.cpp | 1 - components/compiler/fileparser.hpp | 3 +- components/compiler/lineparser.cpp | 5 +- components/compiler/lineparser.hpp | 4 +- components/compiler/literals.cpp | 94 ++++++++++++++++++++++++++++ components/compiler/literals.hpp | 49 +++++++++++++++ components/compiler/output.cpp | 74 ++++++++++++++++++++++ components/compiler/output.hpp | 44 +++++++++++++ components/compiler/scriptparser.cpp | 9 +-- components/compiler/scriptparser.hpp | 9 +-- components/interpreter/types.hpp | 5 ++ 12 files changed, 284 insertions(+), 16 deletions(-) create mode 100644 components/compiler/literals.cpp create mode 100644 components/compiler/literals.hpp create mode 100644 components/compiler/output.cpp create mode 100644 components/compiler/output.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c3a14278e..98a0b5d52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,8 @@ set(COMPILER components/compiler/errorhandler.cpp components/compiler/lineparser.cpp components/compiler/skipparser.cpp components/compiler/parser.cpp components/compiler/scanner.cpp components/compiler/streamerrorhandler.cpp - components/compiler/locals.cpp) + components/compiler/locals.cpp components/compiler/literals.cpp + components/compiler/output.cpp) file(GLOB COMPILER_HEADER components/compiler/*.hpp) source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER}) diff --git a/components/compiler/fileparser.cpp b/components/compiler/fileparser.cpp index caf44f749..f8b3d0e61 100644 --- a/components/compiler/fileparser.cpp +++ b/components/compiler/fileparser.cpp @@ -98,7 +98,6 @@ namespace Compiler mState = BeginState; mName.clear(); mScriptParser.reset(); - mLocals.clear(); } } diff --git a/components/compiler/fileparser.hpp b/components/compiler/fileparser.hpp index b9239841f..13c7fb537 100644 --- a/components/compiler/fileparser.hpp +++ b/components/compiler/fileparser.hpp @@ -4,6 +4,7 @@ #include "parser.hpp" #include "scriptparser.hpp" #include "locals.hpp" +#include "literals.hpp" namespace Compiler { @@ -21,7 +22,7 @@ namespace Compiler State mState; std::string mName; Locals mLocals; - + public: FileParser (ErrorHandler& errorHandler, Context& context); diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 7baf81f24..d88680edc 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -10,8 +10,9 @@ namespace Compiler { LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals, - std::vector& code) - : Parser (errorHandler, context), mLocals (locals), mCode (code), mState (BeginState) + Literals& literals, std::vector& code) + : Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code), + mState (BeginState) {} bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) diff --git a/components/compiler/lineparser.hpp b/components/compiler/lineparser.hpp index d7840af71..43d79883d 100644 --- a/components/compiler/lineparser.hpp +++ b/components/compiler/lineparser.hpp @@ -10,6 +10,7 @@ namespace Compiler { class Locals; + class Literals; /// \brief Line parser, to be used in console scripts and as part of ScriptParser @@ -23,13 +24,14 @@ namespace Compiler }; Locals& mLocals; + Literals& mLiterals; std::vector& mCode; State mState; public: LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals, - std::vector& code); + Literals& literals, std::vector& code); virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); ///< Handle an int token. diff --git a/components/compiler/literals.cpp b/components/compiler/literals.cpp new file mode 100644 index 000000000..626b03afb --- /dev/null +++ b/components/compiler/literals.cpp @@ -0,0 +1,94 @@ + +#include "literals.hpp" + +#include + +namespace Compiler +{ + int Literals::getIntegerSize() const + { + return mIntegers.size() * sizeof (Interpreter::Type_Integer); + } + + int Literals::getFloatSize() const + { + return mFloats.size() * sizeof (Interpreter::Type_Float); + } + + int Literals::getStringSize() const + { + int size = 0; + + for (std::vector::const_iterator iter (mStrings.begin()); + iter!=mStrings.end(); ++iter) + size += static_cast (iter->size()) + 1; + + if (size % 4) // padding + size += 4 - size % 4; + + return size; + } + + void Literals::append (std::vector& code) const + { + for (std::vector::const_iterator iter (mIntegers.begin()); + iter!=mIntegers.end(); ++iter) + code.push_back (*reinterpret_cast (&*iter)); + + for (std::vector::const_iterator iter (mFloats.begin()); + iter!=mFloats.end(); ++iter) + code.push_back (*reinterpret_cast (&*iter)); + + int stringBlockSize = getStringSize(); + int size = static_cast (code.size()); + + code.resize (size+stringBlockSize/4); + + int offset = 0; + + for (std::vector::const_iterator iter (mStrings.begin()); + iter!=mStrings.end(); ++iter) + { + int stringSize = iter->size()+1; + + std::copy (iter->c_str(), iter->c_str()+stringSize, + reinterpret_cast (&code[size]) + offset); + offset += stringSize; + } + } + + int Literals::addInteger (Interpreter::Type_Integer value) + { + int index = static_cast (mIntegers.size()); + + mIntegers.push_back (value); + + return index; + } + + int Literals::addFloat (Interpreter::Type_Float value) + { + int index = static_cast (mFloats.size()); + + mFloats.push_back (value); + + return index; + } + + int Literals::addString (const std::string& value) + { + int index = static_cast (mStrings.size()); + + mStrings.push_back (value); + + return index; + } + + void Literals::clear() + { + mIntegers.clear(); + mFloats.clear(); + mStrings.clear(); + } +} + diff --git a/components/compiler/literals.hpp b/components/compiler/literals.hpp new file mode 100644 index 000000000..b18c86479 --- /dev/null +++ b/components/compiler/literals.hpp @@ -0,0 +1,49 @@ +#ifndef COMPILER_LITERALS_H_INCLUDED +#define COMPILER_LITERALS_H_INCLUDED + +#include +#include + +#include + +namespace Compiler +{ + /// \brief Literal values. + + class Literals + { + std::vector mIntegers; + std::vector mFloats; + std::vector mStrings; + + public: + + int getIntegerSize() const; + ///< Return size of integer block (in bytes). + + int getFloatSize() const; + ///< Return size of float block (in bytes). + + int getStringSize() const; + ///< Return size of string block (in bytes). + + void append (std::vector& code) const; + ///< Apepnd literal blocks to code. + /// \note code blocks will be padded for 32-bit alignment. + + int addInteger (Interpreter::Type_Integer value); + ///< add integer liternal and return index. + + int addFloat (Interpreter::Type_Float value); + ///< add float literal and return value. + + int addString (const std::string& value); + ///< add string literal and return value. + + void clear(); + ///< remove all literals. + }; +} + +#endif + diff --git a/components/compiler/output.cpp b/components/compiler/output.cpp new file mode 100644 index 000000000..46e04b8dc --- /dev/null +++ b/components/compiler/output.cpp @@ -0,0 +1,74 @@ + +#include "output.hpp" + +#include +#include +#include + +#include "locals.hpp" + +namespace Compiler +{ + Output::Output (Locals& locals) : mLocals (locals) {} + + void Output::getCode (std::vector& code) const + { + code.clear(); + + // header + code.push_back (static_cast (mCode.size())); + + assert (mLiterals.getIntegerSize()%4==0); + code.push_back (static_cast (mLiterals.getIntegerSize()/4)); + + assert (mLiterals.getFloatSize()%4==0); + code.push_back (static_cast (mLiterals.getFloatSize()/4)); + + assert (mLiterals.getStringSize()%4==0); + code.push_back (static_cast (mLiterals.getStringSize()/4)); + + // code + std::copy (mCode.begin(), mCode.end(), std::back_inserter (code)); + + // literals + mLiterals.append (code); + } + + const Literals& Output::getLiterals() const + { + return mLiterals; + } + + const std::vector& Output::getCode() const + { + return mCode; + } + + const Locals& Output::getLocals() const + { + return mLocals; + } + + Literals& Output::getLiterals() + { + return mLiterals; + } + + std::vector& Output::getCode() + { + return mCode; + } + + Locals& Output::getLocals() + { + return mLocals; + } + + void Output::clear() + { + mLiterals.clear(); + mCode.clear(); + mLocals.clear(); + } +} + diff --git a/components/compiler/output.hpp b/components/compiler/output.hpp new file mode 100644 index 000000000..37b88cee9 --- /dev/null +++ b/components/compiler/output.hpp @@ -0,0 +1,44 @@ +#ifndef COMPILER_OUTPUT_H_INCLUDED +#define COMPILER_OUTPUT_H_INCLUDED + +#include "literals.hpp" + +#include + +#include + +namespace Compiler +{ + class Locals; + + class Output + { + Literals mLiterals; + std::vector mCode; + Locals& mLocals; + + public: + + Output (Locals& locals); + + void getCode (std::vector& code) const; + ///< store generated code in \æ code. + + const Literals& getLiterals() const; + + const Locals& getLocals() const; + + const std::vector& getCode() const; + + Literals& getLiterals(); + + std::vector& getCode(); + + Locals& getLocals(); + + void clear(); + }; +} + +#endif + diff --git a/components/compiler/scriptparser.cpp b/components/compiler/scriptparser.cpp index 338f4aecf..d3d32af89 100644 --- a/components/compiler/scriptparser.cpp +++ b/components/compiler/scriptparser.cpp @@ -7,13 +7,14 @@ namespace Compiler { ScriptParser::ScriptParser (ErrorHandler& errorHandler, Context& context, Locals& locals, bool end) - : Parser (errorHandler, context), mLineParser (errorHandler, context, locals, mCode), - mLocals (locals), mEnd (end) + : Parser (errorHandler, context), mOutput (locals), + mLineParser (errorHandler, context, locals, mOutput.getLiterals(), mOutput.getCode()), + mEnd (end) {} void ScriptParser::getCode (std::vector& code) const { - code = mCode; + mOutput.getCode (code); } bool ScriptParser::parseName (const std::string& name, const TokenLoc& loc, @@ -61,7 +62,7 @@ namespace Compiler void ScriptParser::reset() { mLineParser.reset(); - mCode.clear(); + mOutput.clear(); } } diff --git a/components/compiler/scriptparser.hpp b/components/compiler/scriptparser.hpp index dd31f0217..dd4e38511 100644 --- a/components/compiler/scriptparser.hpp +++ b/components/compiler/scriptparser.hpp @@ -1,12 +1,10 @@ #ifndef COMPILER_SCRIPTPARSER_H_INCLUDED #define COMPILER_SCRIPTPARSER_H_INCLUDED -#include - -#include #include "parser.hpp" #include "lineparser.hpp" +#include "output.hpp" namespace Compiler { @@ -16,11 +14,10 @@ namespace Compiler class ScriptParser : public Parser { + Output mOutput; LineParser mLineParser; - Locals& mLocals; bool mEnd; - std::vector mCode; - + public: /// \param end of script is marked by end keyword. diff --git a/components/interpreter/types.hpp b/components/interpreter/types.hpp index 8ae59b115..4189914d6 100644 --- a/components/interpreter/types.hpp +++ b/components/interpreter/types.hpp @@ -5,6 +5,11 @@ namespace Interpreter { typedef unsigned int Type_Code; // 32 bit + typedef unsigned int Type_Data; // 32 bit + + typedef unsigned int Type_Integer; // 32 bit + + typedef unsigned int Type_Float; // 32 bit } #endif