summaryrefslogtreecommitdiff
path: root/src/pim/Generator.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
commit058a2edd75debbd0297f92572316daa704bd379f (patch)
treead303f091f9a08b209b91eb34a9fcad996a3de69 /src/pim/Generator.cpp
parente3594aba9e05c6865d396418c028049cda92c2f3 (diff)
parent7a21ae192fe19868539956f3fe28e62b2c7c4429 (diff)
downloadpowder-058a2edd75debbd0297f92572316daa704bd379f.zip
powder-058a2edd75debbd0297f92572316daa704bd379f.tar.gz
Merge branch 'master' of github.com:FacialTurd/PowderToypp
Diffstat (limited to 'src/pim/Generator.cpp')
-rw-r--r--src/pim/Generator.cpp518
1 files changed, 518 insertions, 0 deletions
diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp
new file mode 100644
index 0000000..a791211
--- /dev/null
+++ b/src/pim/Generator.cpp
@@ -0,0 +1,518 @@
+//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()
+ {
+
+ }
+
+ }
+} \ No newline at end of file