Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src
diff options
context:
space:
mode:
Commitb2b2fe9c2c404681fb479018b52a07f3133b7d6b (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-11-15 09:39:00 +0200
Committer
 NDobrev <martindobrev0@gmail.com>
2018-11-15 11:44:10 +0200
Files5339bb6fbc1d2a94e41303bc1975bb912cb2b575 /JSImpl/src
IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.tar
IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.tar.gz
IPL-b2b2fe9c2c404681fb479018b52a07f3133b7d6b.zip
Parent33c5848d11d95e85edc0e2323aaf15ac9cde5a69 (diff)
Implement byte generation for "for statement"
2 files changed, 64 insertions, 12 deletions
-rw-r--r--JSImpl/src/ByteCodeGenerator.cpp72
-rw-r--r--JSImpl/src/main.cpp4
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));
}