added parsing for signed integers and floats

pull/7/head
Marc Zinnschlag 15 years ago
parent ab33234027
commit ca8002e533

@ -9,6 +9,36 @@
namespace Compiler
{
char ExprParser::popUnaryOperator()
{
if (mOperators.empty())
return 0;
char op = mOperators[mOperators.size()-1];
if (op!='m') // unary -
return 0;
mOperators.resize (mOperators.size()-1);
return op;
}
char ExprParser::popOperand (std::vector<Interpreter::Type_Code>& code)
{
Operand operand = mOperands[mOperands.size()-1];
mOperands.resize (mOperands.size()-1);
if (operand.mType=='l')
Generator::pushInt (code, mLiterals, operand.mInteger);
else if (operand.mType=='f')
Generator::pushFloat (code, mLiterals, operand.mFloat);
else
throw std::logic_error ("unknown expression type");
return operand.mType;
}
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals)
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
@ -18,7 +48,7 @@ namespace Compiler
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{
if (mNextOperand)
{
{
Operand operand;
operand.mType = 'l';
operand.mInteger = value;
@ -79,6 +109,17 @@ namespace Compiler
return false;
}
if (code==Scanner::S_minus)
{
if (mNextOperand)
{
// unary
mOperators.push_back ('m');
mTokenLoc = loc;
return true;
}
}
return Parser::parseSpecial (code, loc, scanner);
}
@ -97,17 +138,24 @@ namespace Compiler
if (mNextOperand)
getErrorHandler().error ("syntax error in expression", mTokenLoc);
Operand operand = mOperands[mOperands.size()-1];
mOperands.clear();
if (operand.mType=='l')
Generator::pushInt (code, mLiterals, operand.mInteger);
else if (operand.mType=='f')
Generator::pushFloat (code, mLiterals, operand.mFloat);
else
throw std::logic_error ("unknown expression type");
char type = ' ';
while (!mOperands.empty())
{
type = popOperand (code);
while (char op = popUnaryOperator())
{
if (op=='m')
{
Generator::negate (code, type);
}
else
throw std::logic_error ("unknown unary operator");
}
}
return operand.mType;
return type;
}
}

@ -29,6 +29,11 @@ namespace Compiler
bool mNextOperand;
TokenLoc mTokenLoc;
char popUnaryOperator();
///< returns 0 and not popping, if the next operator isn't unary
char popOperand (std::vector<Interpreter::Type_Code>& code);
public:
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,

@ -84,6 +84,16 @@ namespace
{
code.push_back (segment5 (2));
}
void opNegateInt (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (7));
}
void opNegateFloat (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (8));
}
}
namespace Compiler
@ -145,6 +155,26 @@ namespace Compiler
assert (0);
}
}
void negate (CodeContainer& code, char valueType)
{
switch (valueType)
{
case 'l':
opNegateInt (code);
break;
case 'f':
opNegateFloat (code);
break;
default:
assert (0);
}
}
}
}

@ -19,6 +19,8 @@ namespace Compiler
void assignToLocal (CodeContainer& code, char localType,
int localIndex, const CodeContainer& value, char valueType);
void negate (CodeContainer& code, char valueType);
}
}

@ -58,6 +58,8 @@ op 3: convert stack[0] from integer to float
op 4: replace stack[0] with integer literal index stack[0]
op 5: replace stack[0] with float literal index stack[0]
op 6: convert stack[0] from float to integer
opcodes 7-33554431 unused
op 7: invert sign of int value stack[0]
op 8: invert sign of float value stack[0]
opcodes 9-33554431 unused
opcodes 33554432-67108863 reserved for extensions

@ -39,6 +39,30 @@ namespace Interpreter
runtime[0] = *reinterpret_cast<Type_Data *> (&integerValue);
}
};
class OpNegateInt : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]);
data = -data;
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
}
};
class OpNegateFloat : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]);
data = -data;
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
}
};
}
#endif

@ -13,7 +13,9 @@ namespace Interpreter
interpreter.installSegment0 (0, new OpPushInt);
interpreter.installSegment5 (3, new OpIntToFloat);
interpreter.installSegment5 (6, new OpFloatToInt);
interpreter.installSegment5 (7, new OpNegateInt);
interpreter.installSegment5 (8, new OpNegateFloat);
// local variables
interpreter.installSegment5 (0, new OpStoreLocalShort);
interpreter.installSegment5 (1, new OpStoreLocalLong);

Loading…
Cancel
Save