diff options
| Commit | a2c53c44ff31d40030d45f9ce346413cd8fb815e (patch) | |
|---|---|---|
| Author | 2018-11-15 19:22:41 +0200 | |
| Committer | 2018-11-15 19:22:41 +0200 | |
| Files | 914a9276c101d8d3e4ae100cffc216e06955a195 /JSImpl/src | |
| IPL-a2c53c44ff31d40030d45f9ce346413cd8fb815e.tar IPL-a2c53c44ff31d40030d45f9ce346413cd8fb815e.tar.gz IPL-a2c53c44ff31d40030d45f9ce346413cd8fb815e.zip | ||
| Parent | c32eda4e697803824e79878c74d541b81fbd04d8 (diff) | |
| Parent | 255202e4096048ae72766522f7894830de10bd2f (diff) | |
Merge pull request #49 from SofiaCPP/code-gen
Code gen
6 files changed, 548 insertions, 50 deletions
| -rw-r--r-- | JSImpl/src/ASTInterpreter.cpp | 21 | ||||
| -rw-r--r-- | JSImpl/src/ASTInterpreter.h | 10 | ||||
| -rw-r--r-- | JSImpl/src/ByteCodeGenerator.cpp | 501 | ||||
| -rw-r--r-- | JSImpl/src/ByteCodeGenerator.h | 6 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionVisitor.h | 46 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 14 |
diff --git a/JSImpl/src/ASTInterpreter.cpp b/JSImpl/src/ASTInterpreter.cpp index 04f949f..f7d1dc2 100644 --- a/JSImpl/src/ASTInterpreter.cpp +++ b/JSImpl/src/ASTInterpreter.cpp @@ -21,28 +21,7 @@ public: return m_LValue; } - virtual void Visit(LiteralNull* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LiteralUndefined* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LiteralString* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LiteralNumber* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LiteralBoolean* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LiteralObject* e) override { NOT_IMPLEMENTED; } - virtual void Visit(BinaryExpression* e) override { NOT_IMPLEMENTED; } - virtual void Visit(UnaryExpression* e) override { NOT_IMPLEMENTED; } virtual void Visit(IdentifierExpression* e) override { m_LValue = &m_Interpreter->ModifyVariable(e->GetName()); } - virtual void Visit(ListExpression* e) override { NOT_IMPLEMENTED; } - virtual void Visit(VariableDefinitionExpression* e) override { NOT_IMPLEMENTED; } - virtual void Visit(BlockStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(LabeledStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(IfStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(SwitchStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(CaseStatement *e) override { NOT_IMPLEMENTED; } - virtual void Visit(WhileStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(ForStatement* e) override { NOT_IMPLEMENTED; } - virtual void Visit(FunctionDeclaration* e) override { NOT_IMPLEMENTED; } - virtual void Visit(TopStatements* e) override { NOT_IMPLEMENTED; } - virtual void Visit(EmptyExpression* e) override { NOT_IMPLEMENTED; } - virtual void Visit(CallExpression* e) override { NOT_IMPLEMENTED; } ASTInterpreter* m_Interpreter; ASTInterpreter::value_type* m_LValue; diff --git a/JSImpl/src/ASTInterpreter.h b/JSImpl/src/ASTInterpreter.h index cde3dd0..db89013 100644 --- a/JSImpl/src/ASTInterpreter.h +++ b/JSImpl/src/ASTInterpreter.h @@ -42,11 +42,11 @@ public: value_type& ModifyVariable(const IPLString& name); bool HasVariable(const IPLString& name); - class Printer - { - public: - virtual void PrintVariable(const char* name, double value) = 0; - }; + class Printer + { + public: + virtual void PrintVariable(const char* name, double value) = 0; + }; void Print(Printer& p); private: diff --git a/JSImpl/src/ByteCodeGenerator.cpp b/JSImpl/src/ByteCodeGenerator.cpp new file mode 100644 index 0000000..09901e1 --- /dev/null +++ b/JSImpl/src/ByteCodeGenerator.cpp @@ -0,0 +1,501 @@ +#include "ByteCodeGenerator.h"
+#include "ExpressionVisitor.h"
+#include <algorithm>
+
+class ByteCodeGenerator : public ExpressionVisitor
+{
+public:
+ ByteCodeGenerator() {};
+ ~ByteCodeGenerator() {};
+
+
+ virtual void Visit(FunctionDeclaration* e) override;
+ virtual void Visit(BlockStatement* e) override;
+ virtual void Visit(BinaryExpression* e) override;
+ virtual void Visit(LiteralNumber* e) override;
+ virtual void Visit(TopStatements* e) override;
+ virtual void Visit(ListExpression* e) override;
+ virtual void Visit(VariableDefinitionExpression* e) override;
+ 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:
+ struct Instruction
+ {
+ enum Type : char
+ {
+ ADD,
+ SUB,
+ MUL,
+ DIV,
+ MOD,
+ MOV,
+ PRINT,
+ READ,
+ CALL,
+ RET,
+ JMP,
+ JMPT,
+ JMPF,
+ DUP,
+ PUSH,
+ POP,
+ SAVE,
+ RESTORE,
+ LESS,
+ EQ,
+ LEQ,
+ GETG,
+ SETG,
+ GETUP,
+ SETUP,
+ GET,
+ SET,
+ INC,
+ DEC,
+ AND,
+ OR,
+ XOR,
+ NOT,
+ THROW,
+ CATCH,
+ CONST,
+ STRING,
+ HALT,
+ };
+
+ Type Descriptor;
+ 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);
+}
+
+void ByteCodeGenerator::Visit(ListExpression* e)
+{
+ auto& statements = e->GetValues();
+ for (auto& s : statements)
+ {
+ s->Accept(*this);
+ }
+}
+
+void ByteCodeGenerator::Visit(BlockStatement* e)
+{
+ auto& statements = e->GetValues();
+ for (auto& s : statements)
+ {
+ s->Accept(*this);
+ }
+}
+
+void ByteCodeGenerator::Visit(TopStatements* e)
+{
+ auto& statements = e->GetValues();
+
+ Instruction current;
+ current.Descriptor = Instruction::Type::PUSH;
+ auto index = m_Code.size();
+ m_Code.push_back(current);
+ for (auto& s : statements)
+ {
+ s->Accept(*this);
+ }
+ m_Code[index].Number = (unsigned)m_RegisterTable.size();
+
+ current.Descriptor = Instruction::Type::POP;
+ current.Number = (unsigned)m_RegisterTable.size();
+ m_Code.push_back(current);
+}
+
+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())
+ {
+ e->GetValue()->Accept(*this);
+ }
+ if (!m_RegisterStack.empty())
+ {
+ Instruction current;
+ current.Descriptor = Instruction::Type::MOV;
+ current.Args[0] = e->GetName();
+ current.Args[1] = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ m_Code.push_back(current);
+ }
+}
+
+void ByteCodeGenerator::Visit(BinaryExpression* e)
+{
+ Instruction current;
+
+ e->GetLeft()->Accept(*this);
+ current.Args[1] = m_RegisterStack.top();
+ m_RegisterStack.pop();
+
+ e->GetRight()->Accept(*this);
+ current.Args[2] = m_RegisterStack.top();
+ m_RegisterStack.pop();
+
+ if (e->GetOperator() == TokenType::Equal)
+ {
+ current.Descriptor = Instruction::Type::MOV;
+ current.Args[0] = current.Args[1];
+ current.Args[1] = current.Args[2];
+ m_Code.push_back(current);
+ return;
+ }
+
+
+ IPLString regName = IPLString ("tmp");
+ regName += std::to_string(m_RegisterTable.size());
+ m_RegisterTable.push_back(regName);
+ m_RegisterStack.push(regName);
+ current.Args[0] = regName;
+
+ switch (e->GetOperator()) {
+ case TokenType::Plus:
+ current.Descriptor = Instruction::Type::ADD;
+ break;
+ case TokenType::Minus:
+ current.Descriptor = Instruction::Type::SUB;
+ break;
+ case TokenType::Star:
+ current.Descriptor = Instruction::Type::MUL;
+ break;
+ case TokenType::Division:
+ current.Descriptor = Instruction::Type::DIV;
+ break;
+ case TokenType::Less:
+ current.Descriptor = Instruction::Type::LESS;
+ break;
+ case TokenType::EqualEqual:
+ current.Descriptor = Instruction::Type::EQ;
+ break;
+ case TokenType::BangEqual:
+ NOT_IMPLEMENTED;
+ break;
+ case TokenType::Equal:
+
+ break;
+ default:
+ NOT_IMPLEMENTED;
+ }
+ m_Code.push_back(current);
+}
+
+void ByteCodeGenerator::Visit(IfStatement* e)
+{
+ Instruction current;
+ e->GetCondition()->Accept(*this);
+ current.Descriptor = Instruction::Type::JMPF;
+ current.Args[0] = m_RegisterStack.top();
+ current.Number = 0.0;
+ m_RegisterStack.pop();
+ auto ifIndex = m_Code.size();
+ m_Code.push_back(current);
+
+ e->GetIfStatement()->Accept(*this);
+
+ if (e->GetElseStatement())
+ {
+ current.Descriptor = Instruction::Type::JMP;
+ m_Code.push_back(current);
+ auto afterTrueBlock = m_Code.size();
+
+ e->GetElseStatement()->Accept(*this);
+
+ // Patching
+ m_Code[ifIndex].Number = (double)afterTrueBlock;
+ m_Code[afterTrueBlock - 1].Number = (double)m_Code.size();
+ }
+ 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)
+{
+ m_RegisterStack.push(e->GetName());
+}
+
+void ByteCodeGenerator::Visit(LiteralNumber* e)
+{
+ IPLString regName = IPLString("const");
+ regName += std::to_string(m_RegisterTable.size());
+ m_RegisterTable.push_back(regName);
+ m_RegisterStack.push(regName);
+
+ PushInstruction(Instruction::Type::CONST, regName, (size_t)e->GetValue());
+}
+
+unsigned ByteCodeGenerator::ResolveRegisterName(IPLString& name)
+{
+ auto it = std::find_if(m_RegisterTable.begin(), m_RegisterTable.end(), [&](IPLString& current) {
+ return name == current;
+ });
+ return unsigned(it - m_RegisterTable.begin());
+}
+
+IPLString ByteCodeGenerator::GetCode()
+{
+ IPLString result;
+ auto programCounter = 0;
+ for (auto& i : m_Code)
+ {
+ result += std::to_string(programCounter) + ": ";
+ switch (i.Descriptor)
+ {
+ case ByteCodeGenerator::Instruction::ADD:
+ result += "add r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+
+ break;
+ case ByteCodeGenerator::Instruction::SUB:
+ result += "sub r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::MUL:
+ result += "mul r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::DIV:
+ result += "div r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::MOD:
+ result += "mod r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::MOV:
+ result += "mov r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::PRINT:
+ result += "print r" + std::to_string(ResolveRegisterName(i.Args[0])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::READ:
+ result += "read";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::CALL:
+ result += "call";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::RET:
+ result += "ret";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::JMP:
+ result += "jmp " + std::to_string((size_t)i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::JMPT:
+ result += "jmpt r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " " + std::to_string((size_t)i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::JMPF:
+ result += "jmpf r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " " + std::to_string((size_t)i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::DUP:
+ result += "dup";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::PUSH:
+ result += "push " + std::to_string((size_t)i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::POP:
+ result += "pop " + std::to_string((size_t)i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::SAVE:
+ result += "save";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::RESTORE:
+ result += "restore";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::LESS:
+ result += "less r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::EQ:
+ result += "eq r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::LEQ:
+ result += "leq r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::GETG:
+ result += "getg";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::SETG:
+ result += "setg";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::GETUP:
+ result += "getup";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::SETUP:
+ result += "setup";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::GET:
+ result += "get";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::SET:
+ result += "set";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::INC:
+ result += "inc";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::DEC:
+ result += "dec";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::AND:
+ result += "and r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::OR:
+ result += "or r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::XOR:
+ result += "xor r" + std::to_string(ResolveRegisterName(i.Args[0]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ + " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::NOT:
+ result += "not";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::THROW:
+ result += "throw";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::CATCH:
+ result += "catch";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::CONST:
+ result += "const r" + std::to_string(ResolveRegisterName(i.Args[0])) + " " + std::to_string(i.Number) + '\n';
+ break;
+ case ByteCodeGenerator::Instruction::STRING:
+ result += "string";
+ NOT_IMPLEMENTED;
+ break;
+ case ByteCodeGenerator::Instruction::HALT:
+ result += "halt\n";
+ break;
+ default:
+ NOT_IMPLEMENTED;
+ break;
+
+ }
+ ++programCounter;
+ }
+ result += std::to_string(programCounter) + ": ";
+ result += "halt\n";
+ return result;
+}
+
+IPLString GenerateByteCode(ExpressionPtr program)
+{
+ ByteCodeGenerator generator;
+ program->Accept(generator);
+
+ return generator.GetCode();
+}
\ No newline at end of file diff --git a/JSImpl/src/ByteCodeGenerator.h b/JSImpl/src/ByteCodeGenerator.h new file mode 100644 index 0000000..a619603 --- /dev/null +++ b/JSImpl/src/ByteCodeGenerator.h @@ -0,0 +1,6 @@ +#pragma once + +#include "Expression.h" + + +IPLString GenerateByteCode(ExpressionPtr program); diff --git a/JSImpl/src/ExpressionVisitor.h b/JSImpl/src/ExpressionVisitor.h index f86297f..f1f2fcd 100644 --- a/JSImpl/src/ExpressionVisitor.h +++ b/JSImpl/src/ExpressionVisitor.h @@ -6,26 +6,28 @@ class ExpressionVisitor { public: ~ExpressionVisitor() {} - virtual void Visit(LiteralNull* e) = 0; - virtual void Visit(LiteralUndefined* e) = 0; - virtual void Visit(LiteralString* e) = 0; - virtual void Visit(LiteralNumber* e) = 0; - virtual void Visit(LiteralBoolean* e) = 0; - virtual void Visit(LiteralObject* e) = 0; - virtual void Visit(BinaryExpression* e) = 0; - virtual void Visit(UnaryExpression* e) = 0; - virtual void Visit(IdentifierExpression* e) = 0; - virtual void Visit(ListExpression* e) = 0; - virtual void Visit(VariableDefinitionExpression* e) = 0; - virtual void Visit(BlockStatement* e) = 0; - virtual void Visit(LabeledStatement* e) = 0; - virtual void Visit(IfStatement* e) = 0; - virtual void Visit(SwitchStatement* e) = 0; - virtual void Visit(CaseStatement* e) = 0; - virtual void Visit(WhileStatement* e) = 0; - virtual void Visit(ForStatement* e) = 0; - virtual void Visit(FunctionDeclaration* e) = 0; - virtual void Visit(TopStatements* e) = 0; - virtual void Visit(EmptyExpression* e) = 0; - virtual void Visit(CallExpression* e) = 0; + + virtual void Visit(LiteralNull* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LiteralUndefined* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LiteralString* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LiteralNumber* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LiteralBoolean* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LiteralObject* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(BinaryExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(UnaryExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(IdentifierExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(ListExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(VariableDefinitionExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(BlockStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(LabeledStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(IfStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(SwitchStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(CaseStatement *e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(WhileStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(ForStatement* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(FunctionDeclaration* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(TopStatements* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(EmptyExpression* e) { (void)e; NOT_IMPLEMENTED; } + virtual void Visit(CallExpression* e) { (void)e; NOT_IMPLEMENTED; } + };
\ No newline at end of file diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index a10e4d1..c15458e 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 <iostream> #include <cstring> @@ -62,11 +63,20 @@ void InteractiveInterpreter() } while (true); } +void Generate() +{ + IPLVector<Token> tokens; + //Tokenize("var a = 0; var b = a + 123;a+b;", 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)); +} + int main() { //RunParseCalc(); - InteractiveInterpreter(); - + //InteractiveInterpreter(); + Generate(); #if defined(_WIN32) std::system("pause"); #endif |
