More type conversion and enforcement

This commit is contained in:
Simon Robertshaw 2013-02-02 01:31:19 +00:00
parent 1e535a160d
commit acb126e162
8 changed files with 81 additions and 51 deletions

View File

@ -357,7 +357,7 @@ namespace pim
void Generator::ForceType(int type)
{
if(typeStack.top() != type)
throw new TypeException(typeStack.top(), type);
throw TypeException(typeStack.top(), type);
}
void Generator::ScopeVariable(std::string label)
@ -389,7 +389,7 @@ namespace pim
void Generator::StoreVariable(std::string label)
{
Definition d = currentScope->GetDefinition(label);
AssureType(d.Type);
ForceType(d.Type);
popType(1);
writeOpcode(Opcode::Store);
@ -517,8 +517,18 @@ namespace pim
void Generator::CreateParticle()
{
ForceType(DataType::Integer);
popType(1);
ForceType(DataType::Integer);
popType(1);
ForceType(DataType::Integer);
popType(1);
ForceType(DataType::Integer);
popType(1);
writeOpcode(Opcode::Create);
pushType(DataType::Integer);
output << "create" << std::endl;
}
@ -556,10 +566,12 @@ namespace pim
output << "kill" << std::endl;
}
void Generator::LoadProperty(std::string property)
void Generator::LoadProperty(std::string property, int type)
{
ForceType(DataType::Integer); //Particle type must be integer
popType(1);
pushType(DataType::Integer);
pushType(type);
writeOpcode(Opcode::LoadProperty);
writeConstantPropertyPlaceholder(property);

View File

@ -175,7 +175,7 @@ namespace pim
void GetParticle();
void GetPosition();
void KillParticle();
void LoadProperty(std::string property);
void LoadProperty(std::string property, int type);
void StoreProperty(std::string property);
void JumpEqual(std::string label);

View File

@ -447,6 +447,9 @@ namespace pim
int arg3 = CSPop().Integer;
int arg2 = CSPop().Integer;
int arg1 = CSPop().Integer;
std::cout << arg1 << std::endl;
std::cout << arg2 << std::endl;
std::cout << arg3 << std::endl;
nativeFunction(arg1, arg2, arg3);
}

View File

@ -113,11 +113,11 @@ namespace pim
int type;
switch(token.Symbol)
{
case Token::DecimalConstant:
case Token::DecimalSymbol:
type = DataType::Float;
break;
case Token::IntegerConstant:
case Token::ParticleConstant:
case Token::IntegerSymbol:
case Token::ParticleSymbol:
type = DataType::Integer;
break;
}
@ -148,11 +148,11 @@ namespace pim
int type;
switch(token.Symbol)
{
case Token::DecimalConstant:
case Token::DecimalSymbol:
type = DataType::Float;
break;
case Token::IntegerConstant:
case Token::ParticleConstant:
case Token::IntegerSymbol:
case Token::ParticleSymbol:
type = DataType::Integer;
break;
}
@ -264,12 +264,16 @@ namespace pim
expect(Token::CreateSymbol);
expect(Token::LeftBracket);
expression();
generator->AssureType(DataType::Integer);
expect(Token::CommaSymbol);
expression();
generator->AssureType(DataType::Integer);
expect(Token::CommaSymbol);
expression();
generator->AssureType(DataType::Integer);
expect(Token::CommaSymbol);
expression();
generator->AssureType(DataType::Integer);
expect(Token::RightBracket);
generator->CreateParticle();
}
@ -498,21 +502,7 @@ namespace pim
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->AssureType(GetPropertyType(property));
generator->LoadVariable(variable);
generator->StoreProperty(property);
}
@ -622,7 +612,7 @@ namespace pim
std::string property = token.Source;
expect(Token::Identifier);
generator->LoadVariable(variable);
generator->LoadProperty(property);
generator->LoadProperty(property, GetPropertyType(property));
}
else
{
@ -691,5 +681,23 @@ namespace pim
if(!accept(symbol))
throw ParserExpectException(token, symbol);
}
int Parser::GetPropertyType(std::string property)
{
int t2 = DataType::Integer;
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;
}
return t2;
}
}
}

