summaryrefslogtreecommitdiff
path: root/src/pim
diff options
context:
space:
mode:
Diffstat (limited to 'src/pim')
-rw-r--r--src/pim/Generator.cpp518
-rw-r--r--src/pim/Generator.h178
-rw-r--r--src/pim/Machine.cpp637
-rw-r--r--src/pim/Machine.h120
-rw-r--r--src/pim/Opcodes.h12
-rw-r--r--src/pim/Opcodes.inl28
-rw-r--r--src/pim/Parser.cpp653
-rw-r--r--src/pim/Parser.h79
-rw-r--r--src/pim/Scanner.cpp199
-rw-r--r--src/pim/Scanner.h22
-rw-r--r--src/pim/Token.cpp51
-rw-r--r--src/pim/Token.h83
12 files changed, 0 insertions, 2580 deletions
diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp
deleted file mode 100644
index 3292c8a..0000000
--- a/src/pim/Generator.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-//Code generator for bytecode
-#include <sstream>
-#include <fstream>
-#include "Format.h"
-#include "Generator.h"
-#include "Opcodes.h"
-namespace pim
-{
- namespace compiler
- {
- Generator::Generator() :
- output(std::cout),
- labelCounter(0),
- programCounter(0)
- {
-
- }
-
- void Generator::defineLabel(std::string label)
- {
- Label newLabel;
- newLabel.Name = label;
- newLabel.Position = programCounter;//program.size();
- labelPositions.push_back(newLabel);
- }
-
- void Generator::writeOpcode(int opcode)
- {
- programCounter++;
- program.push_back(opcode);
- }
-
- void Generator::writeConstant(std::string constant)
- {
- writeConstant(format::StringToNumber<int>(constant));
- }
-
- void Generator::writeConstant(int constant)
- {
- program.push_back(constant & 0xFF);
- program.push_back((constant>>8) & 0xFF);
- program.push_back((constant>>16) & 0xFF);
- program.push_back((constant>>24) & 0xFF);
- }
-
- void Generator::writeConstantPlaceholder(std::string label)
- {
- placeholders.push_back(Placeholder(program.size(), label));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantPlaceholder(int * value)
- {
- valuePlaceholders.push_back(ValuePlaceholder(program.size(), value));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantPropertyPlaceholder(std::string property)
- {
- propertyPlaceholders.push_back(PropertyPlaceholder(program.size(), property));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantMacroPlaceholder(std::string macro)
- {
- macroPlaceholders.push_back(MacroPlaceholder(program.size(), macro));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- std::vector<unsigned char> Generator::Finish()
- {
- //All compile time labels, macros, etc
- for(std::vector<Placeholder>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
- {
- bool found = false;
- Placeholder cPosition = *iter;
- for(std::vector<Label>::iterator iter2 = labelPositions.begin(), end2 = labelPositions.end(); iter2 != end2; ++iter2)
- {
- Label cLabel = *iter2;
- if(cPosition.second == cLabel.Name)
- {
- std::cout << "Setting placeholder at " << cPosition.first << " with " << cLabel.Position << " for" << cPosition.second << std::endl;
- found = true;
- program[cPosition.first] = cLabel.Position & 0xFF;
- program[cPosition.first+1] = (cLabel.Position >> 8) & 0xFF;
- program[cPosition.first+2] = (cLabel.Position >> 16) & 0xFF;
- program[cPosition.first+3] = (cLabel.Position >> 24) & 0xFF;
- break;
- }
- }
- if(!found)
- throw SymbolNotFoundException(cPosition.second);
- }
-
- for(std::vector<ValuePlaceholder>::iterator iter = valuePlaceholders.begin(), end = valuePlaceholders.end(); iter != end; ++iter)
- {
- ValuePlaceholder cPosition = *iter;
- int value = *cPosition.second;
-
- std::cout << "Setting value placeholder at " << cPosition.first << " with " << value << std::endl;
-
-
- program[cPosition.first] = value & 0xFF;
- program[cPosition.first+1] = (value >> 8) & 0xFF;
- program[cPosition.first+2] = (value >> 16) & 0xFF;
- program[cPosition.first+3] = (value >> 24) & 0xFF;
- }
-
- //Build file
- int macroSizePos, propSizePos, codeSizePos, macroSize = 0, propSize = 0, codeSize = program.size();
- std::vector<unsigned char> file;
- file.push_back('P');
- file.push_back('V');
- file.push_back('M');
- file.push_back('1');
-
-
- macroSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- propSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- codeSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- //Macros
- for(std::vector<MacroPlaceholder>::iterator iter = macroPlaceholders.begin(), end = macroPlaceholders.end(); iter != end; ++iter)
- {
- MacroPlaceholder cPosition = *iter;
- int position = cPosition.first;
-
- file.push_back(position & 0xFF);
- file.push_back((position >> 8) & 0xFF);
- file.push_back((position >> 16) & 0xFF);
- file.push_back((position >> 24) & 0xFF);
- macroSize += 4;
-
- file.push_back(cPosition.second.length());
- macroSize += 1;
- file.insert(file.end(), cPosition.second.begin(), cPosition.second.end());
- macroSize += cPosition.second.length();
- }
-
- file[macroSizePos] = macroSize & 0xFF;
- file[macroSizePos+1] = (macroSize >> 8) & 0xFF;
- file[macroSizePos+2] = (macroSize >> 16) & 0xFF;
- file[macroSizePos+3] = (macroSize >> 24) & 0xFF;
-
-
- //Macros
- for(std::vector<PropertyPlaceholder>::iterator iter = propertyPlaceholders.begin(), end = propertyPlaceholders.end(); iter != end; ++iter)
- {
- PropertyPlaceholder cPosition = *iter;
- int position = cPosition.first;
-
- file.push_back(position & 0xFF);
- file.push_back((position >> 8) & 0xFF);
- file.push_back((position >> 16) & 0xFF);
- file.push_back((position >> 24) & 0xFF);
- propSize += 4;
-
- file.push_back(cPosition.second.length());
- propSize += 1;
- file.insert(file.end(), cPosition.second.begin(), cPosition.second.end());
- propSize += cPosition.second.length();
- }
-
- file[propSizePos] = propSize & 0xFF;
- file[propSizePos+1] = (propSize >> 8) & 0xFF;
- file[propSizePos+2] = (propSize >> 16) & 0xFF;
- file[propSizePos+3] = (propSize >> 24) & 0xFF;
-
- file.insert(file.end(), program.begin(), program.end());
-
- file[codeSizePos] = codeSize & 0xFF;
- file[codeSizePos+1] = (codeSize >> 8) & 0xFF;
- file[codeSizePos+2] = (codeSize >> 16) & 0xFF;
- file[codeSizePos+3] = (codeSize >> 24) & 0xFF;
-
- std::ofstream newFile("test.pvm");
- for(std::vector<unsigned char>::iterator iter = file.begin(), end = file.end(); iter != end; ++iter)
- {
- newFile.put(*iter);
- }
- newFile.close();
-
- return file;
- }
-
- std::string Generator::UniqueLabel(std::string prefix)
- {
- std::stringstream label;
- label << prefix;
- label << "_";
- label << labelCounter;
- label << "_";
- return label.str();
- }
-
- void Generator::PushScope(std::string label)
- {
- scopes.push(currentScope);
- Scope * prevScope = currentScope;
- currentScope = new Scope();
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::PushLocalScope(std::string label)
- {
- scopes.push(currentScope);
- Scope * prevScope = currentScope;
- currentScope = new Scope();
- currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end());
- currentScope->FrameSize = prevScope->FrameSize;
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::PopScope()
- {
-
- writeOpcode(Opcode::Return);
- writeConstant(currentScope->LocalFrameSize);
-
- output << "return " << currentScope->LocalFrameSize << std::endl;
-
- currentScope = scopes.top();
- scopes.pop();
- }
-
- void Generator::ScopeLabel(std::string label)
- {
- //defineLabelwriteOpcode("." << label);
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::LocalEnter()
- {
- writeOpcode(Opcode::LocalEnter);
- writeConstantPlaceholder(&(currentScope->LocalFrameSize));
-
- output << "enter " << "#" << std::endl;
- }
-
- void Generator::ScopeVariableType(int type)
- {
- variableType = type;
- }
-
- void Generator::ScopeVariable(std::string label)
- {
- currentScope->Definitions.push_back(Definition(label, variableType, currentScope->FrameSize));
- currentScope->FrameSize += 4;
- currentScope->LocalFrameSize += 4;
-
- output << "#declare " << label << " " << currentScope->FrameSize-4 << std::endl;
- }
-
- void Generator::PushVariableAddress(std::string label)
- {
- //writeOpcode("address"); << " " << currentScope->GetDefinition(label).StackPosition
- }
-
- void Generator::LoadVariable(std::string label)
- {
- writeOpcode(Opcode::Load);
- writeConstant(currentScope->GetDefinition(label).StackPosition);
-
- output << "load " << label << std::endl;
- }
-
- void Generator::StoreVariable(std::string label)
- {
- writeOpcode(Opcode::Store);
- writeConstant(currentScope->GetDefinition(label).StackPosition);
-
- output << "store " << label << std::endl;
- }
-
- void Generator::RTConstant(std::string name)
- {
- writeOpcode(Opcode::Constant);
- writeConstantMacroPlaceholder(name);
-
- output << "const " << name << std::endl;
- }
-
- void Generator::Constant(std::string constant)
- {
- writeOpcode(Opcode::Constant);
- writeConstant(constant);
-
- output << "const " << constant << std::endl;
-
- }
-
- void Generator::Increment(std::string constant)
- {
- writeOpcode(Opcode::Increment);
- writeConstant(constant);
-
- output << "inc " << constant << std::endl;
- }
-
- void Generator::Discard()
- {
- writeOpcode(Opcode::Discard);
-
- output << "discard" << std::endl;
- }
-
- void Generator::Duplicate()
- {
- writeOpcode(Opcode::Duplicate);
-
- output << "duplicate" << std::endl;
- }
-
- void Generator::Add()
- {
- writeOpcode(Opcode::Add);
-
- output << "add" << std::endl;
- }
-
- void Generator::Subtract()
- {
- writeOpcode(Opcode::Subtract);
-
- output << "sub" << std::endl;
- }
-
- void Generator::Multiply()
- {
- writeOpcode(Opcode::Multiply);
-
- output << "mul" << std::endl;
- }
-
- void Generator::Divide()
- {
- writeOpcode(Opcode::Divide);
-
- output << "div" << std::endl;
- }
-
- void Generator::Modulus()
- {
- writeOpcode(Opcode::Modulus);
-
- output << "add" << std::endl;
- }
-
- void Generator::Negate()
- {
- writeOpcode(Opcode::Negate);
-
- output << "neg" << std::endl;
- }
-
- void Generator::CreateParticle()
- {
- writeOpcode(Opcode::Create);
-
- output << "create" << std::endl;
- }
-
- void Generator::TransformParticle()
- {
- writeOpcode(Opcode::Transform);
-
- output << "transform" << std::endl;
- }
-
- void Generator::GetParticle()
- {
- writeOpcode(Opcode::Get);
-
- output << "getpart" << std::endl;
- }
-
- void Generator::GetPosition()
- {
- writeOpcode(Opcode::Position);
-
- output << "getpos" << std::endl;
- }
-
- void Generator::KillParticle()
- {
- writeOpcode(Opcode::Kill);
-
- output << "kill" << std::endl;
- }
-
- void Generator::LoadProperty(std::string property)
- {
- writeOpcode(Opcode::LoadProperty);
- writeConstantPropertyPlaceholder(property);
-
- output << "loadprop " << property << std::endl;
- }
-
- void Generator::StoreProperty(std::string property)
- {
- writeOpcode(Opcode::StoreProperty);
- writeConstantPropertyPlaceholder(property);
-
- output << "storeprop " << property << std::endl;
- }
-
- void Generator::IntegerToDecimal()
- {
-
- }
-
- void Generator::DecimalToInteger()
- {
-
- }
-
-
- void Generator::JumpEqual(std::string label)
- {
- writeOpcode(Opcode::JumpEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpe " << label << std::endl;
- }
-
- void Generator::JumpNotEqual(std::string label)
- {
- writeOpcode(Opcode::JumpNotEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpne " << label << std::endl;
- }
-
- void Generator::JumpGreater(std::string label)
- {
- writeOpcode(Opcode::JumpGreater);
- writeConstantPlaceholder(label);
-
- output << "jumpg " << label << std::endl;
- }
-
- void Generator::JumpGreaterEqual(std::string label)
- {
- writeOpcode(Opcode::JumpGreaterEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpge " << label << std::endl;
- }
-
- void Generator::JumpLess(std::string label)
- {
- writeOpcode(Opcode::JumpLess);
- writeConstantPlaceholder(label);
-
- output << "jumpl " << label << std::endl;
- }
-
- void Generator::JumpLessEqual(std::string label)
- {
- writeOpcode(Opcode::JumpLessEqual);
- writeConstantPlaceholder(label);
-
- output << "jumple " << label << std::endl;
- }
-
- void Generator::Jump(std::string label)
- {
- writeOpcode(Opcode::Jump);
- writeConstantPlaceholder(label);
-
- output << "jump " << label << std::endl;
- }
-
-
- void Generator::Call(int arguments, std::string label)
- {
-
- }
-
- void Generator::Return()
- {
-
- }
-
- }
-}
diff --git a/src/pim/Generator.h b/src/pim/Generator.h
deleted file mode 100644
index 4dd2cfe..0000000
--- a/src/pim/Generator.h
+++ /dev/null
@@ -1,178 +0,0 @@
-#pragma once
-
-#include <cstring>
-#include <vector>
-#include <stack>
-#include <iostream>
-#include "Token.h"
-namespace pim
-{
- namespace compiler
- {
- class VariableNotFoundException: public std::exception
- {
- char * error;
- public:
- VariableNotFoundException(std::string variable) {
- error = strdup(std::string("Could not find the variable \""+variable+"\" in the current scope").c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~VariableNotFoundException() throw() {};
- };
-
- class SymbolNotFoundException: public std::exception
- {
- char * error;
- public:
- SymbolNotFoundException(std::string variable) {
- error = strdup(std::string("Could not find the symbol \""+variable+"\".").c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~SymbolNotFoundException() throw() {};
- };
- class Type
- {
- enum { Integer = Token::IntegerSymbol, Decimal = Token::DecimalSymbol };
- };
- class Definition
- {
- public:
- std::string Name;
- int Type;
- int StackPosition;
- Definition(std::string name, int type, int position) :
- Type(type),
- Name(name),
- StackPosition(position)
- {
-
- }
- };
-
- struct Label
- {
- std::string Name;
- int Position;
- };
-
- class Scope
- {
- public:
- std::vector<Definition> Definitions;
- std::vector<Label> Labels;
- int FrameSize;
- int LocalFrameSize;
- Scope():
- FrameSize(0),
- LocalFrameSize(0)
- {
-
- }
- Definition GetDefinition(std::string name)
- {
- for(std::vector<Definition>::iterator iter = Definitions.begin(), end = Definitions.end(); iter != end; ++iter)
- {
- if((*iter).Name == name)
- return *iter;
- }
- throw VariableNotFoundException(name);
- }
- };
-
- class Generator
- {
- int variableType;
- std::stack<Scope*> scopes;
- Scope * currentScope;
- std::ostream & output;
- int labelCounter;
- int programCounter;
-
- typedef std::pair<int, std::string> Placeholder;
- std::vector<Placeholder> placeholders;
-
- typedef std::pair<int, int*> ValuePlaceholder;
- std::vector<ValuePlaceholder> valuePlaceholders;
-
- typedef std::pair<int, std::string> PropertyPlaceholder;
- std::vector<PropertyPlaceholder> propertyPlaceholders;
-
- typedef std::pair<int, std::string> MacroPlaceholder;
- std::vector<MacroPlaceholder> macroPlaceholders;
-
- std::vector<Label> labelPositions;
-
- std::vector<unsigned char> program;
-
- void defineLabel(std::string label);
- void writeOpcode(int opcode);
- void writeConstant(std::string constant);
- void writeConstant(int constant);
- void writeConstantPlaceholder(std::string label);
- void writeConstantPlaceholder(int * value);
- void writeConstantMacroPlaceholder(std::string macro);
- void writeConstantPropertyPlaceholder(std::string property);
-
- public:
- Generator();
-
- std::vector<unsigned char> Finish();
-
- std::string UniqueLabel(std::string prefix);
-
- void PushScope(std::string label);
- void PushLocalScope(std::string label);
- void LocalEnter();
- void PopScope();
-
- void ScopeLabel(std::string label);
- void ScopeVariableType(int type);
- void ScopeVariable(std::string label);
-
- void PushVariableAddress(std::string label);
-// void Store();
- void LoadVariable(std::string label);
- void StoreVariable(std::string label);
-
- void Duplicate();
- void Discard();
- void RTConstant(std::string name);
- void Constant(std::string constant);
- void Increment(std::string constant);
- void Add();
- void Subtract();
- void Multiply();
- void Divide();
- void Modulus();
- void Negate();
-
- void TransformParticle();
- void CreateParticle();
- void GetParticle();
- void GetPosition();
- void KillParticle();
- 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);
- void JumpGreaterEqual(std::string label);
- void JumpLess(std::string label);
- void JumpLessEqual(std::string label);
- void Jump(std::string label);
-
- void Call(int arguments, std::string label);
- void Return();
- };
- }
-}
diff --git a/src/pim/Machine.cpp b/src/pim/Machine.cpp
deleted file mode 100644
index a954d31..0000000
--- a/src/pim/Machine.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-//Virtual machine
-
-#include <iostream>
-#include "Machine.h"
-#include "Opcodes.h"
-#include "simulation/Simulation.h"
-namespace pim
-{
- /*unsigned char * rom;
- int romSize;
- int romMask;
-
- unsigned char * ram;
- int ramSize;
- int ramMask;
-
- int programStack;
- int callStack;*/
-
- VirtualMachine::VirtualMachine(Simulation * simulation) :
- rom(NULL),
- ram(NULL),
- sim(simulation)
- {
-
- }
-
- void VirtualMachine::LoadProgram(std::vector<unsigned char> fileData)
- {
- int lastBit = 0;
-
- if(!(fileData[0] == 'P' && fileData[1] == 'V' && fileData[2] == 'M' && fileData[3] == '1' && fileData.size() >= 16))
- {
- throw InvalidProgramException();
- }
-
- int macroSize = 0, propSize = 0, codeSize = 0;
- macroSize = fileData[4];
- macroSize |= fileData[5] << 8;
- macroSize |= fileData[6] << 16;
- macroSize |= fileData[7] << 24;
-
- propSize = fileData[8];
- propSize |= fileData[9] << 8;
- propSize |= fileData[10] << 16;
- propSize |= fileData[11] << 24;
-
- codeSize = fileData[12];
- codeSize |= fileData[13] << 8;
- codeSize |= fileData[14] << 16;
- codeSize |= fileData[15] << 24;
-
- if(fileData.size() < 16 + macroSize + propSize + codeSize)
- {
- throw InvalidProgramException();
- }
-
- //std::vector<std::pair<int, int> > insertions;
-
- int macroOffset = 16;
- int propOffset = macroOffset+macroSize;
- int codeOffset = propOffset+propSize;
-
-
- int filePosition = macroOffset;
- while(filePosition + 4 < macroSize + macroOffset)
- {
- std::string macro;
- int macroPosition;
- int macroValue;
-
- macroPosition = fileData[filePosition++];
- macroPosition |= fileData[filePosition++] << 8;
- macroPosition |= fileData[filePosition++] << 16;
- macroPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > macroSize + macroOffset)
- {
- throw InvalidProgramException();
- }
-
- macro.insert(macro.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
- for(int i = 0; i < PT_NUM; i++)
- {
- if(sim->elements[i].Enabled && sim->elements[i].Identifier == macro)
- {
- macroValue = i;
- resolved = true;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(macro);
- }
-
- if(macroPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Macro insertion [" << macro << "] at " << macroPosition << " with " << macroValue << std::endl;
-
- fileData[codeOffset+macroPosition] = macroValue & 0xFF;
- fileData[codeOffset+macroPosition+1] = (macroValue >> 8) & 0xFF;
- fileData[codeOffset+macroPosition+2] = (macroValue >> 16) & 0xFF;
- fileData[codeOffset+macroPosition+3] = (macroValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- filePosition = propOffset;
- while(filePosition + 4 < propSize + propOffset)
- {
- std::string prop;
- int propPosition;
- int propValue;
-
- propPosition = fileData[filePosition++];
- propPosition |= fileData[filePosition++] << 8;
- propPosition |= fileData[filePosition++] << 16;
- propPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > propSize + propOffset)
- {
- throw InvalidProgramException();
- }
-
- prop.insert(prop.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
-
- std::vector<StructProperty> properties = Particle::GetProperties();
- for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
- {
- StructProperty property = *iter;
- std::cout << property.Offset << std::endl;
- if(property.Name == prop &&
- (property.Type == StructProperty::ParticleType ||
- property.Type == StructProperty::Colour ||
- property.Type == StructProperty::Integer ||
- property.Type == StructProperty::UInteger ||
- property.Type == StructProperty::Float)
- )
- {
- propValue = property.Offset;
- resolved = true;
- break;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(prop);
- }
-
- if(propPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Property insertion [" << prop << "] at " << propPosition << " with " << propValue << std::endl;
-
- fileData[codeOffset+propPosition] = propValue & 0xFF;
- fileData[codeOffset+propPosition+1] = (propValue >> 8) & 0xFF;
- fileData[codeOffset+propPosition+2] = (propValue >> 16) & 0xFF;
- fileData[codeOffset+propPosition+3] = (propValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- std::vector<unsigned char> programData;
- programData.insert(programData.begin(), fileData.begin()+codeOffset, fileData.begin()+codeOffset+codeSize);
-
- romSize = programData.size();
-
- for (lastBit = 0; romSize > (1 << lastBit); lastBit++ ) { }
- romSize = 1 << lastBit;
- romMask = romSize - 1;
-
- rom = new Instruction[romSize];
-
- int pc = 0;
- int programPosition = 0;
-
- while(programPosition < programData.size())
- {
- int argSize = 0;
- Instruction instruction;
- instruction.Opcode = programData[programPosition++];
- if(argSize = OpcodeArgSize(instruction.Opcode))
- {
- if(argSize == 4 && programPosition+3 < programData.size())
- {
- int tempInt = 0;
- tempInt |= programData[programPosition];
- tempInt |= programData[programPosition+1] << 8;
- tempInt |= programData[programPosition+2] << 16;
- tempInt |= programData[programPosition+3] << 24;
-
-
- std::cout << "Got integer " << tempInt << std::endl;
-
- if(instruction.Opcode == Opcode::LoadProperty || instruction.Opcode == Opcode::StoreProperty)
- {
- if(tempInt > offsetof(Particle, dcolour))
- throw InvalidProgramException();
- }
-
- instruction.Parameter.Integer = tempInt;
-
- programPosition += 4;
- }
- }
- else
- {
- instruction.Parameter.Integer = 0;
- }
- rom[pc++] = instruction;
- }
- romSize = pc;
-
- ramSize = 1024;
- ramMask = ramSize - 1;
-
- ram = new unsigned char[ramSize];
- programStack = ramSize-1;
- callStack = ramSize-260;
-
- framePointer = callStack;
- callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
- }
-
- int VirtualMachine::OpcodeArgSize(int opcode)
- {
- switch(opcode)
- {
- case Opcode::Load:
- case Opcode::Store:
- case Opcode::Constant:
- case Opcode::Increment:
- case Opcode::JumpEqual:
- case Opcode::JumpNotEqual:
- case Opcode::JumpGreater:
- case Opcode::JumpGreaterEqual:
- case Opcode::JumpLess:
- case Opcode::JumpLessEqual:
- case Opcode::Jump:
- case Opcode::Return:
- case Opcode::LocalEnter:
- case Opcode::LoadProperty:
- case Opcode::StoreProperty:
- return 4;
- case Opcode::Discard:
- case Opcode::Duplicate:
- case Opcode::Add:
- case Opcode::Subtract:
- case Opcode::Multiply:
- case Opcode::Divide:
- case Opcode::Modulus:
- case Opcode::Negate:
- case Opcode::Create:
- case Opcode::Transform:
- case Opcode::Get:
- case Opcode::Position:
- case Opcode::Kill:
- return 0;
- }
- }
-
- void VirtualMachine::Run()
- {
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- //std::string names[] = { "Load", "Store", "Constant", "Increment", "Discard", "Duplicate", "Add", "Subtract", "Multiply", "Divide", "Modulus", "Negate", "Create", "Transform", "Get", "Position", "Kill", "JumpEqual", "JumpNotEqual", "JumpGreater", "JumpGreaterEqual", "JumpLess", "JumpLessEqual", "Jump", "Return", "LocalEnter"};
-
- Word temp1;
- Word temp2;
- Word temp3;
- Word temp4;
- int temp;
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- //std::cerr << programCounter << "\t" << names[rom[programCounter].Opcode] << "\t" << argument.Integer << std::endl;//"\t";
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- PSPush(CSA(argument.Integer));
- break;
- case Opcode::Store:
- CSA(argument.Integer) = PSPop();
- break;
- case Opcode::Constant:
- PSPush(argument);
- break;
- case Opcode::Increment:
- PS().Integer += argument.Integer;
- break;
- case Opcode::Discard:
- programStack += WORDSIZE;
- break;
- case Opcode::Duplicate:
- PSPush(PS());
- break;
- case Opcode::Add:
- PSPush(PSPop().Integer + PSPop().Integer);
- break;
- case Opcode::Subtract:
- temp1 = PSPop();
- PSPush(PSPop().Integer - temp1.Integer);
- break;
- case Opcode::Multiply:
- PSPush(PSPop().Integer * PSPop().Integer);
- break;
- case Opcode::Divide:
- temp1 = PSPop();
- PSPush(PSPop().Integer / temp1.Integer);
- break;
- case Opcode::Modulus:
- temp1 = PSPop();
- PSPush(PSPop().Integer % temp1.Integer);
- break;
- case Opcode::Negate:
- PS().Integer = -PS().Integer;
- break;
- case Opcode::Create:
- temp1 = PSPop();
- temp2 = PSPop();
- temp3 = PSPop();
- PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- PSPop();
- PSPop();
- 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);
- 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);
- break;
- case Opcode::Kill:
- sim->kill_part(PSPop().Integer);
- PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- temp1 = PSPop();
- PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- if(PSPop().Integer == PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpNotEqual:
- if(PSPop().Integer != PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreater:
- temp1 = PSPop();
- if(PSPop().Integer > temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreaterEqual:
- temp1 = PSPop();
- if(PSPop().Integer >= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLess:
- temp1 = PSPop();
- if(PSPop().Integer < temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLessEqual:
- temp1 = PSPop();
- if(PSPop().Integer <= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::Jump:
- programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- callStack += argument.Integer;
- break;
- case Opcode::LocalEnter:
- callStack -= argument.Integer;
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::Compile()
- {
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- emit("83 EF 04"); //sub edi 4
-
- //Load value at base stack + offset into eax
- emit("8B 85"); //mov eax [ebp+ram+offset]
- emit((intptr_t) (ram - argument.Integer));
-
- //Store value in eax onto top of program stack
- emit("89 07"); //mov [edi], eax
- emit((intptr_t) (ram));
- break;
- case Opcode::Store:
- //Load value on top of the program stack into eax
- emit("8B 07"); //mov eax [edi]
- emit((intptr_t) (ram));
-
- //Load value in eax onto top of program stack
- emit("89 85"); //mov [ebp+ram+offset], eax
- emit((intptr_t) (ram - argument.Integer));
-
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Constant:
- emit("83 EF 04"); //sub edi 4
-
- emit("C7 07"); //mov [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Increment:
- emit("81 07"); //add [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Discard:
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Duplicate:
- //Copy value on stack into register
- emit("8B 07"); //mov eax [edi]
- //Adjust program stack pointer
- emit("83 EF 04"); //sub edi 4
- //Move value in eax into program stack
- emit("89 07"); //mov [edi], eax
- break;
- case Opcode::Add:
- emit("8B 07"); //mov eax [edi]
- emit("01 47 04"); //add [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Subtract:
- emit("8B 07"); //mov eax [edi]
- emit("29 47 04"); //sub [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Multiply:
- emit("8B 47 04"); //mov eax [edi+4]
- emit("F7 2F"); //imul [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Divide:
- emit("8B 47 04");//mov eax [edi+4]
- emit("99"); //cdq
- emit("F7 3F"); //idiv [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Modulus:
- emit("8B 47 04"); // mov eax [edi+4]
- emit("99"); // cdq
- emit("F7 3F"); // idiv [edi]
- emit("89 57 04"); // mov [edi+4] edx
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Negate:
- emit("F7 1F"); //neg [edi]
- break;
- case Opcode::Create:
- //temp1 = PSPop();
- //temp2 = PSPop();
- //temp3 = PSPop();
- //PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- //PSPop();
- //PSPop();
- //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);
- 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);
- break;
- case Opcode::Kill:
- //sim->kill_part(PSPop().Integer);
- //PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- //PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- //temp1 = PSPop();
- //PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("75 06"); //jne +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpNotEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("74 06"); //je +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreater:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7E 06"); //jng +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreaterEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7C 06"); //jnge +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLess:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7D 06"); //jnl +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLessEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7F 06"); //jnle +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::Jump:
- //programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- emit("81 C6"); //add esi constant
- emit(argument.Integer);
- break;
- case Opcode::LocalEnter:
- emit("81 EE"); //sub esi constant
- emit(argument.Integer);
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::emit(std::string opcode)
- {
-
- }
-
- void VirtualMachine::emit(int constant)
- {
-
- }
-
- void VirtualMachine::CallCompiled(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::CallCompiled(int entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(int entryPoint)
- {
- programCounter = entryPoint;
- Run();
- }
-}
diff --git a/src/pim/Machine.h b/src/pim/Machine.h
deleted file mode 100644
index 0cbac4c..0000000
--- a/src/pim/Machine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <string>
-#include <cstring>
-
-class Simulation;
-namespace pim
-{
- union Word
- {
- int Integer;
- float Decimal;
-
- Word(int integer) : Integer(integer) {}
- Word(float decimal) : Decimal(decimal) {}
- Word() {}
- };
- struct Instruction
- {
- int Opcode;
- Word Parameter;
- };
- class InvalidProgramException: public std::exception
- {
- public:
- InvalidProgramException() { }
- const char * what() const throw()
- {
- return "Invalid program";
- }
- ~InvalidProgramException() throw() {};
- };
- class UnresolvedValueException: public std::exception
- {
- char * error;
- public:
- UnresolvedValueException(std::string value) {
- error = strdup(std::string("Unresolved value: " + value).c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~UnresolvedValueException() throw() {};
- };
- class VirtualMachine
- {
-
- #define WORDSIZE 4
-
- //#define OPDEF(name) void op##name(int parameter);
- //#include "Opcodes.inl"
- //#undef OPDEF
-
- Simulation * sim;
-
- Instruction * rom;
- int romSize;
- int romMask;
-
- unsigned char * compiledRom;
- int compiledRomSize;
-
- unsigned char * ram;
- int ramSize;
- int ramMask;
-
- #define CSA(argument) (*((Word*)&ram[framePointer-argument]))
- #define CS() (*((Word*)&ram[callStack]))
- #define PS() (*((Word*)&ram[programStack]))
- #define PPROP(index, property) (*((Word*)(((char*)&sim->parts[(index)])+property)))
-
- int programStack; //Points to the item on top of the Program Stack
- int callStack; //Points to the item on top of the call stack
- int framePointer; //Points to the bottom (first item) on the current frame of the call stack
-
- //Instruction * instructions;
-
- int programCounter;
-
- void emit(std::string opcode);
- void emit(int constant);
- public:
- VirtualMachine(Simulation * sim);
- int OpcodeArgSize(int opcode);
- void LoadProgram(std::vector<unsigned char> programData);
- void Run();
- void Compile();
- void CallCompiled(std::string entryPoint);
- void CallCompiled(int entryPoint);
- void Call(std::string entryPoint);
- void Call(int entryPoint);
- inline void PSPush(Word word)
- {
- programStack -= WORDSIZE;
- PS() = word;
- }
-
- inline Word PSPop()
- {
- Word word = PS();
- programStack += WORDSIZE;
- return word;
- }
-
- inline void CSPush(Word word)
- {
- callStack -= WORDSIZE;
- CS() = word;
- }
-
- inline Word CSPop()
- {
- Word word = CS();
- callStack += WORDSIZE;
- return word;
- }
- };
-}
diff --git a/src/pim/Opcodes.h b/src/pim/Opcodes.h
deleted file mode 100644
index a701e97..0000000
--- a/src/pim/Opcodes.h
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace pim
-{
- struct Opcode
- {
- enum
- {
- #define OPDEF(name) name,
- #include "Opcodes.inl"
- #undef OPDEF
- };
- };
-}
diff --git a/src/pim/Opcodes.inl b/src/pim/Opcodes.inl
deleted file mode 100644
index 4b28294..0000000
--- a/src/pim/Opcodes.inl
+++ /dev/null
@@ -1,28 +0,0 @@
-OPDEF(Load)
-OPDEF(Store)
-OPDEF(Constant)
-OPDEF(Increment)
-OPDEF(Discard)
-OPDEF(Duplicate)
-OPDEF(Add)
-OPDEF(Subtract)
-OPDEF(Multiply)
-OPDEF(Divide)
-OPDEF(Modulus)
-OPDEF(Negate)
-OPDEF(Create)
-OPDEF(Transform)
-OPDEF(Get)
-OPDEF(Position)
-OPDEF(Kill)
-OPDEF(LoadProperty)
-OPDEF(StoreProperty)
-OPDEF(JumpEqual)
-OPDEF(JumpNotEqual)
-OPDEF(JumpGreater)
-OPDEF(JumpGreaterEqual)
-OPDEF(JumpLess)
-OPDEF(JumpLessEqual)
-OPDEF(Jump)
-OPDEF(Return)
-OPDEF(LocalEnter) \ No newline at end of file
diff --git a/src/pim/Parser.cpp b/src/pim/Parser.cpp
deleted file mode 100644
index 0165141..0000000
--- a/src/pim/Parser.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-//Syntax analyser
-#include "Parser.h"
-#include "Format.h"
-namespace pim
-{
- namespace compiler
- {
- Parser::Parser(std::stringstream & source_) :
- source(source_)
- {
- scanner = new Scanner(source);
- generator = new Generator();
-
- token = scanner->NextToken();
-
- }
-
- std::vector<unsigned char> Parser::Compile()
- {
- program();
- return generator->Finish();
- }
-
- /*
- <program> ::= <function list>
- */
- void Parser::program()
- {
- functionList();
- }
-
- /*
- <function list> ::= <function> | <function> <function list>
- */
- void Parser::functionList()
- {
- function();
- while(look(Token::FunctionSymbol))
- function();
- }
-
- /*
- <function> ::= function identifier ( <declaration list> ) <block> end
- */
- void Parser::function()
- {
- std::string functionName;
-
- expect(Token::FunctionSymbol);
-
- functionName = token.Source;
- //generator->ScopeLabel(functionName); //Function name
- generator->PushScope(functionName);
- expect(Token::Identifier);
-
- expect(Token::LeftBracket);
- if(!accept(Token::RightBracket))
- {
- argumentList();
- expect(Token::RightBracket);
- }
- block();
- expect(Token::EndSymbol);
- generator->Return();
-
- generator->PopScope();
- }
-
- /*
- <function call> ::= identifier ( <expression list> )
- */
- void Parser::functionCall()
- {
- std::string functionName;
-
- functionName = token.Source;
- expect(Token::Identifier);
- expect(Token::LeftBracket);
- expressionList();
- expect(Token::RightBracket);
- //generator->Call(functionName);
- }
-
- /*
- <block> ::= <declaration list> <statement list>
- */
- void Parser::block()
- {
- if(look(Token::IntegerSymbol) || look(Token::DecimalSymbol) || look(Token::ParticleSymbol))
- declarationList();
- statementList();
- }
-
- /*
- <argument list> ::= <argument> | <argument> , <argument list>
- */
- void Parser::argumentList()
- {
- argument();
- while(accept(Token::CommaSymbol))
- argument();
- }
-
- /*
- <argument> ::= integer identifier | decimal identifier | particle identifier
- */
- void Parser::argument()
- {
- generator->ScopeVariableType(token.Symbol);
- if(!accept(Token::IntegerSymbol))
- if(!accept(Token::DecimalSymbol))
- if(!accept(Token::ParticleSymbol))
- throw ParserExpectException(token, "type name");
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- }
-
- /*
- <declaration list> ::= <declaration> | <declaration> , <declaration list>
- */
- void Parser::declarationList()
- {
- declaration();
- while(accept(Token::CommaSymbol))
- declaration();
- }
-
- /*
- <declaration> ::= integer <identifier list> | decimal <identifier list> | particle <identifier list>
- */
- void Parser::declaration()
- {
- generator->ScopeVariableType(token.Symbol);
- if(!accept(Token::IntegerSymbol))
- if(!accept(Token::DecimalSymbol))
- if(!accept(Token::ParticleSymbol))
- throw ParserExpectException(token, "type name");
- identifierList();
- }
-
- /*
- <identifier list> ::= identifier | identifier , <identifier list>
- */
- void Parser::identifierList()
- {
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- while(accept(Token::CommaSymbol))
- {
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- }
- }
-
- /*
- <statement list> ::= <statement> | <statement> <statement list>
- */
- void Parser::statementList()
- {
- statement();
- while(!look(Token::EndSymbol) && !look(Token::ElseIfSymbol))
- statement();
- }
-
- /*
- <statement> ::= <neighbour statement> | <if statement> | <assignment statement> | <function call> | <particle action> | break | continue
- */
- void Parser::statement()
- {
- //generator->Begin(NonTerminal::Statement);
- if(look(Token::NeighbourSymbol))
- {
- neighbourStatement();
- }
- else if(look(Token::IfSymbol))
- {
- ifStatement();
- }
- else if(look(Token::CreateSymbol) || look(Token::KillSymbol) || look(Token::GetSymbol) || look(Token::TransformSymbol))
- {
- particleAction();
- generator->Discard();
- }
- else if(look(Token::BreakSymbol))
- {
- expect(Token::BreakSymbol);
- generator->Jump(breakLabel);
- }
- else if(look(Token::ContinueSymbol))
- {
- expect(Token::ContinueSymbol);
- generator->Jump(continueLabel);
- }
- else if(look(Token::Identifier))
- {
- assigmentStatement();
- }
- //generator->End(NonTerminal::Statement);
- }
-
- /*
- <particle action> ::= <kill statement> | <create statement> | <transform statement>
- */
- void Parser::particleAction()
- {
- if(look(Token::KillSymbol))
- {
- killStatement();
- }
- else if(look(Token::CreateSymbol))
- {
- createStatement();
- }
- else if(look(Token::TransformSymbol))
- {
- transformStatement();
- }
-
- }
-
- /*
- <kill statement> ::= kill ( <expression> )
- */
- void Parser::killStatement()
- {
- expect(Token::KillSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::RightBracket);
- generator->KillParticle();
- }
-
- /*
- <create statement> ::= create ( <expression>, <expression>, <expression>, <expression> )
- */
- void Parser::createStatement()
- {
- expect(Token::CreateSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->CreateParticle();
- }
-
- /*
- <transform statement> ::= transform ( <expression>, <expression> )
- */
- void Parser::transformStatement()
- {
- expect(Token::TransformSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->TransformParticle();
- }
-
- /*
- <get statement> ::= get ( <expression>, <expression> )
- */
- void Parser::getStatement()
- {
- expect(Token::GetSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->GetParticle();
- }
-
- /*
- <neighbour statement> ::= neighbour identifier for <expression> do <block> end | neighbour identifier for <expression>, <expression> do <block> end
- */
- void Parser::neighbourStatement()
- {
- std::string neighbourVariable;
- std::string loopLabel = generator->UniqueLabel("neighbour");
- std::string xVar = loopLabel+"X";
- std::string xMin = loopLabel+"minX";
- std::string xMax = loopLabel+"maxX";
- std::string yVar = loopLabel+"Y";
- std::string yMax = loopLabel+"maxY";
- breakLabel = loopLabel+"End";
- continueLabel = loopLabel+"Next";
-
- expect(Token::NeighbourSymbol);
-
- generator->PushLocalScope(loopLabel+"Start");
- neighbourVariable = token.Source;
- expect(Token::Identifier);
- generator->ScopeVariableType(Token::IntegerConstant);
- generator->ScopeVariable(neighbourVariable);
- generator->ScopeVariable(xVar);
- generator->ScopeVariable(yVar);
- generator->ScopeVariable(xMin);
- generator->ScopeVariable(xMax);
- generator->ScopeVariable(yMax);
-
- generator->LocalEnter();
-
- expect(Token::OfSymbol);
-
- //Initialise position
- expression();
- generator->GetPosition();
- generator->Duplicate();
- generator->Increment("-1");
- generator->StoreVariable(yVar);
- generator->Increment("1");
- generator->StoreVariable(yMax);
-
- generator->Duplicate();
- generator->Increment("-1");
- generator->Duplicate();
- generator->StoreVariable(xVar);
- generator->StoreVariable(xMin);
- generator->Increment("1");
- generator->StoreVariable(xMax);
-
- //if(accept(Token::CommaSymbol))
- // expression();
- expect(Token::DoSymbol);
-
- generator->ScopeLabel(loopLabel+"Next");
-
-
-
-
-
- //Check X
- generator->LoadVariable(xVar);
- generator->LoadVariable(xMax);
- //generator->Duplicate(); //Duplicate xvar so it can be used for incrementing
-
- generator->JumpLessEqual(loopLabel+"Begin");
- //if(xVar > xMax) {
-
- //Reset X, increment Y
- generator->LoadVariable(xMin);
- generator->StoreVariable(xVar);
-
- generator->LoadVariable(yVar);
- generator->Increment("1");
- generator->Duplicate();
- generator->StoreVariable(yVar);
-
-
- //Check Y
- generator->LoadVariable(yMax);
- generator->JumpGreater(loopLabel+"End");
-
- //}
-
- //Start of loop
- generator->ScopeLabel(loopLabel+"Begin");
-
- generator->LoadVariable(xVar);
- generator->LoadVariable(yVar);
- generator->GetParticle();
- generator->StoreVariable(neighbourVariable);
-
- block();
-
- //Increment X
- generator->LoadVariable(xVar);
- generator->Increment("1");
- generator->StoreVariable(xVar);
-
- //Next element
- generator->Jump(loopLabel+"Next");
-
- generator->ScopeLabel(loopLabel+"End");
- generator->Return();
- generator->PopScope();
- expect(Token::EndSymbol);
- }
-
- /*
- <if statement> ::= if <condition> then <block> end
- */
- void Parser::ifStatement()
- {
- std::string label = generator->UniqueLabel("if");
- int blockNum = 0;
- expect(Token::IfSymbol);
- condition(label+format::NumberToString<int>(blockNum));
- expect(Token::ThenSymbol);
- block();
- while(accept(Token::ElseIfSymbol))
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- condition(label+format::NumberToString<int>(blockNum));
- expect(Token::ThenSymbol);
- block();
- }
- if(accept(Token::ElseSymbol))
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- block();
- }
- else
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- }
- expect(Token::EndSymbol);
- //generator->End(NonTerminal::IfStatement);
- }
-
- /*
- <condition> ::= <expression> <conditional operator> <expression>
- */
- void Parser::condition(std::string jumpLabel)
- {
- expression();
-
- Token token = forward();
-
- expression();
-
- if(token.Symbol == Token::GreaterSymbol)
- {
- generator->JumpLessEqual(jumpLabel);
- }
- else if(token.Symbol == Token::GreaterEqualSymbol)
- {
- generator->JumpLess(jumpLabel);
- }
- else if(token.Symbol == Token::EqualSymbol)
- {
- generator->JumpNotEqual(jumpLabel);
- }
- else if(token.Symbol == Token::NotEqualSymbol)
- {
- generator->JumpEqual(jumpLabel);
- }
- else if(token.Symbol == Token::LessSymbol)
- {
- generator->JumpGreaterEqual(jumpLabel);
- }
- else if(token.Symbol == Token::LessEqualSymbol)
- {
- generator->JumpGreater(jumpLabel);
- }
- else
- throw ParserExpectException(token, "conditional operator");
- }
-
- /*
- <assigment statement> ::= identifier = <expression> | identifier.property = <expression>
- */
- void Parser::assigmentStatement()
- {
- std::string variable = token.Source;
- expect(Token::Identifier);
- if(accept(Token::AssignSymbol))
- {
- expression();
- generator->StoreVariable(variable);
- }
- else if(accept(Token::DotSymbol))
- {
- std::string property = token.Source;
- expect(Token::Identifier);
- expect(Token::AssignSymbol);
- expression();
- generator->LoadVariable(variable);
- generator->StoreProperty(property);
- }
- }
-
- /*
- <expression list> ::= <expression> | <expression> , <expression list>
- */
- void Parser::expressionList()
- {
- //generator->Begin(NonTerminal::ExpressionList);
- expression();
- while(accept(Token::CommaSymbol))
- expression();
- //generator->End(NonTerminal::ExpressionList);
- }
-
- /*
- <expression> ::= <term> | <expression> + <term> | <expression> - <term>
- */
- void Parser::expression()
- {
- term();
- int as = token.Symbol;
- while(accept(Token::PlusSymbol) || accept(Token::MinusSymbol))
- {
- term();
- if(as == Token::PlusSymbol)
- generator->Add();
- else if(as == Token::MinusSymbol)
- generator->Subtract();
- }
- //generator->End(NonTerminal::Expression);
- }
-
- /*
- <term> ::= <factor> | <term> * <factor> | <term> / <factor>
- */
- void Parser::term()
- {
- //generator->Begin(NonTerminal::Term);
- factor();
- int md = token.Symbol;
- while(accept(Token::MultiplySymbol) || accept(Token::DivideSymbol))
- {
- factor();
- if(md == Token::MultiplySymbol)
- generator->Multiply();
- else if(md == Token::DivideSymbol)
- generator->Divide();
- }
- //generator->End(NonTerminal::Term);
- }
-
- /*
- <factor> ::= <variable value> | - <variable value> | numberConstant | - numberConstant | ( <expression> ) | - ( <expression> )
- */
- void Parser::factor()
- {
- bool doNegate = false;
- std::string factor = token.Source;
- if(accept(Token::MinusSymbol))
- {
- factor = token.Source;
- doNegate = true;
- }
- if(accept(Token::IntegerConstant) || accept(Token::DecimalConstant))
- {
- if(doNegate)
- {
- doNegate = false;
- generator->Constant("-" + factor);
- }
- else
- generator->Constant(factor);
- }
- else if(accept(Token::LeftBracket))
- {
- expression();
- expect(Token::RightBracket);
- }
- else
- {
- variableValue();
- }
- if(doNegate)
- generator->Negate();
- }
-
- /*
- <variable value> ::= <function call> | identifier | identifier.property | rtmacro | <particle action>
- */
- void Parser::variableValue()
- {
- std::string variable = token.Source;
- if(accept(Token::Identifier))
- {
- if(look(Token::LeftBracket))
- {
- back();
- functionCall();
- }
- else
- {
- if(accept(Token::DotSymbol))
- {
- std::string property = token.Source;
- expect(Token::Identifier);
- generator->LoadVariable(variable);
- generator->LoadProperty(property);
- }
- else
- {
- generator->LoadVariable(variable);
- }
- }
- }
- else if(accept(Token::RTMacro))
- {
- generator->RTConstant(variable);
- }
- else
- {
- particleAction();
- }
- }
-
- bool Parser::accept(int symbol)
- {
- if(symbol == token.Symbol)
- {
- lastToken = token;
- if(previousTokens.size())
- {
- token = previousTokens.top();
- previousTokens.pop();
- }
- else
- token = scanner->NextToken();
- //std::cout << "Symbol " << Token::SymbolNames[symbol] << " " << lastToken.Source << std::endl;
- return true;
- }
- //std::cout << "Bad Symbol " << Token::SymbolNames[symbol] << " " << token.Source << " (" << token.GetName() << ")" << std::endl;
- return false;
- }
-
-
- bool Parser::look(int symbol)
- {
- if(symbol == token.Symbol)
- return true;
- return false;
- }
-
- void Parser::back()
- {
- previousTokens.push(token);
- token = lastToken;
- }
-
- Token Parser::forward()
- {
- lastToken = token;
- if(previousTokens.size())
- {
- token = previousTokens.top();
- previousTokens.pop();
- }
- else
- token = scanner->NextToken();
- return lastToken;
- }
-
- void Parser::expect(int symbol)
- {
- if(!accept(symbol))
- throw ParserExpectException(token, symbol);
- }
- }
-}
diff --git a/src/pim/Parser.h b/src/pim/Parser.h
deleted file mode 100644
index 19a2835..0000000
--- a/src/pim/Parser.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <string>
-#include <cstring>
-#include <sstream>
-#include "Scanner.h"
-#include "Generator.h"
-#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 Parser
- {
- std::stringstream & source;
- Generator * generator;
- Scanner * scanner;
- Token token;
- Token lastToken;
- std::string breakLabel;
- std::string continueLabel;
- std::stack<Token> previousTokens;
-
- void program();
- void functionList();
- void function();
- void functionCall();
- void block();
- void argumentList();
- void argument();
- void declarationList();
- void declaration();
- void identifierList();
- void statementList();
- void statement();
- void neighbourStatement();
- void ifStatement();
- void condition(std::string jumpLabel);
- void assigmentStatement();
- void particleAction();
- void killStatement();
- void getStatement();
- void createStatement();
- void transformStatement();
- void expressionList();
-
- void expression();
- void term();
- void factor();
- void variableValue();
-
- Token forward();
- bool accept(int symbol);
- bool look(int symbol);
- void back();
- void expect(int symbol);
- public:
- Parser(std::stringstream & source_);
-
- std::vector<unsigned char> Compile();
- };
- }
-}
diff --git a/src/pim/Scanner.cpp b/src/pim/Scanner.cpp
deleted file mode 100644
index 4ceb942..0000000
--- a/src/pim/Scanner.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//Lexical analyser
-#include <algorithm>
-#include <cctype>
-#include "Scanner.h"
-
-namespace pim
-{
- namespace compiler
- {
- Scanner::Scanner(std::stringstream & source_) :
- source(source_)
- {
- nextCharacter();
- }
-
- Token Scanner::NextToken()
- {
- //Read whitespace, newlines and comments
- while(
- cChar == ' ' || cChar == '\t' ||
- cChar == '\r' || cChar == '\n' ||
- cChar == '/')
- {
- if(cChar == '/')
- {
- nextCharacter();
- if(cChar == '/')
- {
- while(cChar != '\n' && cChar != '\r')
- nextCharacter();
- }
- else
- return Token(Token::DivideSymbol, "/", cLine);
- }
-
- if(cChar == '\r')
- {
- nextCharacter();
- if(cChar == '\n')
- cLine++;
- else
- continue;
- }
- else if(cChar == '\n')
- cLine++;
-
- nextCharacter();
- }
-
- if(std::isalpha(cChar)) //Read alphanumeric symbols
- {
- cToken.clear();
- while(std::isalpha(cChar) || std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
-
- std::transform(cToken.begin(), cToken.end(), cToken.begin(), ::tolower);
-
- for(int i = 0; i < Token::SymbolNumber; i++)
- if(Token::SymbolNames[i] == cToken)
- return Token(i, cToken, cLine);
- return Token(Token::Identifier, cToken, cLine);
- }
- else if(std::isdigit(cChar)) //Read numeric constants
- {
- bool decimal = false;
- cToken.clear();
- while(std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- if(cChar == '.')
- {
- decimal = true;
- cToken.push_back(cChar);
- nextCharacter();
- while(std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- }
- if(decimal)
- return Token(Token::DecimalConstant, cToken, cLine);
- return Token(Token::IntegerConstant, cToken, cLine);
- }
- else if(cChar == '[')
- {
- cToken.clear();
- nextCharacter();
- while(std::isalpha(cChar) || std::isdigit(cChar) || cChar == '_' || cChar == '-')
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- nextCharacter();
-
- std::transform(cToken.begin(), cToken.end(), cToken.begin(), ::toupper);
-
- return Token(Token::RTMacro, cToken, cLine);
- }
- else if(cChar == '=')
- {
- nextCharacter();
- if(cChar == '=')
- {
- nextCharacter();
- return Token(Token::EqualSymbol, "==", cLine);
- }
- return Token(Token::AssignSymbol, "=", cLine);
- }
- else if(cChar == '!')
- {
- nextCharacter();
- if(cChar == '=')
- return Token(Token::NotEqualSymbol, "==", cLine);
- }
- else if(cChar == '(')
- {
- nextCharacter();
- return Token(Token::LeftBracket, "(", cLine);
- }
- else if(cChar == ')')
- {
- nextCharacter();
- return Token(Token::RightBracket, ")", cLine);
- }
- else if(cChar == '/')
- {
- nextCharacter();
- return Token(Token::DivideSymbol, "/", cLine);
- }
- else if(cChar == '*')
- {
- nextCharacter();
- return Token(Token::MultiplySymbol, "*", cLine);
- }
- else if(cChar == '+')
- {
- nextCharacter();
- return Token(Token::PlusSymbol, "+", cLine);
- }
- else if(cChar == '-')
- {
- nextCharacter();
- return Token(Token::MinusSymbol, "-", cLine);
- }
- else if(cChar == '%')
- {
- nextCharacter();
- return Token(Token::ModuloSymbol, "%", cLine);
- }
- else if(cChar == '<')
- {
- nextCharacter();
- if(cChar == '=')
- {
- return Token(Token::LessEqualSymbol, "<=", cLine);
- }
- return Token(Token::LessSymbol, "<", cLine);
- }
- else if(cChar == '>')
- {
- nextCharacter();
- if(cChar == '=')
- {
- return Token(Token::GreaterEqualSymbol, ">=", cLine);
- }
- return Token(Token::GreaterSymbol, ">", cLine);
- }
- else if(cChar == ',')
- {
- nextCharacter();
- return Token(Token::CommaSymbol, ",", cLine);
- }
- else if(cChar == '.')
- {
- nextCharacter();
- return Token(Token::DotSymbol, ".", cLine);
- }
- else
- {
- nextCharacter();
- return Token(Token::InvalidSymbol, std::string(1, cChar), cLine);
- }
- }
-
- void Scanner::nextCharacter()
- {
- if(source.good())
- cChar = source.get();
- else
- cChar = 0;
- }
- }
-}
diff --git a/src/pim/Scanner.h b/src/pim/Scanner.h
deleted file mode 100644
index 70e02ac..0000000
--- a/src/pim/Scanner.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <string>
-#include <sstream>
-#include "Token.h"
-namespace pim
-{
- namespace compiler
- {
- class Scanner
- {
- char cChar;
- int cLine;
- std::string cToken;
- std::stringstream & source;
- void nextCharacter();
- public:
- Scanner(std::stringstream & source_);
- Token NextToken();
- };
- }
-}
diff --git a/src/pim/Token.cpp b/src/pim/Token.cpp
deleted file mode 100644
index 62931ac..0000000
--- a/src/pim/Token.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "Token.h"
-
-namespace pim
-{
- namespace compiler
- {
- std::string Token::SymbolNames[] = {
- "=",
- "function",
- "(",
- ")",
- "/",
- "*",
- "+",
- "-",
- "%",
- "INTEGER",
- "DECIMAL",
- "PARTICLE",
- "integer",
- "decimal",
- "particle",
- "is",
- "<",
- "<=",
- ">",
- ">=",
- "==",
- "!=",
- "neighbour",
- "do",
- "of",
- "break",
- "continue",
- "if",
- "else",
- "elseif",
- "then",
- "end",
- "kill",
- "create",
- "transform",
- "get",
- "RUNTIMEMACRO",
- "IDENTIFIER",
- ",",
- ".",
- "INVALID SYMBOL"
- };
- }
-}
diff --git a/src/pim/Token.h b/src/pim/Token.h
deleted file mode 100644
index 95d3f08..0000000
--- a/src/pim/Token.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-#include <string>
-namespace pim
-{
- namespace compiler
- {
- class Token
- {
- public:
- static std::string SymbolNames[];
-
- enum
- {
- AssignSymbol = 0,
- FunctionSymbol,
-
- LeftBracket,
- RightBracket,
- DivideSymbol,
- MultiplySymbol,
- PlusSymbol,
- MinusSymbol,
- ModuloSymbol,
-
- IntegerConstant,
- DecimalConstant,
- ParticleConstant,
-
- IntegerSymbol,
- DecimalSymbol,
- ParticleSymbol,
-
- IsSymbol,
- LessSymbol,
- LessEqualSymbol,
- GreaterSymbol,
- GreaterEqualSymbol,
- NotEqualSymbol,
- EqualSymbol,
-
- NeighbourSymbol,
- DoSymbol,
- OfSymbol,
- BreakSymbol,
- ContinueSymbol,
- IfSymbol,
- ElseSymbol,
- ElseIfSymbol,
- ThenSymbol,
- EndSymbol,
-
- KillSymbol,
- CreateSymbol,
- TransformSymbol,
- GetSymbol,
-
- RTMacro,
- Identifier,
-
- CommaSymbol,
- DotSymbol,
-
- InvalidSymbol,
-
- SymbolNumber
- };
- int Symbol;
- int LineNumber;
- std::string Source;
-
- Token(int symbol = InvalidSymbol, std::string source = "HERP DERP", int lineNumber = 0) :
- Symbol(symbol),
- Source(source),
- LineNumber(lineNumber) {}
-
- std::string GetName()
- {
- return SymbolNames[Symbol];
- }
- };
- }
-}