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(i);
|
||||||
machine->CSPush(x);
|
machine->CSPush(x);
|
||||||
machine->CSPush(y);
|
machine->CSPush(y);
|
||||||
machine->Call(0);
|
//machine->Call(0);
|
||||||
//machine->CallCompiled(0);
|
machine->CallCompiled(0);
|
||||||
|
|
||||||
|
|
||||||
/*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
|
/*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 "Format.h"
|
||||||
#include "Generator.h"
|
#include "Generator.h"
|
||||||
#include "Opcodes.h"
|
#include "Opcodes.h"
|
||||||
|
#include "Exceptions.h"
|
||||||
namespace pim
|
namespace pim
|
||||||
{
|
{
|
||||||
namespace compiler
|
namespace compiler
|
||||||
{
|
{
|
||||||
Generator::Generator() :
|
Generator::Generator() :
|
||||||
|
typeStack(),
|
||||||
output(std::cout),
|
output(std::cout),
|
||||||
labelCounter(0),
|
labelCounter(0),
|
||||||
programCounter(0)
|
programCounter(0)
|
||||||
@ -16,6 +18,10 @@ namespace pim
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Generator::~Generator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Generator::defineLabel(std::string label)
|
void Generator::defineLabel(std::string label)
|
||||||
{
|
{
|
||||||
Label newLabel;
|
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)
|
void Generator::ScopeVariable(std::string label)
|
||||||
{
|
{
|
||||||
currentScope->Definitions.push_back(Definition(label, variableType, currentScope->LocalFrameSize, currentScope));
|
currentScope->Definitions.push_back(Definition(label, variableType, currentScope->LocalFrameSize, currentScope));
|
||||||
currentScope->FrameSize += 4;
|
currentScope->FrameSize += 4;
|
||||||
currentScope->LocalFrameSize += 4;
|
currentScope->LocalFrameSize += 4;
|
||||||
typeStack.pop();
|
|
||||||
|
|
||||||
output << "#declare " << label << " " << currentScope->LocalFrameSize-4 << std::endl;
|
output << "#declare " << label << " " << currentScope->LocalFrameSize-4 << std::endl;
|
||||||
}
|
}
|
||||||
@ -361,20 +389,8 @@ namespace pim
|
|||||||
void Generator::StoreVariable(std::string label)
|
void Generator::StoreVariable(std::string label)
|
||||||
{
|
{
|
||||||
Definition d = currentScope->GetDefinition(label);
|
Definition d = currentScope->GetDefinition(label);
|
||||||
int otherType = typeStack.top();
|
AssureType(d.Type);
|
||||||
|
popType(1);
|
||||||
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);
|
|
||||||
|
|
||||||
writeOpcode(Opcode::Store);
|
writeOpcode(Opcode::Store);
|
||||||
|
|
||||||
@ -461,6 +477,8 @@ namespace pim
|
|||||||
popType(1);
|
popType(1);
|
||||||
pushType(DataType::Integer);
|
pushType(DataType::Integer);
|
||||||
writeOpcode(Opcode::ToInteger);
|
writeOpcode(Opcode::ToInteger);
|
||||||
|
|
||||||
|
output << "ftoi" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::ToFloat()
|
void Generator::ToFloat()
|
||||||
@ -468,6 +486,8 @@ namespace pim
|
|||||||
popType(1);
|
popType(1);
|
||||||
pushType(DataType::Float);
|
pushType(DataType::Float);
|
||||||
writeOpcode(Opcode::ToFloat);
|
writeOpcode(Opcode::ToFloat);
|
||||||
|
|
||||||
|
output << "itof" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::Divide()
|
void Generator::Divide()
|
||||||
@ -481,9 +501,9 @@ namespace pim
|
|||||||
|
|
||||||
void Generator::Modulus()
|
void Generator::Modulus()
|
||||||
{
|
{
|
||||||
writeOpcode(Opcode::Modulus);
|
|
||||||
popType(2);
|
popType(2);
|
||||||
pushType(DataType::Integer);
|
pushType(DataType::Integer);
|
||||||
|
writeOpcode(Opcode::Modulus);
|
||||||
|
|
||||||
output << "add" << std::endl;
|
output << "add" << std::endl;
|
||||||
}
|
}
|
||||||
@ -538,7 +558,7 @@ namespace pim
|
|||||||
|
|
||||||
void Generator::LoadProperty(std::string property)
|
void Generator::LoadProperty(std::string property)
|
||||||
{
|
{
|
||||||
popType(2);
|
popType(1);
|
||||||
pushType(DataType::Integer);
|
pushType(DataType::Integer);
|
||||||
writeOpcode(Opcode::LoadProperty);
|
writeOpcode(Opcode::LoadProperty);
|
||||||
writeConstantPropertyPlaceholder(property);
|
writeConstantPropertyPlaceholder(property);
|
||||||
@ -548,24 +568,16 @@ namespace pim
|
|||||||
|
|
||||||
void Generator::StoreProperty(std::string property)
|
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);
|
writeOpcode(Opcode::StoreProperty);
|
||||||
writeConstantPropertyPlaceholder(property);
|
writeConstantPropertyPlaceholder(property);
|
||||||
|
|
||||||
output << "storeprop " << property << std::endl;
|
output << "storeprop " << property << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::IntegerToDecimal()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Generator::DecimalToInteger()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::JumpEqual(std::string label)
|
void Generator::JumpEqual(std::string label)
|
||||||
{
|
{
|
||||||
popType(2);
|
popType(2);
|
||||||
|
@ -131,11 +131,15 @@ namespace pim
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Generator();
|
Generator();
|
||||||
|
virtual ~Generator();
|
||||||
|
|
||||||
std::vector<unsigned char> Finish();
|
std::vector<unsigned char> Finish();
|
||||||
|
|
||||||
std::string UniqueLabel(std::string prefix);
|
std::string UniqueLabel(std::string prefix);
|
||||||
|
|
||||||
|
void AssureType(int type);
|
||||||
|
void ForceType(int type);
|
||||||
|
|
||||||
void PushScope(std::string label);
|
void PushScope(std::string label);
|
||||||
void PushLocalScope(std::string label);
|
void PushLocalScope(std::string label);
|
||||||
void LocalEnter();
|
void LocalEnter();
|
||||||
@ -174,9 +178,6 @@ namespace pim
|
|||||||
void LoadProperty(std::string property);
|
void LoadProperty(std::string property);
|
||||||
void StoreProperty(std::string property);
|
void StoreProperty(std::string property);
|
||||||
|
|
||||||
void IntegerToDecimal();
|
|
||||||
void DecimalToInteger();
|
|
||||||
|
|
||||||
void JumpEqual(std::string label);
|
void JumpEqual(std::string label);
|
||||||
void JumpNotEqual(std::string label);
|
void JumpNotEqual(std::string label);
|
||||||
void JumpGreater(std::string label);
|
void JumpGreater(std::string label);
|
||||||
|
@ -270,6 +270,8 @@ namespace pim
|
|||||||
case Opcode::Get:
|
case Opcode::Get:
|
||||||
case Opcode::Position:
|
case Opcode::Position:
|
||||||
case Opcode::Kill:
|
case Opcode::Kill:
|
||||||
|
case Opcode::ToFloat:
|
||||||
|
case Opcode::ToInteger:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
#include "Format.h"
|
#include "Format.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
#include "Exceptions.h"
|
||||||
|
#include "simulation/Particle.h"
|
||||||
|
#include "simulation/StructProperty.h"
|
||||||
namespace pim
|
namespace pim
|
||||||
{
|
{
|
||||||
namespace compiler
|
namespace compiler
|
||||||
@ -494,6 +497,22 @@ namespace pim
|
|||||||
expect(Token::Identifier);
|
expect(Token::Identifier);
|
||||||
expect(Token::AssignSymbol);
|
expect(Token::AssignSymbol);
|
||||||
expression();
|
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->LoadVariable(variable);
|
||||||
generator->StoreProperty(property);
|
generator->StoreProperty(property);
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,6 @@ namespace pim
|
|||||||
{
|
{
|
||||||
namespace compiler
|
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
|
class Parser
|
||||||
{
|
{
|
||||||
std::stringstream & source;
|
std::stringstream & source;
|
||||||
|
@ -11,15 +11,10 @@ namespace pim
|
|||||||
nativeRom.clear();
|
nativeRom.clear();
|
||||||
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
|
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
|
||||||
esi += 512;
|
esi += 512;
|
||||||
//int * esi = malloc(1024*1024);
|
|
||||||
emit("BE"); //mov esi, machineStack
|
emit("BE"); //mov esi, machineStack
|
||||||
emit((intptr_t)esi);
|
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)
|
while(programCounter < romSize)
|
||||||
{
|
{
|
||||||
Word argument = rom[programCounter].Parameter;
|
Word argument = rom[programCounter].Parameter;
|
||||||
@ -221,6 +216,14 @@ namespace pim
|
|||||||
emit("83 C6 08"); //add esi, 8
|
emit("83 C6 08"); //add esi, 8
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case Opcode::JumpEqual:
|
||||||
emit("83 C6 08"); //add esi, 8
|
emit("83 C6 08"); //add esi, 8
|
||||||
emit("8B 46 FC"); //mov eax, [esi-4]
|
emit("8B 46 FC"); //mov eax, [esi-4]
|
||||||
@ -290,12 +293,6 @@ namespace pim
|
|||||||
//std::cout << programStack << std::endl;
|
//std::cout << programStack << std::endl;
|
||||||
programCounter++;
|
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)
|
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
|
||||||
{
|
{
|
||||||
std::pair<int, int> placeholder = *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)));
|
properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
|
||||||
return properties;
|
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
|
/** 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 **/
|
by higher-level processes refering to them by name such as Lua or the property tool **/
|
||||||
static std::vector<StructProperty> GetProperties();
|
static std::vector<StructProperty> GetProperties();
|
||||||
|
static StructProperty GetProperty(std::string propertyName);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user