summaryrefslogtreecommitdiff
path: root/src/pim/Generator.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-09-21 14:05:50 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-09-21 14:05:50 (GMT)
commit939a04d3c77bf9aa8d54e912f5e12817de51756c (patch)
tree750119bf74b8fbcb409eaf02d03877c00056613d /src/pim/Generator.cpp
parent6e44ebc358d1206c147f514225373da07b43c015 (diff)
downloadpowder-939a04d3c77bf9aa8d54e912f5e12817de51756c.zip
powder-939a04d3c77bf9aa8d54e912f5e12817de51756c.tar.gz
Testing new vm/language WIP
Diffstat (limited to 'src/pim/Generator.cpp')
-rw-r--r--src/pim/Generator.cpp326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp
new file mode 100644
index 0000000..b2ea84c
--- /dev/null
+++ b/src/pim/Generator.cpp
@@ -0,0 +1,326 @@
+//Code generator for bytecode
+#include <sstream>
+#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);
+ }
+
+ std::vector<unsigned char> Generator::Finish()
+ {
+ 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;
+ }
+
+ return program;
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ void Generator::PopScope()
+ {
+
+ writeOpcode(Opcode::Return);
+ writeConstant(currentScope->LocalFrameSize);
+ currentScope = scopes.top();
+ scopes.pop();
+ }
+
+ void Generator::ScopeLabel(std::string label)
+ {
+ //defineLabelwriteOpcode("." << label);
+ defineLabel(label);
+ }
+
+ void Generator::LocalEnter()
+ {
+ writeOpcode(Opcode::LocalEnter);
+ writeConstantPlaceholder(&(currentScope->LocalFrameSize));
+ }
+
+ 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;
+ }
+
+ 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);
+ }
+
+ void Generator::StoreVariable(std::string label)
+ {
+ writeOpcode(Opcode::Store);
+ writeConstant(currentScope->GetDefinition(label).StackPosition);
+ }
+
+ void Generator::Constant(std::string constant)
+ {
+ writeOpcode(Opcode::Constant);
+ writeConstant(constant);
+ }
+
+ void Generator::Increment(std::string constant)
+ {
+ writeOpcode(Opcode::Increment);
+ writeConstant(constant);
+ }
+
+ void Generator::Discard()
+ {
+ writeOpcode(Opcode::Discard);
+ }
+
+ void Generator::Duplicate()
+ {
+ writeOpcode(Opcode::Duplicate);
+ }
+
+ void Generator::Add()
+ {
+ writeOpcode(Opcode::Add);
+ }
+
+ void Generator::Subtract()
+ {
+ writeOpcode(Opcode::Subtract);
+ }
+
+ void Generator::Multiply()
+ {
+ writeOpcode(Opcode::Multiply);
+ }
+
+ void Generator::Divide()
+ {
+ writeOpcode(Opcode::Divide);
+ }
+
+ void Generator::Modulus()
+ {
+ writeOpcode(Opcode::Modulus);
+ }
+
+ void Generator::Negate()
+ {
+ writeOpcode(Opcode::Negate);
+ }
+
+ void Generator::CreateParticle()
+ {
+ writeOpcode(Opcode::Create);
+
+ }
+
+ void Generator::TransformParticle()
+ {
+ writeOpcode(Opcode::Transform);
+ }
+
+ void Generator::GetParticle()
+ {
+ writeOpcode(Opcode::Get);
+ }
+
+ void Generator::GetPosition()
+ {
+ writeOpcode(Opcode::Position);
+ }
+
+ void Generator::KillParticle()
+ {
+ writeOpcode(Opcode::Kill);
+ }
+
+
+ void Generator::IntegerToDecimal()
+ {
+
+ }
+
+ void Generator::DecimalToInteger()
+ {
+
+ }
+
+
+ void Generator::JumpEqual(std::string label)
+ {
+ writeOpcode(Opcode::JumpEqual);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::JumpNotEqual(std::string label)
+ {
+ writeOpcode(Opcode::JumpNotEqual);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::JumpGreater(std::string label)
+ {
+ writeOpcode(Opcode::JumpGreater);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::JumpGreaterEqual(std::string label)
+ {
+ writeOpcode(Opcode::JumpGreaterEqual);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::JumpLess(std::string label)
+ {
+ writeOpcode(Opcode::JumpLess);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::JumpLessEqual(std::string label)
+ {
+ writeOpcode(Opcode::JumpLessEqual);
+ writeConstantPlaceholder(label);
+ }
+
+ void Generator::Jump(std::string label)
+ {
+ writeOpcode(Opcode::Jump);
+ writeConstantPlaceholder(label);
+ }
+
+
+ void Generator::Call(int arguments, std::string label)
+ {
+
+ }
+
+ void Generator::Return()
+ {
+
+ }
+
+ }
+} \ No newline at end of file