From 532a594a0efac2e7624e1c9ddce8fb6d81dace4f Mon Sep 17 00:00:00 2001 From: martin dobrev Date: Wed, 14 Nov 2018 09:33:50 +0200 Subject: Implement if --- JSImpl/src/main.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'JSImpl/src/main.cpp') diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index a10e4d1..b2fb83d 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -2,6 +2,7 @@ #include "Parser.h" #include "ASTPrinter.h" #include "ASTInterpreter.h" +#include "ByteCodeGenerator.h" #include #include @@ -62,11 +63,20 @@ void InteractiveInterpreter() } while (true); } +void Generate() +{ + IPLVector tokens; + //Tokenize("var a = 0; var b = a + 123;a+b;", tokens); + Tokenize("var a; if(a < 4) { a = 8;} else { a = 2} ", tokens); + + std::cout << GenerateByteCode(Parse(tokens)); +} + int main() { //RunParseCalc(); - InteractiveInterpreter(); - + //InteractiveInterpreter(); + Generate(); #if defined(_WIN32) std::system("pause"); #endif -- cgit v1.3.1-23-gd82d From b2b2fe9c2c404681fb479018b52a07f3133b7d6b Mon Sep 17 00:00:00 2001 From: martin dobrev Date: Thu, 15 Nov 2018 09:39:00 +0200 Subject: Implement byte generation for "for statement" --- JSImpl/src/ByteCodeGenerator.cpp | 72 ++++++++++++++++++++++++++++++++++------ JSImpl/src/main.cpp | 4 +-- 2 files changed, 64 insertions(+), 12 deletions(-) (limited to 'JSImpl/src/main.cpp') 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 m_RegisterTable; IPLVector m_Code; IPLStack 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 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)); } -- cgit v1.3.1-23-gd82d