Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src
diff options
context:
space:
mode:
Commit156d0957c1b36bba2685fef548a8573e9337309a (patch)
Author
 omalinov <ognyan.m@coherent-labs.com>
2018-11-18 23:01:20 +0200
Committer
 GitHub <noreply@github.com>
2018-11-18 23:01:20 +0200
Files3a882d71f65d8b5c129e348985c2c1a4fe70a031 /JSImpl/src
IPL-156d0957c1b36bba2685fef548a8573e9337309a.tar
IPL-156d0957c1b36bba2685fef548a8573e9337309a.tar.gz
IPL-156d0957c1b36bba2685fef548a8573e9337309a.zip
Parenta5ebf986574bdcdad968962751d9ab8dbe90980d (diff)
Parent12232668d931b0f3593807d2096a2c2f26844b0b (diff)
Merge branch 'master' into json-to-ast
7 files changed, 352 insertions, 105 deletions
-rw-r--r--JSImpl/src/ByteCodeGenerator.cpp327
-rw-r--r--JSImpl/src/ByteCodeGenerator.h12
-rw-r--r--JSImpl/src/Expression.h7
-rw-r--r--JSImpl/src/Lexer.cpp8
-rw-r--r--JSImpl/src/Lexer.h1
-rw-r--r--JSImpl/src/Parser.cpp54
-rw-r--r--JSImpl/src/main.cpp48
diff --git a/JSImpl/src/ByteCodeGenerator.cpp b/JSImpl/src/ByteCodeGenerator.cpp
index 09901e1..dc846f2 100644
--- a/JSImpl/src/ByteCodeGenerator.cpp
+++ b/JSImpl/src/ByteCodeGenerator.cpp
@@ -1,13 +1,15 @@
#include "ByteCodeGenerator.h"
#include "ExpressionVisitor.h"
#include <algorithm>
+#include <sstream>
+#include <iterator>
class ByteCodeGenerator : public ExpressionVisitor
{
public:
- ByteCodeGenerator() {};
- ~ByteCodeGenerator() {};
+ ByteCodeGenerator(const ByteCodeGeneratorOptions& o, const IPLVector<IPLString>& source) : m_Source(source), m_Options(o) {};
+ ~ByteCodeGenerator() {};
virtual void Visit(FunctionDeclaration* e) override;
virtual void Visit(BlockStatement* e) override;
@@ -20,16 +22,19 @@ public:
virtual void Visit(EmptyExpression* e) override { (void)e; }
virtual void Visit(IfStatement* e) override;
virtual void Visit(ForStatement* e) override;
+ virtual void Visit(UnaryExpression* e) override;
IPLString GetCode();
unsigned ResolveRegisterName(IPLString& name);
private:
+ void AddDebugInformation(Expression* e);
struct Instruction
{
enum Type : char
{
- ADD,
+ FIRST = 0,
+ ADD = FIRST,
SUB,
MUL,
DIV,
@@ -67,56 +72,119 @@ private:
CONST,
STRING,
HALT,
+ DEBUG,
+ LAST = DEBUG
};
Type Descriptor;
IPLString Args[3];
- double Number;
+ union
+ {
+ double Double[3];
+ long long Int[3];
+ unsigned long long Address[3];
+ } Values;
};
- size_t PushInstruction(Instruction::Type opcode, IPLString& arg1, IPLString& arg2, IPLString& arg3);
+ size_t PushInstruction(Instruction::Type opcode, const IPLString& arg1 = "", const IPLString& arg2 = "", const IPLString& arg3 = "");
size_t PushInstruction(Instruction::Type opcode, size_t Address);
- size_t PushInstruction(Instruction::Type opcode, IPLString& arg1, size_t Address);
+ size_t PushInstruction(Instruction::Type opcode, const IPLString& arg1, size_t Address);
+ size_t PushInstruction(Instruction::Type opcode, int Int);
+ size_t PushInstruction(Instruction::Type opcode, const IPLString& arg0, double value);
+ void PushConst(double c);
+ IPLString CreateRegister();
+ bool CheckOpCode(Instruction::Type opcode) { return opcode >= Instruction::Type::FIRST && opcode <= Instruction::Type::LAST; }
private:
IPLVector<IPLString> m_RegisterTable;
IPLVector<Instruction> m_Code;
+ IPLVector<IPLString> m_Source;
IPLStack<IPLString> m_RegisterStack;
- unsigned m_CurrentStackPointer;
IPLString m_OutputCode;
+ ByteCodeGeneratorOptions m_Options;
};
-size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, IPLString& arg0, IPLString& arg1, IPLString& arg2)
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, const IPLString& arg0, const IPLString& arg1, const IPLString& arg2)
{
+ assert(CheckOpCode(opcode));
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;
+ return m_Code.size() - 1;;
}
size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, size_t Address)
{
+ assert(CheckOpCode(opcode));
Instruction ins;
ins.Descriptor = opcode;
- ins.Number = (double)Address;
- auto address = m_Code.size();
+ ins.Values.Address[0] = Address;
m_Code.push_back(ins);
- return address;
+ return m_Code.size() - 1;;
}
-size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, IPLString& arg0, size_t Address)
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, int Int)
{
+ assert(CheckOpCode(opcode));
+ Instruction ins;
+ ins.Descriptor = opcode;
+ ins.Values.Int[0] = Int;
+ m_Code.push_back(ins);
+ return m_Code.size() - 1;;
+}
+
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, const IPLString& arg0, size_t Address)
+{
+ assert(CheckOpCode(opcode));
Instruction ins;
ins.Descriptor = opcode;
ins.Args[0] = arg0;
- ins.Number = (double)Address;
- auto address = m_Code.size();
+ ins.Values.Address[0] = Address;
+ m_Code.push_back(ins);
+ return m_Code.size() - 1;;
+}
+
+size_t ByteCodeGenerator::PushInstruction(Instruction::Type opcode, const IPLString& arg0, double value)
+{
+ assert(CheckOpCode(opcode));
+ Instruction ins;
+ ins.Descriptor = opcode;
+ ins.Args[0] = arg0;
+ ins.Values.Double[0] = value;
+ m_Code.push_back(ins);
+ return m_Code.size() - 1;;
+}
+
+void ByteCodeGenerator::PushConst(double c)
+{
+ IPLString regName = CreateRegister();
+ m_RegisterStack.push(regName);
+
+ PushInstruction(Instruction::Type::CONST, regName, c);
+}
+
+IPLString ByteCodeGenerator::CreateRegister()
+{
+ IPLString regName = IPLString("tmp");
+ regName += std::to_string(m_RegisterTable.size());
+ m_RegisterTable.push_back(regName);
+ return regName;
+}
+
+void ByteCodeGenerator::AddDebugInformation(Expression* e)
+{
+ if (!m_Options.AddDebugInformation || e->GetLine() == (unsigned)-1 || e->GetColumn() == (unsigned)-1)
+ {
+ return;
+ }
+ Instruction ins;
+ ins.Descriptor = Instruction::Type::DEBUG;
+ ins.Values.Int[0] = e->GetLine();
+ ins.Values.Int[1] = e->GetColumn();
m_Code.push_back(ins);
- return address;
}
void ByteCodeGenerator::Visit(FunctionDeclaration* e)
@@ -146,19 +214,14 @@ 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);
+ auto startAddress = PushInstruction(Instruction::Type::PUSH, (int)0);
for (auto& s : statements)
{
s->Accept(*this);
}
- m_Code[index].Number = (unsigned)m_RegisterTable.size();
+ m_Code[startAddress].Values.Int[0] = (int)m_RegisterTable.size();
- current.Descriptor = Instruction::Type::POP;
- current.Number = (unsigned)m_RegisterTable.size();
- m_Code.push_back(current);
+ PushInstruction(Instruction::Type::POP, (int)m_RegisterTable.size());
}
void ByteCodeGenerator::Visit(VariableDefinitionExpression* e)
@@ -166,6 +229,8 @@ 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
@@ -176,64 +241,50 @@ void ByteCodeGenerator::Visit(VariableDefinitionExpression* e)
{
e->GetValue()->Accept(*this);
}
+ AddDebugInformation(e);
if (!m_RegisterStack.empty())
{
- Instruction current;
- current.Descriptor = Instruction::Type::MOV;
- current.Args[0] = e->GetName();
- current.Args[1] = m_RegisterStack.top();
+ PushInstruction(Instruction::Type::MOV, e->GetName(), 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();
+ auto r = m_RegisterStack.top();
+ e->GetLeft()->Accept(*this);
+ auto l = m_RegisterStack.top();
+ AddDebugInformation(e);
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);
+ PushInstruction(Instruction::Type::MOV, l, r);
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;
+ IPLString o = CreateRegister();
+ m_RegisterStack.push(o);
switch (e->GetOperator()) {
case TokenType::Plus:
- current.Descriptor = Instruction::Type::ADD;
- break;
+ PushInstruction(Instruction::Type::ADD, o, l, r);
+ return;
case TokenType::Minus:
- current.Descriptor = Instruction::Type::SUB;
- break;
+ PushInstruction(Instruction::Type::SUB, o, l, r);
+ return;
case TokenType::Star:
- current.Descriptor = Instruction::Type::MUL;
- break;
+ PushInstruction(Instruction::Type::MUL, o, l, r);
+ return;
case TokenType::Division:
- current.Descriptor = Instruction::Type::DIV;
- break;
+ PushInstruction(Instruction::Type::DIV, o, l, r);
+ return;
case TokenType::Less:
- current.Descriptor = Instruction::Type::LESS;
- break;
+ PushInstruction(Instruction::Type::LESS, o, l, r);
+ return;
case TokenType::EqualEqual:
- current.Descriptor = Instruction::Type::EQ;
- break;
+ PushInstruction(Instruction::Type::EQ, o, l, r);
+ return;
case TokenType::BangEqual:
NOT_IMPLEMENTED;
break;
@@ -243,37 +294,28 @@ void ByteCodeGenerator::Visit(BinaryExpression* e)
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);
+ auto ifAddress = PushInstruction(Instruction::Type::JMPF, m_RegisterStack.top(), size_t(0));
e->GetIfStatement()->Accept(*this);
if (e->GetElseStatement())
{
- current.Descriptor = Instruction::Type::JMP;
- m_Code.push_back(current);
- auto afterTrueBlock = m_Code.size();
+ auto blockEndAddress = PushInstruction(Instruction::Type::JMP);
e->GetElseStatement()->Accept(*this);
// Patching
- m_Code[ifIndex].Number = (double)afterTrueBlock;
- m_Code[afterTrueBlock - 1].Number = (double)m_Code.size();
+ m_Code[ifAddress].Values.Address[0] = blockEndAddress + 1;
+ m_Code[blockEndAddress].Values.Address[0] = m_Code.size();
}
else
{
- m_Code[ifIndex].Number = (double)m_Code.size();
+ m_Code[ifAddress].Values.Address[0] = m_Code.size();
}
}
@@ -282,12 +324,12 @@ 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);
+ auto endAddress = PushInstruction(Instruction::Type::JMPF, m_RegisterStack.top(), (size_t)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();
+ m_Code[endAddress].Values.Address[0] = m_Code.size();
}
void ByteCodeGenerator::Visit(IdentifierExpression* e)
@@ -297,12 +339,99 @@ void ByteCodeGenerator::Visit(IdentifierExpression* e)
void ByteCodeGenerator::Visit(LiteralNumber* e)
{
- IPLString regName = IPLString("const");
- regName += std::to_string(m_RegisterTable.size());
- m_RegisterTable.push_back(regName);
+ AddDebugInformation(e);
+ IPLString regName = CreateRegister();
m_RegisterStack.push(regName);
- PushInstruction(Instruction::Type::CONST, regName, (size_t)e->GetValue());
+ PushInstruction(Instruction::Type::CONST, regName, e->GetValue());
+}
+
+void ByteCodeGenerator::Visit(UnaryExpression* e)
+{
+ AddDebugInformation(e);
+ e->GetExpr()->Accept(*this);
+ auto reg = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ if (e->GetSuffix())
+ {
+ switch (e->GetOperator())
+ {
+ case TokenType::PlusPlus:
+ PushConst(1);
+ {
+ auto one = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ auto o = CreateRegister();
+ PushInstruction(Instruction::Type::MOV, o, reg);
+ m_RegisterStack.push(o);
+ PushInstruction(Instruction::Type::ADD, reg, reg, one);
+ }
+ return;
+ case TokenType::MinusMinus:
+ PushConst(1);
+ {
+ auto one = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ auto o = CreateRegister();
+ PushInstruction(Instruction::Type::MOV, o, reg);
+ m_RegisterStack.push(o);
+ PushInstruction(Instruction::Type::SUB, reg, reg, one);
+ }
+ return;
+ default:
+ NOT_IMPLEMENTED;
+ break;
+ }
+ }
+ else
+ {
+ // prefix
+ switch (e->GetOperator())
+ {
+ case TokenType::Delete:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::PlusPlus:
+ PushConst(1);
+ {
+ auto one = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ m_RegisterStack.push(reg);
+ PushInstruction(Instruction::Type::ADD, reg, reg, one);
+ }
+ return;
+ case TokenType::MinusMinus:
+ PushConst(1);
+ {
+ auto one = m_RegisterStack.top();
+ m_RegisterStack.pop();
+ m_RegisterStack.push(reg);
+ PushInstruction(Instruction::Type::SUB, reg, reg, one);
+ }
+ return;
+ case TokenType::Void:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::Typeof:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::Plus:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::Minus:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::BitwiseNot:
+ NOT_IMPLEMENTED;
+ return;
+ case TokenType::Bang:
+ NOT_IMPLEMENTED;
+ return;
+ default:
+ NOT_IMPLEMENTED;
+ break;
+ }
+ }
}
unsigned ByteCodeGenerator::ResolveRegisterName(IPLString& name)
@@ -319,14 +448,16 @@ IPLString ByteCodeGenerator::GetCode()
auto programCounter = 0;
for (auto& i : m_Code)
{
- result += std::to_string(programCounter) + ": ";
+ if (i.Descriptor != ByteCodeGenerator::Instruction::DEBUG)
+ {
+ 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]))
@@ -368,25 +499,25 @@ IPLString ByteCodeGenerator::GetCode()
NOT_IMPLEMENTED;
break;
case ByteCodeGenerator::Instruction::JMP:
- result += "jmp " + std::to_string((size_t)i.Number) + '\n';
+ result += "jmp " + std::to_string(i.Values.Address[0]) + '\n';
break;
case ByteCodeGenerator::Instruction::JMPT:
result += "jmpt r" + std::to_string(ResolveRegisterName(i.Args[0]))
- + " " + std::to_string((size_t)i.Number) + '\n';
+ + " " + std::to_string(i.Values.Address[0]) + '\n';
break;
case ByteCodeGenerator::Instruction::JMPF:
result += "jmpf r" + std::to_string(ResolveRegisterName(i.Args[0]))
- + " " + std::to_string((size_t)i.Number) + '\n';
+ + " " + std::to_string(i.Values.Address[0]) + '\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';
+ result += "push " + std::to_string(i.Values.Int[0]) + '\n';
break;
case ByteCodeGenerator::Instruction::POP:
- result += "pop " + std::to_string((size_t)i.Number) + '\n';
+ result += "pop " + std::to_string(i.Values.Int[0]) + '\n';
break;
case ByteCodeGenerator::Instruction::SAVE:
result += "save";
@@ -471,7 +602,7 @@ IPLString ByteCodeGenerator::GetCode()
NOT_IMPLEMENTED;
break;
case ByteCodeGenerator::Instruction::CONST:
- result += "const r" + std::to_string(ResolveRegisterName(i.Args[0])) + " " + std::to_string(i.Number) + '\n';
+ result += "const r" + std::to_string(ResolveRegisterName(i.Args[0])) + " " + std::to_string(i.Values.Double[0]) + '\n';
break;
case ByteCodeGenerator::Instruction::STRING:
result += "string";
@@ -480,6 +611,13 @@ IPLString ByteCodeGenerator::GetCode()
case ByteCodeGenerator::Instruction::HALT:
result += "halt\n";
break;
+ case ByteCodeGenerator::Instruction::DEBUG:
+ {
+ auto line = i.Values.Int[0];
+ auto column = i.Values.Int[1];
+ result += "D: " + m_Source[line].substr(0, column) + "@@=>" + m_Source[line].substr(column, m_Source[line].size()) + '\n';
+ }
+ break;
default:
NOT_IMPLEMENTED;
break;
@@ -492,9 +630,18 @@ IPLString ByteCodeGenerator::GetCode()
return result;
}
-IPLString GenerateByteCode(ExpressionPtr program)
+IPLString GenerateByteCode(ExpressionPtr program, const IPLString& source, const ByteCodeGeneratorOptions& options)
{
- ByteCodeGenerator generator;
+ std::istringstream sourceStream(source);
+
+ IPLVector<IPLString> sourceByLines;
+ while (sourceStream.good())
+ {
+ IPLString currentLine;
+ std::getline(sourceStream, currentLine);
+ sourceByLines.push_back(currentLine);
+ }
+ ByteCodeGenerator generator(options, sourceByLines);
program->Accept(generator);
return generator.GetCode();
diff --git a/JSImpl/src/ByteCodeGenerator.h b/JSImpl/src/ByteCodeGenerator.h
index a619603..4a1d521 100644
--- a/JSImpl/src/ByteCodeGenerator.h
+++ b/JSImpl/src/ByteCodeGenerator.h
@@ -2,5 +2,15 @@
#include "Expression.h"
+struct ByteCodeGeneratorOptions
+{
+ enum OptimizationsType
+ {
+ None
+ };
+ ByteCodeGeneratorOptions(OptimizationsType o = None, bool debug = false) : Optimisations(o), AddDebugInformation(debug) {}
+ OptimizationsType Optimisations;
+ bool AddDebugInformation;
+};
-IPLString GenerateByteCode(ExpressionPtr program);
+IPLString GenerateByteCode(ExpressionPtr program, const IPLString& source, const ByteCodeGeneratorOptions& options = ByteCodeGeneratorOptions());
diff --git a/JSImpl/src/Expression.h b/JSImpl/src/Expression.h
index 4d45cc3..3fa7b90 100644
--- a/JSImpl/src/Expression.h
+++ b/JSImpl/src/Expression.h
@@ -8,8 +8,15 @@
class Expression : public IPLEnableShared<Expression>
{
public:
+ Expression() : m_Line((unsigned)-1), m_Column((unsigned)-1) {}
virtual ~Expression() {}
virtual void Accept(ExpressionVisitor& v) = 0;
+ unsigned GetLine() { return m_Line; };
+ unsigned GetColumn() { return m_Column; };
+ void SetLocation(unsigned l, unsigned c) { m_Line = l; m_Column = c; };
+ private:
+ unsigned m_Line = 0;
+ unsigned m_Column = 0;
};
#define EXPAND_ARGUMENT(type, name, def)\
diff --git a/JSImpl/src/Lexer.cpp b/JSImpl/src/Lexer.cpp
index 8b3b909..dbbf92d 100644
--- a/JSImpl/src/Lexer.cpp
+++ b/JSImpl/src/Lexer.cpp
@@ -105,6 +105,7 @@ private:
unsigned m_Line;
unsigned m_Column;
unsigned m_Current;
+ unsigned m_LastTokenPozition;
const char* m_Code;
IPLError m_Error;
@@ -132,6 +133,7 @@ Tokenizer::Tokenizer(const char* code, const LexerSettings& settings)
: m_Line(0)
, m_Column(0)
, m_Current(0)
+ , m_LastTokenPozition(0)
, m_Code(code)
, m_Error()
, m_GenerationState(State::Success)
@@ -253,12 +255,14 @@ inline void Tokenizer::NextLine()
{
++m_Current;
++m_Line;
- m_Column = 0;
+ m_LastTokenPozition = m_Column = 0;
}
inline Token Tokenizer::ProduceToken(TokenType type, IPLString lexeme, double number = 0.0)
{
- return Token{ type, m_Line, lexeme, number };
+ auto token = Token{ type, m_Line, m_LastTokenPozition, lexeme, number };
+ m_LastTokenPozition = m_Column;
+ return token;
}
inline Token Tokenizer::ProduceSkipToken()
diff --git a/JSImpl/src/Lexer.h b/JSImpl/src/Lexer.h
index 5ea5064..3c0c785 100644
--- a/JSImpl/src/Lexer.h
+++ b/JSImpl/src/Lexer.h
@@ -110,6 +110,7 @@ struct Token
{
TokenType Type;
unsigned Line;
+ unsigned Column;
IPLString Lexeme;
double Number;
};
diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp
index 8c387c8..7c3c039 100644
--- a/JSImpl/src/Parser.cpp
+++ b/JSImpl/src/Parser.cpp
@@ -63,6 +63,14 @@ private:
{
unsigned Current;
};
+
+ struct Location
+ {
+ unsigned Line;
+ unsigned Column;
+ };
+ Location GetLocation() const { return { m_Tokens[m_Current].Line , m_Tokens[m_Current].Column }; }
+
InternalState Snapshot();
void Restore(const InternalState& state);
@@ -649,6 +657,7 @@ ExpressionPtr Parser::ConditionalExpression()
ExpressionPtr Parser::AssignmentExpression()
{
+ auto location = GetLocation();
auto snapShot = m_Current;
auto left = LeftSideExpression();
if (MatchOneOf({ TokenType::Equal,
@@ -665,11 +674,21 @@ ExpressionPtr Parser::AssignmentExpression()
{
auto type = Prev().Type;
auto right = AssignmentExpression();
- return IPLMakeSharePtr<BinaryExpression>(left, right, type);
+ auto be = IPLMakeSharePtr<BinaryExpression>(left, right, type);
+ if (be)
+ {
+ be->SetLocation(location.Line, location.Column);
+ }
+ return be;
}
// revert state;
m_Current = snapShot;
- return ConditionalExpression();
+ auto ce = ConditionalExpression();
+ if (ce)
+ {
+ ce->SetLocation(location.Line, location.Column);
+ }
+ return ce;
}
ExpressionPtr Parser::Expression()
@@ -729,6 +748,7 @@ ExpressionPtr Parser::EmptyStatement()
ExpressionPtr Parser::VariableDefinition()
{
auto VariableDeclaration = [&]() -> ExpressionPtr {
+ auto location = GetLocation();
if (Match(TokenType::Identifier))
{
auto id = Prev().Lexeme;
@@ -737,7 +757,9 @@ ExpressionPtr Parser::VariableDefinition()
{
ae = AssignmentExpression();
}
- return IPLMakeSharePtr<VariableDefinitionExpression>(id, ae);
+ auto vd = IPLMakeSharePtr<VariableDefinitionExpression>(id, ae);
+ vd->SetLocation(location.Line, location.Column);
+ return vd;
}
return nullptr;
};
@@ -790,17 +812,21 @@ ExpressionPtr Parser::Block()
ExpressionPtr Parser::LabeledStatement()
{
+ auto location = GetLocation();
if (Match(TokenType::Identifier))
{
auto identifier = Prev().Lexeme;
auto stament = Statement();
- return IPLMakeSharePtr<::LabeledStatement>(identifier, stament);
+ auto ls = IPLMakeSharePtr<::LabeledStatement>(identifier, stament);
+ ls->SetLocation(location.Line, location.Column);
+ return ls;
}
return nullptr;
}
ExpressionPtr Parser::IfStatementfull()
{
+ auto location = GetLocation();
if (Match(TokenType::If))
{
auto cond = ParenthesizedExpression();
@@ -810,7 +836,9 @@ ExpressionPtr Parser::IfStatementfull()
{
elseBody = Statement();
}
- return IPLMakeSharePtr<::IfStatement>(cond, ifBody, elseBody);
+ auto is = IPLMakeSharePtr<::IfStatement>(cond, ifBody, elseBody);
+ is->SetLocation(location.Line, location.Column);
+ return is;
}
return nullptr;
}
@@ -868,18 +896,22 @@ ExpressionPtr Parser::DoStatement()
ExpressionPtr Parser::WhileStatement()
{
+ auto location = GetLocation();
if (Match(TokenType::While))
{
auto cond = ParenthesizedExpression();
auto body = Statement();
auto isDoWhile = false;
- return IPLMakeSharePtr<::WhileStatement>(cond, body, isDoWhile);
+ auto ws = IPLMakeSharePtr<::WhileStatement>(cond, body, isDoWhile);
+ ws->SetLocation(location.Line, location.Column);
+ return ws;
}
return nullptr;
}
ExpressionPtr Parser::ForStatement()
{
+ auto location = GetLocation();
if (Match(TokenType::For))
{
if (!Match(TokenType::LeftParen))
@@ -907,7 +939,9 @@ ExpressionPtr Parser::ForStatement()
assert(false);
}
auto body = Statement();
- return IPLMakeSharePtr<::ForStatement>(initializer, cond, iteration, body);
+ auto fs = IPLMakeSharePtr<::ForStatement>(initializer, cond, iteration, body);
+ fs->SetLocation(location.Line, location.Column);
+ return fs;
}
return nullptr;
}
@@ -1047,7 +1081,7 @@ ExpressionPtr Parser::FunctionDefinition()
}
return nullptr;
};
-
+ auto location = GetLocation();
if (Match(TokenType::Function))
{
if (Match(TokenType::Identifier))
@@ -1058,7 +1092,9 @@ ExpressionPtr Parser::FunctionDefinition()
{
if (auto body = Body())
{
- return IPLMakeSharePtr<FunctionDeclaration>(name, identifiers, body);
+ auto fd = IPLMakeSharePtr<FunctionDeclaration>(name, identifiers, body);
+ fd->SetLocation(location.Line, location.Column);
+ return fd;
}
else
{
diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp
index c15458e..90f6023 100644
--- a/JSImpl/src/main.cpp
+++ b/JSImpl/src/main.cpp
@@ -6,6 +6,13 @@
#include <iostream>
#include <cstring>
+#include <sstream>
+#include <iterator>
+
+#if defined(_WIN32)
+#include <Windows.h>
+#endif
+
void RunParseCalc()
{
IPLVector<Token> tokens;
@@ -68,8 +75,43 @@ 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));
+ IPLString source = "var i = 0; \n"
+ "for (var j = 0; j < 10; j++)\n"
+ "{\n"
+ " i = i + j;\n"
+ "}";
+ Tokenize(source.c_str(), tokens);
+
+ auto asmb = GenerateByteCode(Parse(tokens), source,
+ ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, true));
+
+ //sets the color to intense red on blue background
+#if defined(_WIN32)
+ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ std::istringstream asmbStream(asmb);
+ while (asmbStream.good())
+ {
+ IPLString it;
+ std::getline(asmbStream, it);
+ if (it[0] == 'D')
+ {
+ SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN| BACKGROUND_BLUE | FOREGROUND_INTENSITY);
+ auto dd = it.find("@@=>");
+ std::cout << it.substr(0, dd);
+ SetConsoleTextAttribute(hStdout, FOREGROUND_RED | BACKGROUND_BLUE | FOREGROUND_INTENSITY);
+ std::cout << it.substr(dd, 4);
+ SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_INTENSITY);
+ std::cout << it.substr(dd + 4, it.size()) << std::endl;
+ }
+ else
+ {
+ std::cout << it << std::endl;
+ }
+ SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
+ }
+#else
+ std::cout << asmb;
+#endif
}
int main()
@@ -78,7 +120,7 @@ int main()
//InteractiveInterpreter();
Generate();
#if defined(_WIN32)
- std::system("pause");
+ //std::system("pause");
#endif
return 0;
}