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

View File

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

View File

@ -447,6 +447,9 @@ namespace pim
int arg3 = CSPop().Integer; int arg3 = CSPop().Integer;
int arg2 = CSPop().Integer; int arg2 = CSPop().Integer;
int arg1 = 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); nativeFunction(arg1, arg2, arg3);
} }

View File

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

View File

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

View File

@ -11,6 +11,9 @@ 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;
emit("52"); //push edx
emit("56"); //push esi
emit("BE"); //mov esi, machineStack emit("BE"); //mov esi, machineStack
emit((intptr_t)esi); emit((intptr_t)esi);
@ -98,7 +101,17 @@ namespace pim
emit("F7 1E"); //neg [esi] emit("F7 1E"); //neg [esi]
break; break;
case Opcode::Create: 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(); //temp1 = PSPop();
//temp2 = PSPop(); //temp2 = PSPop();
//temp3 = PSPop(); //temp3 = PSPop();
@ -110,14 +123,6 @@ namespace pim
//PSPush((Word)-1); //PSPush((Word)-1);
break; break;
case Opcode::Get: 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; intptr_t partsArray = (intptr_t)sim->pmap;
emit("8B 06"); //mov eax, [esi] emit("8B 06"); //mov eax, [esi]
@ -145,15 +150,6 @@ namespace pim
} }
break; break;
case Opcode::Position: 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; intptr_t partsArray = (intptr_t)sim->parts;
emit("8B 06"); //mov eax, [esi] #Load index from stack emit("8B 06"); //mov eax, [esi] #Load index from stack
@ -277,6 +273,8 @@ namespace pim
emitPlaceholder(argument.Integer); emitPlaceholder(argument.Integer);
break; break;
case Opcode::Return: case Opcode::Return:
emit("5E"); //pop esi
emit("5A"); //pop edx
emit("C3"); //ret emit("C3"); //ret
break; break;
case Opcode::Leave: case Opcode::Leave:
@ -293,6 +291,8 @@ namespace pim
//std::cout << programStack << std::endl; //std::cout << programStack << std::endl;
programCounter++; programCounter++;
} }
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;
@ -313,13 +313,16 @@ namespace pim
emit((int)0); 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((int) objectPtr);
emit("A1"); //mov eax, functionAddress emit("B8"); //mov eax, functionAddress
emit((int)functionAddress); emit((int)functionAddress);
emit("FF D0"); //call eax emit("FF D0"); //call eax
emit("81 C4"); //add esp, stacksize
emit((int)stackSize+sizeof(intptr_t));
} }
void X86Native::emit(std::string opcode) void X86Native::emit(std::string opcode)

View File

@ -12,7 +12,7 @@ namespace pim
private: private:
void emit(std::string opcode); void emit(std::string opcode);
void emit(int constant); 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); void emitPlaceholder(int virtualAddress);
unsigned char hex(char c); unsigned char hex(char c);
std::vector<unsigned char> nativeRom; std::vector<unsigned char> nativeRom;