added function parsing (only one function so far)

actorid
Marc Zinnschlag 15 years ago
parent c8c5ef5467
commit 5fb4abae4f

@ -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…
Cancel
Save