diff options
| Commit | b2b2fe9c2c404681fb479018b52a07f3133b7d6b (patch) | |
|---|---|---|
| Author | 2018-11-15 09:39:00 +0200 | |
| Committer | 2018-11-15 11:44:10 +0200 | |
| Files | 5339bb6fbc1d2a94e41303bc1975bb912cb2b575 /JSImpl | |
| IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.tar IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.tar.gz IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.zip | ||
| Parent | 33c5848d11d95e85edc0e2323aaf15ac9cde5a69 (diff) | |
Implement byte generation for "for statement"
2 files changed, 64 insertions, 12 deletions
| -rw-r--r-- | JSImpl/src/ByteCodeGenerator.cpp | 72 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 4 |
diff --git a/JSImpl/src/ByteCodeGenerator.cpp b/JSImpl/src/ByteCodeGenerator.cpp index 385284d..fefed78 100644 --- a/JSImpl/src/ByteCodeGenerator.cpp +++ b/JSImpl/src/ByteCodeGenerator.cpp @@ -19,11 +19,12 @@ public: virtual void Visit(IdentifierExpression* e) override;
virtual void Visit(EmptyExpression* e) override { (void)e; }
virtual void Visit(IfStatement* e) override;
+ virtual void Visit(ForStatement* e) override;
IPLString GetCode();
unsigned ResolveRegisterName(IPLString& name);
-private:
+private:
struct Instruction
{
enum Type : char
@@ -72,12 +73,50 @@ private: IPLString Args[3];
double Number;
};
+ size_t PushInstruction(Instruction::Type opcode, IPLString& arg1, IPLString& arg2, IPLString& arg3);
+ size_t PushInstruction(Instruction::Type opcode, size_t Address);
+ size_t PushInstruction(Instruction::Type opcode, IPLString& arg1, size_t Address);
+
+private:
IPLVector<IPLString> m_RegisterTable;
IPLVector<Instruction> m_Code;
IPLStack<IPLString> m_RegisterStack;
unsigned m_CurrentStackPointer;
IPLString m_OutputCode;
};
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, IPLString& arg0, IPLString& arg1, IPLString& arg2)
+{
+ Instruction ins;
+ ins.Descriptor = opcode;
+ ins.Args[0] = arg0;
+ ins.Args[1] = arg1;
+ ins.Args[2] = arg2;
+ auto address = m_Code.size();
+ m_Code.push_back(ins);
+ return address;
+}
+
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, size_t Address)
+{
+ Instruction ins;
+ ins.Descriptor = opcode;
+ ins.Number = (double)Address;
+ auto address = m_Code.size();
+ m_Code.push_back(ins);
+ return address;
+}
+
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, IPLString& arg0, size_t Address)
+{
+ Instruction ins;
+ ins.Descriptor = opcode;
+ ins.Args[0] = arg0;
+ ins.Number = (double)Address;
+ auto address = m_Code.size();
+ m_Code.push_back(ins);
+ return address;
+}
+
void ByteCodeGenerator::Visit(FunctionDeclaration* e)
{
e->GetBody()->Accept(*this);
@@ -122,6 +161,14 @@ void ByteCodeGenerator::Visit(TopStatements* e) void ByteCodeGenerator::Visit(VariableDefinitionExpression* e)
{
+ auto it = std::find_if(m_RegisterTable.begin(), m_RegisterTable.end(), [&](IPLString& current) {
+ return e->GetName() == current;
+ });
+ if (it != m_RegisterTable.end())
+ {
+ // TODO: error double definitions
+ return;
+ }
m_RegisterTable.push_back(e->GetName());
if (e->GetValue())
{
@@ -225,9 +272,20 @@ void ByteCodeGenerator::Visit(IfStatement* e) else
{
m_Code[ifIndex].Number = (double)m_Code.size();
-
}
+}
+void ByteCodeGenerator::Visit(ForStatement* e)
+{
+ e->GetInitialization()->Accept(*this);
+ auto compareAddress = m_Code.size();
+ e->GetCondition()->Accept(*this);
+ auto endAddress = PushInstruction(Instruction::Type::JMPF, m_RegisterStack.top(), 0);
+ m_RegisterStack.pop();
+ e->GetBody()->Accept(*this);
+ e->GetIteration()->Accept(*this);
+ PushInstruction(Instruction::Type::JMP, compareAddress);
+ m_Code[endAddress].Number = (double)m_Code.size();
}
void ByteCodeGenerator::Visit(IdentifierExpression* e)
@@ -237,18 +295,12 @@ void ByteCodeGenerator::Visit(IdentifierExpression* e) void ByteCodeGenerator::Visit(LiteralNumber* e)
{
- Instruction current;
-
IPLString regName = IPLString("const");
regName += std::to_string(m_RegisterTable.size());
m_RegisterTable.push_back(regName);
m_RegisterStack.push(regName);
- current.Descriptor = Instruction::Type::CONST;
- current.Args[0] = regName;
- current.Number = e->GetValue();
-
- m_Code.push_back(current);
+ PushInstruction(Instruction::Type::CONST, regName, (size_t)e->GetValue());
}
unsigned ByteCodeGenerator::ResolveRegisterName(IPLString& name)
@@ -433,7 +485,7 @@ IPLString ByteCodeGenerator::GetCode() }
++programCounter;
}
-
+ result += std::to_string(programCounter) + ": ";
result += "halt\n";
return result;
}
diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index b2fb83d..c15458e 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -67,8 +67,8 @@ void Generate() { IPLVector<Token> tokens; //Tokenize("var a = 0; var b = a + 123;a+b;", tokens); - Tokenize("var a; if(a < 4) { a = 8;} else { a = 2} ", tokens); - + /*Tokenize("var a; if(a < 4) { a = 8; if(a < 7) {var b = 4;}} else { a = 2} ", tokens);*/ + Tokenize("var i = 0; for (var j = 0; j < 10; j = j + 1) { i = i + j; }", tokens); std::cout << GenerateByteCode(Parse(tokens)); } |
