forked from mirror/openmw-tes3mp
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();
|
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,
|
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||||
Literals& literals)
|
Literals& literals)
|
||||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
|
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
|
||||||
|
@ -193,6 +212,17 @@ namespace Compiler
|
||||||
|
|
||||||
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
|
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);
|
return Parser::parseKeyword (keyword, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,14 +264,17 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTokenLoc = loc;
|
if (!mNextOperand)
|
||||||
|
|
||||||
switch (code)
|
|
||||||
{
|
{
|
||||||
case Scanner::S_plus: pushBinaryOperator ('+'); return true;
|
mTokenLoc = loc;
|
||||||
case Scanner::S_minus: pushBinaryOperator ('-'); return true;
|
|
||||||
case Scanner::S_mult: pushBinaryOperator ('*'); return true;
|
switch (code)
|
||||||
case Scanner::S_div: pushBinaryOperator ('/'); return true;
|
{
|
||||||
|
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);
|
return Parser::parseSpecial (code, loc, scanner);
|
||||||
|
|
|
@ -45,6 +45,8 @@ namespace Compiler
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
void parseArguments (const std::string& arguments, Scanner& scanner);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "literals.hpp"
|
#include "literals.hpp"
|
||||||
|
|
||||||
|
@ -144,6 +145,11 @@ namespace
|
||||||
{
|
{
|
||||||
code.push_back (segment5 (18));
|
code.push_back (segment5 (18));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void opSquareRoot (Compiler::Generator::CodeContainer& code)
|
||||||
|
{
|
||||||
|
code.push_back (segment5 (19));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
|
@ -297,6 +303,24 @@ namespace Compiler
|
||||||
opDivFloat (code);
|
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 mul (CodeContainer& code, char valueType1, char valueType2);
|
||||||
|
|
||||||
void div (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",
|
"return",
|
||||||
"messagebox",
|
"messagebox",
|
||||||
"set", "to",
|
"set", "to",
|
||||||
|
"getsquareroot",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ namespace Compiler
|
||||||
K_while, K_endwhile,
|
K_while, K_endwhile,
|
||||||
K_return,
|
K_return,
|
||||||
K_messageBox,
|
K_messageBox,
|
||||||
K_set, K_to
|
K_set, K_to,
|
||||||
|
K_getsquareroot
|
||||||
};
|
};
|
||||||
|
|
||||||
enum special
|
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 16: div (float) stack[1] by stack[0], pop twice, push result
|
||||||
op 17: convert stack[1] from integer to float
|
op 17: convert stack[1] from integer to float
|
||||||
op 18: convert stack[1] from float to integer
|
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
|
opcodes 33554432-67108863 reserved for extensions
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Interpreter
|
||||||
interpreter.installSegment5 (14, new OpMulInt<Type_Float>);
|
interpreter.installSegment5 (14, new OpMulInt<Type_Float>);
|
||||||
interpreter.installSegment5 (15, new OpDivInt<Type_Integer>);
|
interpreter.installSegment5 (15, new OpDivInt<Type_Integer>);
|
||||||
interpreter.installSegment5 (16, new OpDivInt<Type_Float>);
|
interpreter.installSegment5 (16, new OpDivInt<Type_Float>);
|
||||||
|
interpreter.installSegment5 (19, new OpSquareRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define INTERPRETER_MATHOPCODES_H_INCLUDED
|
#define INTERPRETER_MATHOPCODES_H_INCLUDED
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "opcodes.hpp"
|
#include "opcodes.hpp"
|
||||||
#include "runtime.hpp"
|
#include "runtime.hpp"
|
||||||
|
@ -84,6 +85,24 @@ namespace Interpreter
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue