Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit09e59ae226f2fcb469b944c815b1e1bf46d4c569 (patch)
Author
 ValeriHristov <valeri.dhristov@gmail.com>
2018-11-25 17:49:14 +0200
Committer
 Martin Dobrev <martindobrev0@gmail.com>
2018-11-25 17:49:14 +0200
Filesd8273d7a27cab059957720e06dc19c2c0fd728d1
IPL-09e59ae226f2fcb469b944c815b1e1bf46d4c569.tar
IPL-09e59ae226f2fcb469b944c815b1e1bf46d4c569.tar.gz
IPL-09e59ae226f2fcb469b944c815b1e1bf46d4c569.zip
Parent2425ccff65421e82dc406125c52b7bf804dcc918 (diff)
Implement comparison operators (#71)
* Implement comparison operators. * Remove debug code. * Undo test code.
5 files changed, 180 insertions, 7 deletions
-rw-r--r--JSImpl/src/ASTInterpreter.cpp9
-rw-r--r--JSImpl/src/ByteCodeGenerator.cpp43
-rw-r--r--JSImpl/test/sprtTests.cpp71
-rw-r--r--spasm/src/spasm.cpp52
-rw-r--r--spasm/src/spasm_impl.hpp12
diff --git a/JSImpl/src/ASTInterpreter.cpp b/JSImpl/src/ASTInterpreter.cpp
index f7d1dc2..25f5c02 100644
--- a/JSImpl/src/ASTInterpreter.cpp
+++ b/JSImpl/src/ASTInterpreter.cpp
@@ -185,6 +185,15 @@ void ASTInterpreter::Visit(BinaryExpression* e) {
case TokenType::Less:
m_Evaluation.push_back(left < right);
break;
+ case TokenType::LessEqual:
+ m_Evaluation.push_back(left <= right);
+ break;
+ case TokenType::Greater:
+ m_Evaluation.push_back(left > right);
+ break;
+ case TokenType::GreaterEqual:
+ m_Evaluation.push_back(left >= right);
+ break;
case TokenType::Comma:
m_Evaluation.push_back(right);
break;
diff --git a/JSImpl/src/ByteCodeGenerator.cpp b/JSImpl/src/ByteCodeGenerator.cpp
index dc846f2..fd85326 100644
--- a/JSImpl/src/ByteCodeGenerator.cpp
+++ b/JSImpl/src/ByteCodeGenerator.cpp
@@ -53,7 +53,11 @@ private:
SAVE,
RESTORE,
LESS,
+ LESSEQ,
+ GREATER,
+ GREATEREQ,
EQ,
+ NEQ,
LEQ,
GETG,
SETG,
@@ -282,11 +286,20 @@ void ByteCodeGenerator::Visit(BinaryExpression* e)
case TokenType::Less:
PushInstruction(Instruction::Type::LESS, o, l, r);
return;
+ case TokenType::LessEqual:
+ PushInstruction(Instruction::Type::LESSEQ, o, l, r);
+ return;
+ case TokenType::Greater:
+ PushInstruction(Instruction::Type::GREATER, o, l, r);
+ return;
+ case TokenType::GreaterEqual:
+ PushInstruction(Instruction::Type::GREATEREQ, o, l, r);
+ break;
case TokenType::EqualEqual:
PushInstruction(Instruction::Type::EQ, o, l, r);
return;
case TokenType::BangEqual:
- NOT_IMPLEMENTED;
+ PushInstruction(Instruction::Type::NEQ,o,l,r);
break;
case TokenType::Equal:
@@ -378,8 +391,8 @@ void ByteCodeGenerator::Visit(UnaryExpression* e)
PushInstruction(Instruction::Type::SUB, reg, reg, one);
}
return;
- default:
- NOT_IMPLEMENTED;
+ default:
+ NOT_IMPLEMENTED;
break;
}
}
@@ -427,8 +440,8 @@ void ByteCodeGenerator::Visit(UnaryExpression* e)
case TokenType::Bang:
NOT_IMPLEMENTED;
return;
- default:
- NOT_IMPLEMENTED;
+ default:
+ NOT_IMPLEMENTED;
break;
}
}
@@ -532,11 +545,31 @@ IPLString ByteCodeGenerator::GetCode()
+ " r" + std::to_string(ResolveRegisterName(i.Args[1]))
+ " r" + std::to_string(ResolveRegisterName(i.Args[2])) + '\n';
break;
+ case ByteCodeGenerator::Instruction::LESSEQ:
+ result += "lesseq 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::GREATER:
+ result += "greater 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::GREATEREQ:
+ result += "greatereq 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::NEQ:
+ result += "neq 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]))
diff --git a/JSImpl/test/sprtTests.cpp b/JSImpl/test/sprtTests.cpp
index 8480554..a7b9e3b 100644
--- a/JSImpl/test/sprtTests.cpp
+++ b/JSImpl/test/sprtTests.cpp
@@ -127,7 +127,6 @@ TEST_F(SPRTTest, Less)
ASSERT_EQ(Output.str(), "100");
}
-
TEST_F(SPRTTest, LessEq)
{
Spasm::byte bytecode[] = {
@@ -145,6 +144,76 @@ TEST_F(SPRTTest, LessEq)
ASSERT_EQ(Output.str(), "101");
}
+TEST_F(SPRTTest, Greater)
+{
+ Spasm::byte bytecode[] = {
+ OpCodes::Const, 1, 6,
+ OpCodes::Const, 2, 7,
+ OpCodes::Greater, 3, 1, 2,
+ OpCodes::Greater, 4, 2, 1,
+ OpCodes::Greater, 5, 2, 2,
+ OpCodes::Print, 3,
+ OpCodes::Print, 4,
+ OpCodes::Print, 5,
+ };
+
+ Run(bytecode, sizeof(bytecode));
+ ASSERT_EQ(Output.str(), "010");
+}
+
+TEST_F(SPRTTest, GreaterEq)
+{
+ Spasm::byte bytecode[] = {
+ OpCodes::Const, 1, 6,
+ OpCodes::Const, 2, 7,
+ OpCodes::GreaterEq, 3, 1, 2,
+ OpCodes::GreaterEq, 4, 2, 1,
+ OpCodes::GreaterEq, 5, 2, 2,
+ OpCodes::Print, 3,
+ OpCodes::Print, 4,
+ OpCodes::Print, 5,
+ };
+
+ Run(bytecode, sizeof(bytecode));
+ ASSERT_EQ(Output.str(), "011");
+}
+
+TEST_F(SPRTTest, Equal)
+{
+ Spasm::byte bytecode[] = {
+ OpCodes::Const, 1, 6,
+ OpCodes::Const, 2, 7,
+ OpCodes::Const, 3, 6,
+ OpCodes::Equal, 4, 2, 1,
+ OpCodes::Equal, 5, 2, 2,
+ OpCodes::Equal, 6, 1, 3,
+ OpCodes::Print, 4,
+ OpCodes::Print, 5,
+ OpCodes::Print, 6,
+ };
+
+ Run(bytecode, sizeof(bytecode));
+ ASSERT_EQ(Output.str(), "011");
+}
+
+TEST_F(SPRTTest, NotEqual)
+{
+ Spasm::byte bytecode[] = {
+ OpCodes::Const, 1, 6,
+ OpCodes::Const, 2, 7,
+ OpCodes::Const, 3, 6,
+ OpCodes::NotEqual, 4, 2, 1,
+ OpCodes::NotEqual, 5, 2, 2,
+ OpCodes::NotEqual, 6, 1, 3,
+ OpCodes::Print, 4,
+ OpCodes::Print, 5,
+ OpCodes::Print, 6,
+ };
+
+ Run(bytecode, sizeof(bytecode));
+ ASSERT_EQ(Output.str(), "100");
+}
+
TEST_F(SPRTTest, Jump)
{
Spasm::byte bytecode[] = {
diff --git a/spasm/src/spasm.cpp b/spasm/src/spasm.cpp
index 58fb6d4..4d30946 100644
--- a/spasm/src/spasm.cpp
+++ b/spasm/src/spasm.cpp
@@ -187,6 +187,38 @@ Spasm::RunResult Spasm::run()
lesseq(arg0, arg1, arg2);
break;
}
+ case OpCodes::Greater:
+ {
+ const auto arg0 = read_reg(size);
+ const auto arg1 = read_reg(size);
+ const auto arg2 = read_reg(size);
+ greater(arg0, arg1, arg2);
+ break;
+ }
+ case OpCodes::GreaterEq:
+ {
+ const auto arg0 = read_reg(size);
+ const auto arg1 = read_reg(size);
+ const auto arg2 = read_reg(size);
+ greatereq(arg0, arg1, arg2);
+ break;
+ }
+ case OpCodes::Equal:
+ {
+ const auto arg0 = read_reg(size);
+ const auto arg1 = read_reg(size);
+ const auto arg2 = read_reg(size);
+ equal(arg0, arg1, arg2);
+ break;
+ }
+ case OpCodes::NotEqual:
+ {
+ const auto arg0 = read_reg(size);
+ const auto arg1 = read_reg(size);
+ const auto arg2 = read_reg(size);
+ not_equal(arg0, arg1, arg2);
+ break;
+ }
default:
{
std::cerr << opcode << ": not implemented" << std::endl;
@@ -380,6 +412,26 @@ void Spasm::lesseq(reg_t a0, reg_t a1, reg_t a2)
set_local(a0, get_local(a1) <= get_local(a2));
}
+void Spasm::greater(reg_t a0, reg_t a1, reg_t a2)
+{
+ set_local(a0, get_local(a1) > get_local(a2));
+}
+
+void Spasm::greatereq(reg_t a0, reg_t a1, reg_t a2)
+{
+ set_local(a0, get_local(a1) >= get_local(a2));
+}
+
+void Spasm::equal(reg_t a0, reg_t a1, reg_t a2)
+{
+ set_local(a0, fabs(get_local(a1) - get_local(a2)) < 0.0001);
+}
+
+void Spasm::not_equal(reg_t a0, reg_t a1, reg_t a2)
+{
+ set_local(a0, fabs(get_local(a1) - get_local(a2)) > 0.0001);
+}
+
data_t Spasm::get_local(reg_t reg)
{
assert(&data_stack[0] <= (m_FP + reg));
diff --git a/spasm/src/spasm_impl.hpp b/spasm/src/spasm_impl.hpp
index 7c2bd38..2548828 100644
--- a/spasm/src/spasm_impl.hpp
+++ b/spasm/src/spasm_impl.hpp
@@ -30,7 +30,11 @@ enum OpCodes : char
Mod,
Less,
LessEq,
- LastIndex = LessEq,
+ Greater,
+ GreaterEq,
+ Equal,
+ NotEqual,
+ LastIndex = NotEqual,
};
static_assert(LastIndex < 0x3f, "Too many opcodes");
@@ -121,6 +125,12 @@ class Spasm
void less(reg_t a0, reg_t a1, reg_t a2);
void lesseq(reg_t a0, reg_t a1, reg_t a2);
+ void greater(reg_t a0, reg_t a1, reg_t a2);
+ void greatereq(reg_t a0, reg_t a1, reg_t a2);
+
+ void equal(reg_t a0, reg_t a1, reg_t a2);
+ void not_equal(reg_t a0, reg_t a1, reg_t a2);
+
data_t get_local(reg_t reg);
void set_local(reg_t reg, data_t data);
data_t pop_data();