From 187bf11d3d8b4ec2e521dfc2372c8bfce5065e26 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Fri, 1 Feb 2013 15:21:21 +0000 Subject: [PATCH] tointeger and tofloat instructions. Detection and implicit conversion of number types --- src/cat/LuaScriptInterface.cpp | 4 +- src/pim/Exceptions.h | 40 +++++++++++++++++++ src/pim/Generator.cpp | 70 ++++++++++++++++++++-------------- src/pim/Generator.h | 7 ++-- src/pim/Machine.cpp | 2 + src/pim/Parser.cpp | 19 +++++++++ src/pim/Parser.h | 16 -------- src/pim/X86Native.cpp | 23 +++++------ src/simulation/Particle.cpp | 12 ++++++ src/simulation/Particle.h | 1 + 10 files changed, 131 insertions(+), 63 deletions(-) create mode 100644 src/pim/Exceptions.h diff --git a/src/cat/LuaScriptInterface.cpp b/src/cat/LuaScriptInterface.cpp index 19110c523..78a9ff025 100644 --- a/src/cat/LuaScriptInterface.cpp +++ b/src/cat/LuaScriptInterface.cpp @@ -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]; diff --git a/src/pim/Exceptions.h b/src/pim/Exceptions.h new file mode 100644 index 000000000..7f48e0e85 --- /dev/null +++ b/src/pim/Exceptions.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#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() {}; + }; + } +} \ No newline at end of file diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp index 3f296b7ab..4d929f0fe 100644 --- a/src/pim/Generator.cpp +++ b/src/pim/Generator.cpp @@ -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); diff --git a/src/pim/Generator.h b/src/pim/Generator.h index ca20d6df5..f40d2734d 100644 --- a/src/pim/Generator.h +++ b/src/pim/Generator.h @@ -131,11 +131,15 @@ namespace pim public: Generator(); + virtual ~Generator(); std::vector 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); diff --git a/src/pim/Machine.cpp b/src/pim/Machine.cpp index c69fa52ed..db1747382 100644 --- a/src/pim/Machine.cpp +++ b/src/pim/Machine.cpp @@ -270,6 +270,8 @@ namespace pim case Opcode::Get: case Opcode::Position: case Opcode::Kill: + case Opcode::ToFloat: + case Opcode::ToInteger: return 0; } } diff --git a/src/pim/Parser.cpp b/src/pim/Parser.cpp index 91b50f867..29fc56983 100644 --- a/src/pim/Parser.cpp +++ b/src/pim/Parser.cpp @@ -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); } diff --git a/src/pim/Parser.h b/src/pim/Parser.h index 9a4f736a2..a94ac165e 100644 --- a/src/pim/Parser.h +++ b/src/pim/Parser.h @@ -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; diff --git a/src/pim/X86Native.cpp b/src/pim/X86Native.cpp index bbc0a66aa..f09ea8783 100644 --- a/src/pim/X86Native.cpp +++ b/src/pim/X86Native.cpp @@ -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::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter) { std::pair placeholder = *iter; diff --git a/src/simulation/Particle.cpp b/src/simulation/Particle.cpp index 115ed9518..d5ab97709 100644 --- a/src/simulation/Particle.cpp +++ b/src/simulation/Particle.cpp @@ -25,3 +25,15 @@ std::vector Particle::GetProperties() properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour))); return properties; } + + +StructProperty Particle::GetProperty(std::string propertyName) +{ + std::vector types = GetProperties(); + for(std::vector::iterator iter = types.begin(), end = types.end(); iter != end; ++iter) + { + if((*iter).Name == propertyName) + return *iter; + } + return StructProperty("unknown", StructProperty::Float, 0); +} \ No newline at end of file diff --git a/src/simulation/Particle.h b/src/simulation/Particle.h index bb0297eb8..ad01a507c 100644 --- a/src/simulation/Particle.h +++ b/src/simulation/Particle.h @@ -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 GetProperties(); + static StructProperty GetProperty(std::string propertyName); }; #endif