mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:59:54 +00:00
added function parsing (only one function so far)
This commit is contained in:
parent
c8c5ef5467
commit
5fb4abae4f
9 changed files with 95 additions and 9 deletions
|
@ -155,6 +155,25 @@ namespace Compiler
|
|||
popOperator();
|
||||
}
|
||||
|
||||
void ExprParser::parseArguments (const std::string& arguments, Scanner& scanner)
|
||||
{
|
||||
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals);
|
||||
|
||||
for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end();
|
||||
++iter)
|
||||
{
|
||||
parser.reset();
|
||||
scanner.scan (parser);
|
||||
|
||||
char type = parser.append (mCode);
|
||||
|
||||
if (type!=*iter)
|
||||
Generator::convert (mCode, type, *iter);
|
||||
|
||||
mOperands.push_back (*iter);
|
||||
}
|
||||
}
|
||||
|
||||
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals)
|
||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
|
||||
|
@ -193,6 +212,17 @@ namespace Compiler
|
|||
|
||||
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
if (keyword==Scanner::K_getsquareroot && mNextOperand)
|
||||
{
|
||||
mTokenLoc = loc;
|
||||
parseArguments ("f", scanner);
|
||||
|
||||
Generator::squareRoot (mCode);
|
||||
|
||||
mNextOperand = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parser::parseKeyword (keyword, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -234,14 +264,17 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
mTokenLoc = loc;
|
||||
|
||||
switch (code)
|
||||
if (!mNextOperand)
|
||||
{
|
||||
case Scanner::S_plus: pushBinaryOperator ('+'); return true;
|
||||
case Scanner::S_minus: pushBinaryOperator ('-'); return true;
|
||||
case Scanner::S_mult: pushBinaryOperator ('*'); return true;
|
||||
case Scanner::S_div: pushBinaryOperator ('/'); return true;
|
||||
mTokenLoc = loc;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case Scanner::S_plus: pushBinaryOperator ('+'); return true;
|
||||
case Scanner::S_minus: pushBinaryOperator ('-'); return true;
|
||||
case Scanner::S_mult: pushBinaryOperator ('*'); return true;
|
||||
case Scanner::S_div: pushBinaryOperator ('/'); return true;
|
||||
}
|
||||
}
|
||||
|
||||
return Parser::parseSpecial (code, loc, scanner);
|
||||
|
|
|
@ -44,6 +44,8 @@ namespace Compiler
|
|||
void pushBinaryOperator (char c);
|
||||
|
||||
void close();
|
||||
|
||||
void parseArguments (const std::string& arguments, Scanner& scanner);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "literals.hpp"
|
||||
|
||||
|
@ -144,6 +145,11 @@ namespace
|
|||
{
|
||||
code.push_back (segment5 (18));
|
||||
}
|
||||
|
||||
void opSquareRoot (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (19));
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
|
@ -297,6 +303,24 @@ namespace Compiler
|
|||
opDivFloat (code);
|
||||
}
|
||||
}
|
||||
|
||||
void convert (CodeContainer& code, char fromType, char toType)
|
||||
{
|
||||
if (fromType!=toType)
|
||||
{
|
||||
if (fromType=='f' && toType=='l')
|
||||
opFloatToInt (code);
|
||||
else if (fromType=='l' && toType=='f')
|
||||
opIntToFloat (code);
|
||||
else
|
||||
throw std::logic_error ("illegal type conversion");
|
||||
}
|
||||
}
|
||||
|
||||
void squareRoot (CodeContainer& code)
|
||||
{
|
||||
opSquareRoot (code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace Compiler
|
|||
void mul (CodeContainer& code, char valueType1, char valueType2);
|
||||
|
||||
void div (CodeContainer& code, char valueType1, char valueType2);
|
||||
|
||||
void convert (CodeContainer& code, char fromType, char toType);
|
||||
|
||||
void squareRoot (CodeContainer& code);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ namespace Compiler
|
|||
"return",
|
||||
"messagebox",
|
||||
"set", "to",
|
||||
"getsquareroot",
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace Compiler
|
|||
K_while, K_endwhile,
|
||||
K_return,
|
||||
K_messageBox,
|
||||
K_set, K_to
|
||||
K_set, K_to,
|
||||
K_getsquareroot
|
||||
};
|
||||
|
||||
enum special
|
||||
|
|
|
@ -70,6 +70,7 @@ op 15: div (integer) stack[1] by stack[0], pop twice, push result
|
|||
op 16: div (float) stack[1] by stack[0], pop twice, push result
|
||||
op 17: convert stack[1] from integer to float
|
||||
op 18: convert stack[1] from float to integer
|
||||
opcodes 19-33554431 unused
|
||||
op 19: take square root of stack[0] (float)
|
||||
opcodes 20-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Interpreter
|
|||
interpreter.installSegment5 (14, new OpMulInt<Type_Float>);
|
||||
interpreter.installSegment5 (15, new OpDivInt<Type_Integer>);
|
||||
interpreter.installSegment5 (16, new OpDivInt<Type_Float>);
|
||||
interpreter.installSegment5 (19, new OpSquareRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define INTERPRETER_MATHOPCODES_H_INCLUDED
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
|
||||
#include "opcodes.hpp"
|
||||
#include "runtime.hpp"
|
||||
|
@ -84,6 +85,24 @@ namespace Interpreter
|
|||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSquareRoot : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float value = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
||||
|
||||
if (value<0)
|
||||
throw std::runtime_error (
|
||||
"square root of negative number (we aren't that imaginary)");
|
||||
|
||||
value = std::sqrt (value);
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue