reimplemented expression parsing as a separate parser (still only handling non-negative integers)

actorid
Marc Zinnschlag 15 years ago
parent 10cb9d3dab
commit bceb7ebcbd

@ -66,18 +66,11 @@ set(MISC_HEADER components/misc/fileops.hpp components/misc/slice_array.hpp
components/misc/stringops.hpp)
source_group(misc FILES ${MISC} ${MISC_HEADER})
set(COMPILER components/compiler/errorhandler.cpp
components/compiler/fileparser.cpp components/compiler/scriptparser.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/literals.cpp
components/compiler/output.cpp components/compiler/generator.cpp)
file(GLOB COMPILER components/compiler/*.cpp)
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp
components/interpreter/installopcodes.cpp)
file(GLOB INTERPRETER components/interpreter/*.cpp)
file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp)
source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})

@ -0,0 +1,65 @@
#include "exprparser.hpp"
#include <stdexcept>
#include "generator.hpp"
namespace Compiler
{
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals)
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals)
{}
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{
Operand operand;
operand.mType = 'l';
operand.mInteger = value;
mOperands.push_back (operand);
return false;
}
bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
{
return Parser::parseFloat (value, loc, scanner);
}
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc,
Scanner& scanner)
{
return Parser::parseName (name, loc, scanner);
}
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
{
return Parser::parseKeyword (keyword, loc, scanner);
}
bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
{
return Parser::parseSpecial (code, loc, scanner);
}
void ExprParser::reset()
{
mOperands.clear();
}
char ExprParser::write (std::vector<Interpreter::Type_Code>& code)
{
if (mOperands.empty())
throw std::logic_error ("empty expression");
Operand operand = mOperands[mOperands.size()-1];
mOperands.clear();
Generator::pushInt (code, mLiterals, operand.mInteger);
return operand.mType;
}
}

@ -0,0 +1,67 @@
#ifndef COMPILER_EXPRPARSER_H_INCLUDED
#define COMPILER_EXPRPARSER_H_INCLUDED
#include <vector>
#include <components/interpreter/types.hpp>
#include "parser.hpp"
namespace Compiler
{
class Locals;
class Literals;
class ExprParser : public Parser
{
struct Operand
{
char mType;
int mInteger;
float mFloat;
};
Locals& mLocals;
Literals& mLiterals;
std::vector<Operand> mOperands;
public:
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals);
///< constructor
char getType() const;
///< Return type of parsed expression ('l' integer, 'f' float)
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
///< Handle an int token.
/// \return fetch another token?
virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner);
///< Handle a float token.
/// \return fetch another token?
virtual bool parseName (const std::string& name, const TokenLoc& loc,
Scanner& scanner);
///< Handle a name token.
/// \return fetch another token?
virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner);
///< Handle a keyword token.
/// \return fetch another token?
virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner);
///< Handle a special character token.
/// \return fetch another token?
void reset();
///< Reset parser to clean state.
char write (std::vector<Interpreter::Type_Code>& code);
///< Generate code for parsed expression.
/// \return Type ('l': integer, 'f': float)
};
}
#endif

@ -2,6 +2,8 @@
#include "generator.hpp"
#include <cassert>
#include <algorithm>
#include <iterator>
#include "literals.hpp"
@ -63,6 +65,11 @@ namespace
code.push_back (segment5 (3));
}
void opFloatToInt (Compiler::Generator::CodeContainer& code)
{
assert (0); // not implemented
}
void opStoreLocalShort (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (0));
@ -83,20 +90,36 @@ namespace Compiler
{
namespace Generator
{
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
int localIndex, int value)
void pushInt (CodeContainer& code, Literals& literals, int value)
{
int index = literals.addInteger (value);
int index = literals.addInteger (value);
opPushInt (code, index);
opFetchIntLiteral (code);
}
void assignToLocal (CodeContainer& code, char localType,
int localIndex, const CodeContainer& value, char valueType)
{
opPushInt (code, localIndex);
opPushInt (code, index);
opFetchIntLiteral (code);
std::copy (value.begin(), value.end(), std::back_inserter (code));
if (localType!=valueType)
{
if (localType=='f' && valueType=='l')
{
opIntToFloat (code);
}
else if ((localType=='l' || localType=='s') && valueType=='f')
{
opFloatToInt (code);
}
}
switch (localType)
{
case 'f':
opIntToFloat (code);
opStoreLocalFloat (code);
break;
@ -113,7 +136,7 @@ namespace Compiler
default:
assert (0);
}
}
}
}
}

@ -12,9 +12,11 @@ namespace Compiler
namespace Generator
{
typedef std::vector<Interpreter::Type_Code> CodeContainer;
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
int localIndex, int value);
void pushInt (CodeContainer& code, Literals& literals, int value);
void assignToLocal (CodeContainer& code, char localType,
int localIndex, const CodeContainer& value, char valueType);
}
}

@ -13,22 +13,11 @@ namespace Compiler
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals, std::vector<Interpreter::Type_Code>& code)
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code),
mState (BeginState)
mState (BeginState), mExprParser (errorHandler, context, locals, literals)
{}
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{
if (mState==SetLocalToState)
{
Generator::assignIntToLocal (mCode, mLiterals, mLocals.getType (mName),
mLocals.getIndex (mName), value);
mState = EndState;
mName.clear();
return true;
}
{
return Parser::parseInt (value, loc, scanner);
}
@ -104,7 +93,16 @@ namespace Compiler
}
else if (mState==SetLocalVarState && keyword==Scanner::K_to)
{
mState = SetLocalToState;
mExprParser.reset();
scanner.scan (mExprParser);
std::vector<Interpreter::Type_Code> code;
char type = mExprParser.write (code);
Generator::assignToLocal (mCode, mLocals.getType (mName),
mLocals.getIndex (mName), code, type);
mState = EndState;
return true;
}

@ -6,6 +6,7 @@
#include <components/interpreter/types.hpp>
#include "parser.hpp"
#include "exprparser.hpp"
namespace Compiler
{
@ -29,6 +30,7 @@ namespace Compiler
std::vector<Interpreter::Type_Code>& mCode;
State mState;
std::string mName;
ExprParser mExprParser;
public:

Loading…
Cancel
Save