tointeger and tofloat instructions. Detection and implicit conversion of number types
This commit is contained in:
parent
833cbf9b77
commit
187bf11d3d
@ -958,8 +958,8 @@ int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
|
||||
machine->CSPush(i);
|
||||
machine->CSPush(x);
|
||||
machine->CSPush(y);
|
||||
machine->Call(0);
|
||||
//machine->CallCompiled(0);
|
||||
//machine->Call(0);
|
||||
machine->CallCompiled(0);
|
||||
|
||||
|
||||
/*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
|
||||
|
40
src/pim/Exceptions.h
Normal file
40
src/pim/Exceptions.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "Token.h"
|
||||
|
||||
namespace pim
|
||||
{
|
||||
namespace compiler {
|
||||
class ParserExpectException: public std::exception
|
||||
{
|
||||
char * error;
|
||||
public:
|
||||
ParserExpectException(Token token, int expectingSymbol) {
|
||||
error = strdup(std::string("Expecting " + Token::SymbolNames[expectingSymbol] + " got " + token.Source).c_str());
|
||||
}
|
||||
ParserExpectException(Token token, std::string expectingString) {
|
||||
error = strdup(std::string("Expecting " + expectingString + " got " + token.Source).c_str());
|
||||
}
|
||||
const char * what() const throw()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
~ParserExpectException() throw() {};
|
||||
};
|
||||
class TypeException: public std::exception
|
||||
{
|
||||
char * error;
|
||||
public:
|
||||
TypeException(int type, int expectingType) {
|
||||
error = strdup(std::string("Expecting a particular type, got a different type").c_str());
|
||||
}
|
||||
const char * what() const throw()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
~TypeException() throw() {};
|
||||
};
|
||||
}
|
||||
}
|
@ -4,11 +4,13 @@
|
||||
#include "Format.h"
|
||||
#include "Generator.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Exceptions.h"
|
||||
namespace pim
|
||||
{
|
||||
namespace compiler
|
||||
{
|
||||
Generator::Generator() :
|
||||
typeStack(),
|
||||
output(std::cout),
|
||||
labelCounter(0),
|
||||
programCounter(0)
|
||||
@ -16,6 +18,10 @@ namespace pim
|
||||
|
||||
}
|
||||
|
||||
Generator::~Generator()
|
||||
{
|
||||
}
|
||||
|
||||
void Generator::defineLabel(std::string label)
|
||||
{
|
||||
Label newLabel;
|
||||
@ -331,12 +337,34 @@ namespace pim
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::AssureType(int type)
|
||||
{
|
||||
int otherType = typeStack.top();
|
||||
|
||||
if(otherType != type)
|
||||
{
|
||||
if(otherType == DataType::Integer && type == DataType::Float)
|
||||
{
|
||||
ToFloat();
|
||||
}
|
||||
else if(otherType == DataType::Float && type == DataType::Integer)
|
||||
{
|
||||
ToInteger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::ForceType(int type)
|
||||
{
|
||||
if(typeStack.top() != type)
|
||||
throw new TypeException(typeStack.top(), type);
|
||||
}
|
||||
|
||||
void Generator::ScopeVariable(std::string label)
|
||||
{
|
||||
currentScope->Definitions.push_back(Definition(label, variableType, currentScope->LocalFrameSize, currentScope));
|
||||
currentScope->FrameSize += 4;
|
||||
currentScope->LocalFrameSize += 4;
|
||||
typeStack.pop();
|
||||
|
||||
output << "#declare " << label << " " << currentScope->LocalFrameSize-4 << std::endl;
|
||||
}
|
||||
@ -361,20 +389,8 @@ namespace pim
|
||||
void Generator::StoreVariable(std::string label)
|
||||
{
|
||||
Definition d = currentScope->GetDefinition(label);
|
||||
int otherType = typeStack.top();
|
||||
|
||||
if(otherType != d.Type)
|
||||
{
|
||||
if(otherType == DataType::Integer && d.Type == DataType::Float)
|
||||
{
|
||||
ToFloat();
|
||||
}
|
||||
else if(otherType == DataType::Float && d.Type == DataType::Integer)
|
||||
{
|
||||
ToInteger();
|
||||
}
|
||||
}
|
||||
popType(2);
|
||||
AssureType(d.Type);
|
||||
popType(1);
|
||||
|
||||
writeOpcode(Opcode::Store);
|
||||
|
||||
@ -461,6 +477,8 @@ namespace pim
|
||||
popType(1);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::ToInteger);
|
||||
|
||||
output << "ftoi" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::ToFloat()
|
||||
@ -468,6 +486,8 @@ namespace pim
|
||||
popType(1);
|
||||
pushType(DataType::Float);
|
||||
writeOpcode(Opcode::ToFloat);
|
||||
|
||||
output << "itof" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Divide()
|
||||
@ -481,9 +501,9 @@ namespace pim
|
||||
|
||||
void Generator::Modulus()
|
||||
{
|
||||
writeOpcode(Opcode::Modulus);
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Modulus);
|
||||
|
||||
output << "add" << std::endl;
|
||||
}
|
||||
@ -538,7 +558,7 @@ namespace pim
|
||||
|
||||
void Generator::LoadProperty(std::string property)
|
||||
{
|
||||
popType(2);
|
||||
popType(1);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::LoadProperty);
|
||||
writeConstantPropertyPlaceholder(property);
|
||||
@ -548,24 +568,16 @@ namespace pim
|
||||
|
||||
void Generator::StoreProperty(std::string property)
|
||||
{
|
||||
popType(2);
|
||||
ForceType(DataType::Integer); //Ensure particle ID is an integer
|
||||
popType(1); //Use particle ID
|
||||
popType(1);
|
||||
|
||||
writeOpcode(Opcode::StoreProperty);
|
||||
writeConstantPropertyPlaceholder(property);
|
||||
|
||||
output << "storeprop " << property << std::endl;
|
||||
}
|
||||
|
||||
void Generator::IntegerToDecimal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Generator::DecimalToInteger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Generator::JumpEqual(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
|
@ -131,11 +131,15 @@ namespace pim
|
||||
|
||||
public:
|
||||
Generator();
|
||||
virtual ~Generator();
|
||||
|
||||
std::vector<unsigned char> Finish();
|
||||
|
||||
std::string UniqueLabel(std::string prefix);
|
||||
|
||||
void AssureType(int type);
|
||||
void ForceType(int type);
|
||||
|
||||
void PushScope(std::string label);
|
||||
void PushLocalScope(std::string label);
|
||||
void LocalEnter();
|
||||
@ -174,9 +178,6 @@ namespace pim
|
||||
void LoadProperty(std::string property);
|
||||
void StoreProperty(std::string property);
|
||||
|
||||
void IntegerToDecimal();
|
||||
void DecimalToInteger();
|
||||
|
||||
void JumpEqual(std::string label);
|
||||
void JumpNotEqual(std::string label);
|
||||
void JumpGreater(std::string label);
|
||||
|
@ -270,6 +270,8 @@ namespace pim
|
||||
case Opcode::Get:
|
||||
case Opcode::Position:
|
||||
case Opcode::Kill:
|
||||
case Opcode::ToFloat:
|
||||
case Opcode::ToInteger:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "Parser.h"
|
||||
#include "Format.h"
|
||||
#include "Types.h"
|
||||
#include "Exceptions.h"
|
||||
#include "simulation/Particle.h"
|
||||
#include "simulation/StructProperty.h"
|
||||
namespace pim
|
||||
{
|
||||
namespace compiler
|
||||
@ -494,6 +497,22 @@ namespace pim
|
||||
expect(Token::Identifier);
|
||||
expect(Token::AssignSymbol);
|
||||
expression();
|
||||
|
||||
int t2;
|
||||
StructProperty::PropertyType t = Particle::GetProperty(property).Type;
|
||||
switch(t){
|
||||
case StructProperty::ParticleType:
|
||||
case StructProperty::Colour:
|
||||
case StructProperty::Integer:
|
||||
case StructProperty::UInteger:
|
||||
t2 = DataType::Integer;
|
||||
break;
|
||||
case StructProperty::Float:
|
||||
t2 = DataType::Float;
|
||||
break;
|
||||
}
|
||||
|
||||
generator->AssureType(t2);
|
||||
generator->LoadVariable(variable);
|
||||
generator->StoreProperty(property);
|
||||
}
|
||||
|
@ -10,22 +10,6 @@ namespace pim
|
||||
{
|
||||
namespace compiler
|
||||
{
|
||||
class ParserExpectException: public std::exception
|
||||
{
|
||||
char * error;
|
||||
public:
|
||||
ParserExpectException(Token token, int expectingSymbol) {
|
||||
error = strdup(std::string("Expecting " + Token::SymbolNames[expectingSymbol] + " got " + token.Source).c_str());
|
||||
}
|
||||
ParserExpectException(Token token, std::string expectingString) {
|
||||
error = strdup(std::string("Expecting " + expectingString + " got " + token.Source).c_str());
|
||||
}
|
||||
const char * what() const throw()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
~ParserExpectException() throw() {};
|
||||
};
|
||||
class Parser
|
||||
{
|
||||
std::stringstream & source;
|
||||
|
@ -11,15 +11,10 @@ namespace pim
|
||||
nativeRom.clear();
|
||||
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
|
||||
esi += 512;
|
||||
//int * esi = malloc(1024*1024);
|
||||
|
||||
emit("BE"); //mov esi, machineStack
|
||||
emit((intptr_t)esi);
|
||||
//emit("81 EC"); //sub esp, 12
|
||||
//emit(12);
|
||||
#ifdef DEBUG
|
||||
emit("81 C4"); //add esp, 4
|
||||
emit(4);
|
||||
#endif
|
||||
|
||||
while(programCounter < romSize)
|
||||
{
|
||||
Word argument = rom[programCounter].Parameter;
|
||||
@ -221,6 +216,14 @@ namespace pim
|
||||
emit("83 C6 08"); //add esi, 8
|
||||
}
|
||||
break;
|
||||
case Opcode::ToFloat:
|
||||
emit("DB 06"); //fild [esi]
|
||||
emit("D9 1E"); //fstp [esi]
|
||||
break;
|
||||
case Opcode::ToInteger:
|
||||
emit("D9 06"); //fld [esi]
|
||||
emit("DB 1E"); //fistp [esi]
|
||||
break;
|
||||
case Opcode::JumpEqual:
|
||||
emit("83 C6 08"); //add esi, 8
|
||||
emit("8B 46 FC"); //mov eax, [esi-4]
|
||||
@ -290,12 +293,6 @@ namespace pim
|
||||
//std::cout << programStack << std::endl;
|
||||
programCounter++;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
emit("81 EC"); //sub esp, 4
|
||||
//emit("81 EC"); //sub esp, 4
|
||||
emit(4);
|
||||
emit("C9"); //leave //When -fomit-frame-pointers is used, don't 'leave', since ebp isn't on the stack
|
||||
#endif
|
||||
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
|
||||
{
|
||||
std::pair<int, int> placeholder = *iter;
|
||||
|
@ -25,3 +25,15 @@ std::vector<StructProperty> Particle::GetProperties()
|
||||
properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
StructProperty Particle::GetProperty(std::string propertyName)
|
||||
{
|
||||
std::vector<StructProperty> types = GetProperties();
|
||||
for(std::vector<StructProperty>::iterator iter = types.begin(), end = types.end(); iter != end; ++iter)
|
||||
{
|
||||
if((*iter).Name == propertyName)
|
||||
return *iter;
|
||||
}
|
||||
return StructProperty("unknown", StructProperty::Float, 0);
|
||||
}
|
@ -26,6 +26,7 @@ struct Particle
|
||||
/** Returns a list of properties, their type and offset within the structure that can be changed
|
||||
by higher-level processes refering to them by name such as Lua or the property tool **/
|
||||
static std::vector<StructProperty> GetProperties();
|
||||
static StructProperty GetProperty(std::string propertyName);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user