View File

@ -58,6 +58,7 @@ namespace pim
Parser(std::stringstream & source_);
std::vector<unsigned char> Compile();
int GetPropertyType(std::string property);
};
}
}

View File

@ -116,7 +116,10 @@ namespace pim
{
nextCharacter();
if(cChar == '=')
return Token(Token::NotEqualSymbol, "==", cLine);
{
nextCharacter();
return Token(Token::NotEqualSymbol, "!=", cLine);
}
}
else if(cChar == '(')
{

View File

@ -12,6 +12,9 @@ namespace pim
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
esi += 512;
emit("52"); //push edx
emit("56"); //push esi
emit("BE"); //mov esi, machineStack
emit((intptr_t)esi);
@ -98,7 +101,17 @@ namespace pim
emit("F7 1E"); //neg [esi]
break;
case Opcode::Create:
emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part));
emit("8B 06"); //mov eax, [esi]
emit("50"); //push eax
emit("8B 46 04"); //mov eax, [esi+4]
emit("50"); //push eax
emit("8B 46 08"); //mov eax, [esi+8]
emit("50"); //push eax
emit("8B 46 0C"); //mov eax, [esi+12]
emit("50"); //push eax
emit("83 C6 08"); //add esi, 8
emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part), 16);
emit("89 06"); //mov [esi], eax
//temp1 = PSPop();
//temp2 = PSPop();
//temp3 = PSPop();
@ -110,14 +123,6 @@ namespace pim
//PSPush((Word)-1);
break;
case Opcode::Get:
//temp1 = PSPop();
//temp2 = PSPop();
//if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer]))
//{
// PSPush(-1);
// break;
//}
//PSPush(temp>>8);
{
intptr_t partsArray = (intptr_t)sim->pmap;
emit("8B 06"); //mov eax, [esi]
@ -145,15 +150,6 @@ namespace pim
}
break;
case Opcode::Position:
//temp1 = PSPop();
//if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type)
//{
// PSPush(-1);
// PSPush(-1);
// break;
//}
//PSPush((int)sim->parts[temp1.Integer].x);
//PSPush((int)sim->parts[temp1.Integer].y);
{
intptr_t partsArray = (intptr_t)sim->parts;
emit("8B 06"); //mov eax, [esi] #Load index from stack
@ -277,6 +273,8 @@ namespace pim
emitPlaceholder(argument.Integer);
break;
case Opcode::Return:
emit("5E"); //pop esi
emit("5A"); //pop edx
emit("C3"); //ret
break;
case Opcode::Leave:
@ -293,6 +291,8 @@ namespace pim
//std::cout << programStack << std::endl;
programCounter++;
}
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
{
std::pair<int, int> placeholder = *iter;
@ -313,13 +313,16 @@ namespace pim
emit((int)0);
}
void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress)
void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize)
{
emit("B9"); //mov ecx, instancePointer
//emit("B9"); //mov ecx, instancePointer
emit("68"); //push instancePointer
emit((int) objectPtr);
emit("A1"); //mov eax, functionAddress
emit("B8"); //mov eax, functionAddress
emit((int)functionAddress);
emit("FF D0"); //call eax
emit("81 C4"); //add esp, stacksize
emit((int)stackSize+sizeof(intptr_t));
}
void X86Native::emit(std::string opcode)

View File

@ -12,7 +12,7 @@ namespace pim
private:
void emit(std::string opcode);
void emit(int constant);
void emitCall(intptr_t objectPtr, intptr_t functionAddress);
void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize);
void emitPlaceholder(int virtualAddress);
unsigned char hex(char c);
std::vector<unsigned char> nativeRom;