Merge
This commit is contained in:
commit
1e535a160d
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 "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;
|
||||
@ -313,6 +319,47 @@ namespace pim
|
||||
variableType = type;
|
||||
}
|
||||
|
||||
void Generator::PushType(int type)
|
||||
{
|
||||
typeStack.push(type);
|
||||
}
|
||||
|
||||
void Generator::pushType(int type)
|
||||
{
|
||||
typeStack.push(type);
|
||||
}
|
||||
|
||||
void Generator::popType(int count)
|
||||
{
|
||||
while(count--)
|
||||
{
|
||||
typeStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
@ -329,8 +376,11 @@ namespace pim
|
||||
|
||||
void Generator::LoadVariable(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::Load);
|
||||
Definition d = currentScope->GetDefinition(label);
|
||||
|
||||
pushType(d.Type);
|
||||
writeOpcode(Opcode::Load);
|
||||
|
||||
writeConstant(d.StackPosition+(currentScope->FrameSize-d.MyScope->FrameSize));
|
||||
|
||||
output << "load " << label << std::endl;
|
||||
@ -338,8 +388,12 @@ namespace pim
|
||||
|
||||
void Generator::StoreVariable(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::Store);
|
||||
Definition d = currentScope->GetDefinition(label);
|
||||
AssureType(d.Type);
|
||||
popType(1);
|
||||
|
||||
writeOpcode(Opcode::Store);
|
||||
|
||||
writeConstant(d.StackPosition+(currentScope->FrameSize-d.MyScope->FrameSize));
|
||||
//writeConstantPlaceholderOffset(currentScope->GetDefinition(label).StackPosition, &(currentScope->OldFrameSize));
|
||||
//writeConstant(currentScope->GetDefinition(label).StackPosition);
|
||||
@ -349,6 +403,7 @@ namespace pim
|
||||
|
||||
void Generator::RTConstant(std::string name)
|
||||
{
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Constant);
|
||||
writeConstantMacroPlaceholder(name);
|
||||
|
||||
@ -357,6 +412,7 @@ namespace pim
|
||||
|
||||
void Generator::Constant(std::string constant)
|
||||
{
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Constant);
|
||||
writeConstant(constant);
|
||||
|
||||
@ -374,6 +430,7 @@ namespace pim
|
||||
|
||||
void Generator::Discard()
|
||||
{
|
||||
popType(1);
|
||||
writeOpcode(Opcode::Discard);
|
||||
|
||||
output << "discard" << std::endl;
|
||||
@ -381,6 +438,7 @@ namespace pim
|
||||
|
||||
void Generator::Duplicate()
|
||||
{
|
||||
pushType(typeStack.top());
|
||||
writeOpcode(Opcode::Duplicate);
|
||||
|
||||
output << "duplicate" << std::endl;
|
||||
@ -388,6 +446,8 @@ namespace pim
|
||||
|
||||
void Generator::Add()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Add);
|
||||
|
||||
output << "add" << std::endl;
|
||||
@ -395,6 +455,8 @@ namespace pim
|
||||
|
||||
void Generator::Subtract()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Subtract);
|
||||
|
||||
output << "sub" << std::endl;
|
||||
@ -402,13 +464,36 @@ namespace pim
|
||||
|
||||
void Generator::Multiply()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Multiply);
|
||||
|
||||
|
||||
output << "mul" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::ToInteger()
|
||||
{
|
||||
popType(1);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::ToInteger);
|
||||
|
||||
output << "ftoi" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::ToFloat()
|
||||
{
|
||||
popType(1);
|
||||
pushType(DataType::Float);
|
||||
writeOpcode(Opcode::ToFloat);
|
||||
|
||||
output << "itof" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Divide()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Divide);
|
||||
|
||||
output << "div" << std::endl;
|
||||
@ -416,6 +501,8 @@ namespace pim
|
||||
|
||||
void Generator::Modulus()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Modulus);
|
||||
|
||||
output << "add" << std::endl;
|
||||
@ -444,6 +531,8 @@ namespace pim
|
||||
|
||||
void Generator::GetParticle()
|
||||
{
|
||||
popType(2);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Get);
|
||||
|
||||
output << "getpart" << std::endl;
|
||||
@ -451,6 +540,9 @@ namespace pim
|
||||
|
||||
void Generator::GetPosition()
|
||||
{
|
||||
popType(1);
|
||||
pushType(DataType::Integer);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::Position);
|
||||
|
||||
output << "getpos" << std::endl;
|
||||
@ -458,6 +550,7 @@ namespace pim
|
||||
|
||||
void Generator::KillParticle()
|
||||
{
|
||||
popType(1);
|
||||
writeOpcode(Opcode::Kill);
|
||||
|
||||
output << "kill" << std::endl;
|
||||
@ -465,6 +558,8 @@ namespace pim
|
||||
|
||||
void Generator::LoadProperty(std::string property)
|
||||
{
|
||||
popType(1);
|
||||
pushType(DataType::Integer);
|
||||
writeOpcode(Opcode::LoadProperty);
|
||||
writeConstantPropertyPlaceholder(property);
|
||||
|
||||
@ -473,25 +568,19 @@ namespace pim
|
||||
|
||||
void Generator::StoreProperty(std::string property)
|
||||
{
|
||||
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);
|
||||
writeOpcode(Opcode::JumpEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -500,6 +589,7 @@ namespace pim
|
||||
|
||||
void Generator::JumpNotEqual(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::JumpNotEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -508,6 +598,7 @@ namespace pim
|
||||
|
||||
void Generator::JumpGreater(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::JumpGreater);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -516,6 +607,7 @@ namespace pim
|
||||
|
||||
void Generator::JumpGreaterEqual(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::JumpGreaterEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -524,6 +616,7 @@ namespace pim
|
||||
|
||||
void Generator::JumpLess(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::JumpLess);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -532,6 +625,7 @@ namespace pim
|
||||
|
||||
void Generator::JumpLessEqual(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::JumpLessEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
@ -540,6 +634,7 @@ namespace pim
|
||||
|
||||
void Generator::Jump(std::string label)
|
||||
{
|
||||
popType(2);
|
||||
writeOpcode(Opcode::Jump);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stack>
|
||||
#include <iostream>
|
||||
#include "Token.h"
|
||||
#include "Types.h"
|
||||
namespace pim
|
||||
{
|
||||
namespace compiler
|
||||
@ -36,10 +37,6 @@ namespace pim
|
||||
}
|
||||
~SymbolNotFoundException() throw() {};
|
||||
};
|
||||
class Type
|
||||
{
|
||||
enum { Integer = Token::IntegerSymbol, Decimal = Token::DecimalSymbol };
|
||||
};
|
||||
class Scope;
|
||||
class Definition
|
||||
{
|
||||
@ -93,6 +90,7 @@ namespace pim
|
||||
class Generator
|
||||
{
|
||||
int variableType;
|
||||
std::stack<int> typeStack;
|
||||
std::stack<Scope*> scopes;
|
||||
Scope * currentScope;
|
||||
std::ostream & output;
|
||||
@ -118,6 +116,9 @@ namespace pim
|
||||
|
||||
std::vector<unsigned char> program;
|
||||
|
||||
void pushType(int type);
|
||||
void popType(int count);
|
||||
|
||||
void defineLabel(std::string label);
|
||||
void writeOpcode(int opcode);
|
||||
void writeConstant(std::string constant);
|
||||
@ -130,11 +131,15 @@ namespace pim
|
||||
|
||||
public:
|
||||
Generator();
|
||||
virtual ~Generator();
|
||||
|
||||
std::vector<unsigned char> 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();
|
||||
@ -145,6 +150,7 @@ namespace pim
|
||||
void ScopeVariableType(int type);
|
||||
void ScopeVariable(std::string label);
|
||||
|
||||
void PushType(int type);
|
||||
void PushVariableAddress(std::string label);
|
||||
// void Store();
|
||||
void LoadVariable(std::string label);
|
||||
@ -161,6 +167,8 @@ namespace pim
|
||||
void Divide();
|
||||
void Modulus();
|
||||
void Negate();
|
||||
void ToInteger();
|
||||
void ToFloat();
|
||||
|
||||
void TransformParticle();
|
||||
void CreateParticle();
|
||||
@ -170,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);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fstream>
|
||||
#include "Machine.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Types.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "X86Native.h"
|
||||
namespace pim
|
||||
@ -269,6 +270,8 @@ namespace pim
|
||||
case Opcode::Get:
|
||||
case Opcode::Position:
|
||||
case Opcode::Kill:
|
||||
case Opcode::ToFloat:
|
||||
case Opcode::ToInteger:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ namespace pim
|
||||
{
|
||||
struct Opcode
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
#define OPDEF(name) name,
|
||||
|
@ -1,4 +1,6 @@
|
||||
OPDEF(Load)
|
||||
OPDEF(ToFloat)
|
||||
OPDEF(ToInteger)
|
||||
OPDEF(Store)
|
||||
OPDEF(Constant)
|
||||
OPDEF(Increment)
|
||||
|
@ -1,6 +1,10 @@
|
||||
//Syntax analyser
|
||||
#include "Parser.h"
|
||||
#include "Format.h"
|
||||
#include "Types.h"
|
||||
#include "Exceptions.h"
|
||||
#include "simulation/Particle.h"
|
||||
#include "simulation/StructProperty.h"
|
||||
namespace pim
|
||||
{
|
||||
namespace compiler
|
||||
@ -106,7 +110,18 @@ namespace pim
|
||||
*/
|
||||
void Parser::argument()
|
||||
{
|
||||
generator->ScopeVariableType(token.Symbol);
|
||||
int type;
|
||||
switch(token.Symbol)
|
||||
{
|
||||
case Token::DecimalConstant:
|
||||
type = DataType::Float;
|
||||
break;
|
||||
case Token::IntegerConstant:
|
||||
case Token::ParticleConstant:
|
||||
type = DataType::Integer;
|
||||
break;
|
||||
}
|
||||
generator->ScopeVariableType(type);
|
||||
if(!accept(Token::IntegerSymbol))
|
||||
if(!accept(Token::DecimalSymbol))
|
||||
if(!accept(Token::ParticleSymbol))
|
||||
@ -130,7 +145,18 @@ namespace pim
|
||||
*/
|
||||
void Parser::declaration()
|
||||
{
|
||||
generator->ScopeVariableType(token.Symbol);
|
||||
int type;
|
||||
switch(token.Symbol)
|
||||
{
|
||||
case Token::DecimalConstant:
|
||||
type = DataType::Float;
|
||||
break;
|
||||
case Token::IntegerConstant:
|
||||
case Token::ParticleConstant:
|
||||
type = DataType::Integer;
|
||||
break;
|
||||
}
|
||||
generator->ScopeVariableType(type);
|
||||
if(!accept(Token::IntegerSymbol))
|
||||
if(!accept(Token::DecimalSymbol))
|
||||
if(!accept(Token::ParticleSymbol))
|
||||
@ -296,7 +322,7 @@ namespace pim
|
||||
generator->PushLocalScope(loopLabel+"Start");
|
||||
neighbourVariable = token.Source;
|
||||
expect(Token::Identifier);
|
||||
generator->ScopeVariableType(Token::IntegerConstant);
|
||||
generator->ScopeVariableType(DataType::Integer);
|
||||
generator->ScopeVariable(neighbourVariable);
|
||||
generator->ScopeVariable(xVar);
|
||||
generator->ScopeVariable(yVar);
|
||||
@ -471,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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
13
src/pim/Types.h
Normal file
13
src/pim/Types.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
namespace pim
|
||||
{
|
||||
struct DataType
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Integer,
|
||||
Float
|
||||
};
|
||||
};
|
||||
}
|
@ -11,9 +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);
|
||||
|
||||
while(programCounter < romSize)
|
||||
{
|
||||
Word argument = rom[programCounter].Parameter;
|
||||
@ -215,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]
|
||||
|
@ -25,3 +25,15 @@ std::vector<StructProperty> Particle::GetProperties()
|
||||
properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
|
||||
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
|
||||
by higher-level processes refering to them by name such as Lua or the property tool **/
|
||||
static std::vector<StructProperty> GetProperties();
|
||||
static StructProperty GetProperty(std::string propertyName);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user