More type conversion and enforcement
This commit is contained in:
parent
1e535a160d
commit
acb126e162
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -58,6 +58,7 @@ namespace pim
|
||||
Parser(std::stringstream & source_);
|
||||
|
||||
std::vector<unsigned char> Compile();
|
||||
int GetPropertyType(std::string property);
|
||||
};
|
||||
}
|
||||
}
|
@ -116,7 +116,10 @@ namespace pim
|
||||
{
|
||||
nextCharacter();
|
||||
if(cChar == '=')
|
||||
return Token(Token::NotEqualSymbol, "==", cLine);
|
||||
{
|
||||
nextCharacter();
|
||||
return Token(Token::NotEqualSymbol, "!=", cLine);
|
||||
}
|
||||
}
|
||||
else if(cChar == '(')
|
||||
{
|
||||
|
@ -11,6 +11,9 @@ namespace pim
|
||||
nativeRom.clear();
|
||||
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("FF D0"); //call eax
|
||||
emit("81 C4"); //add esp, stacksize
|
||||
emit((int)stackSize+sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void X86Native::emit(std::string opcode)
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user