summaryrefslogtreecommitdiff
path: root/src/pim/Generator.h
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.h
parent6e44ebc358d1206c147f514225373da07b43c015 (diff)
downloadpowder-939a04d3c77bf9aa8d54e912f5e12817de51756c.zip
powder-939a04d3c77bf9aa8d54e912f5e12817de51756c.tar.gz
Testing new vm/language WIP
Diffstat (limited to 'src/pim/Generator.h')
-rw-r--r--src/pim/Generator.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/pim/Generator.h b/src/pim/Generator.h
new file mode 100644
index 0000000..0121c13
--- /dev/null
+++ b/src/pim/Generator.h
@@ -0,0 +1,164 @@
+#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 Definition
+ {
+ public:
+ enum { Integer = Token::IntegerSymbol, Decimal = Token::DecimalSymbol };
+ 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;
+
+ 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);
+
+ 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 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 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();
+ };
+ }
+} \ No newline at end of file