diff options
Diffstat (limited to 'src/pim')
| -rw-r--r-- | src/pim/Generator.cpp | 518 | ||||
| -rw-r--r-- | src/pim/Generator.h | 178 | ||||
| -rw-r--r-- | src/pim/Machine.cpp | 637 | ||||
| -rw-r--r-- | src/pim/Machine.h | 120 | ||||
| -rw-r--r-- | src/pim/Opcodes.h | 12 | ||||
| -rw-r--r-- | src/pim/Opcodes.inl | 28 | ||||
| -rw-r--r-- | src/pim/Parser.cpp | 653 | ||||
| -rw-r--r-- | src/pim/Parser.h | 79 | ||||
| -rw-r--r-- | src/pim/Scanner.cpp | 199 | ||||
| -rw-r--r-- | src/pim/Scanner.h | 22 | ||||
| -rw-r--r-- | src/pim/Token.cpp | 51 | ||||
| -rw-r--r-- | src/pim/Token.h | 83 |
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]; - } - }; - } -} |
