Skip to content

Commit

Permalink
Merge pull request #43 from BastianBlokland/feature/string-length
Browse files Browse the repository at this point in the history
String length build-in function
  • Loading branch information
BastianBlokland committed Jan 7, 2020
2 parents 58d2b08 + 7edc3a5 commit 1e3b64d
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 20 deletions.
1 change: 1 addition & 0 deletions include/backend/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Builder final {
auto addAndInt() -> void;
auto addOrInt() -> void;
auto addXorInt() -> void;
auto addLengthString() -> void;

auto addCheckEqInt() -> void;
auto addCheckEqFloat() -> void;
Expand Down
1 change: 1 addition & 0 deletions include/prog/sym/func_kind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum class FuncKind {
CheckNEqBool,

AddString,
LengthString,
CheckEqString,
CheckNEqString,

Expand Down
41 changes: 21 additions & 20 deletions include/vm/opcode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,27 @@ enum class OpCode : uint8_t {
AndInt = 65,
OrInt = 66,
XorInt = 67,

CheckEqInt = 70,
CheckEqFloat = 71,
CheckEqString = 72,
CheckEqIp = 73,
CheckEqCallDynTgt = 74,
CheckGtInt = 75,
CheckGtFloat = 76,
CheckLeInt = 77,
CheckLeFloat = 78,

ConvIntFloat = 81,
ConvFloatInt = 82,
ConvIntString = 83,
ConvFloatString = 84,

MakeStruct = 90,
LoadStructField = 91,

PrintString = 100,
LengthString = 68,

CheckEqInt = 80,
CheckEqFloat = 81,
CheckEqString = 82,
CheckEqIp = 83,
CheckEqCallDynTgt = 84,
CheckGtInt = 85,
CheckGtFloat = 86,
CheckLeInt = 87,
CheckLeFloat = 88,

ConvIntFloat = 91,
ConvFloatInt = 92,
ConvIntString = 93,
ConvFloatString = 94,

MakeStruct = 100,
LoadStructField = 101,

PrintString = 150,

Jump = 220,
JumpIf = 221,
Expand Down
2 changes: 2 additions & 0 deletions src/backend/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ auto Builder::addOrInt() -> void { writeOpCode(vm::OpCode::OrInt); }

auto Builder::addXorInt() -> void { writeOpCode(vm::OpCode::XorInt); }

auto Builder::addLengthString() -> void { writeOpCode(vm::OpCode::LengthString); }

auto Builder::addCheckEqInt() -> void { writeOpCode(vm::OpCode::CheckEqInt); }

auto Builder::addCheckEqFloat() -> void { writeOpCode(vm::OpCode::CheckEqFloat); }
Expand Down
1 change: 1 addition & 0 deletions src/backend/dasm/disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ auto disassembleInstructions(const vm::Assembly& assembly) -> std::vector<Instru
case vm::OpCode::AndInt:
case vm::OpCode::OrInt:
case vm::OpCode::XorInt:
case vm::OpCode::LengthString:
case vm::OpCode::CheckEqInt:
case vm::OpCode::CheckEqFloat:
case vm::OpCode::CheckEqString:
Expand Down
3 changes: 3 additions & 0 deletions src/backend/internal/gen_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ auto GenExpr::visit(const prog::expr::CallExprNode& n) -> void {
case prog::sym::FuncKind::AddString:
m_builder->addAddString();
break;
case prog::sym::FuncKind::LengthString:
m_builder->addLengthString();
break;
case prog::sym::FuncKind::CheckEqString:
m_builder->addCheckEqString();
break;
Expand Down
1 change: 1 addition & 0 deletions src/prog/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ Program::Program() :

// Register build-in explicit conversions.
m_funcDecls.registerFunc(*this, fk::ConvFloatInt, "toInt", sym::TypeSet{m_float}, m_int);
m_funcDecls.registerFunc(*this, fk::LengthString, "length", sym::TypeSet{m_string}, m_int);

// Register build-in actions.
m_actionDecls.registerAction(*this, ak::PrintString, "print", sym::TypeSet{m_string});
Expand Down
4 changes: 4 additions & 0 deletions src/vm/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ static auto execute(const Assembly& assembly, io::Interface* interface, uint32_t
auto a = evalStack.pop().getInt();
evalStack.push(internal::intValue(a ^ b)); // NOLINT: Signed bitwise operand
} break;
case OpCode::LengthString: {
auto* strRef = getStringRef(evalStack.pop());
evalStack.push(internal::intValue(strRef->getSize()));
} break;

case OpCode::CheckEqInt: {
auto b = evalStack.pop().getInt();
Expand Down
3 changes: 3 additions & 0 deletions src/vm/opcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ auto operator<<(std::ostream& out, const OpCode& rhs) -> std::ostream& {
case OpCode::XorInt:
out << "xor-int";
break;
case OpCode::LengthString:
out << "length-string";
break;

case OpCode::CheckEqInt:
out << "check-eq-int";
Expand Down
5 changes: 5 additions & 0 deletions tests/backend/call_expr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ TEST_CASE("Generate assembly for call expressions", "[backend]") {
builder->addLoadLitString("world");
builder->addAddString();
});

CHECK_EXPR_INT("length(\"hello world\")", [](backend::Builder* builder) -> void {
builder->addLoadLitString("hello world");
builder->addLengthString();
});
}

SECTION("String checks") {
Expand Down
31 changes: 31 additions & 0 deletions tests/vm/string_op_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,37 @@ TEST_CASE("Execute string operations", "[vm]") {
},
"hello world");
}

SECTION("Length") {
CHECK_EXPR(
[](backend::Builder* builder) -> void {
builder->addLoadLitString("");
builder->addLengthString();
builder->addConvIntString();
builder->addPrintString();
},
"0");
CHECK_EXPR(
[](backend::Builder* builder) -> void {
builder->addLoadLitString("hello");
builder->addLengthString();
builder->addConvIntString();
builder->addPrintString();
},
"5");
CHECK_EXPR(
[](backend::Builder* builder) -> void {
builder->addLoadLitString("hello");
builder->addLoadLitString(" ");
builder->addAddString();
builder->addLoadLitString("world");
builder->addAddString();
builder->addLengthString();
builder->addConvIntString();
builder->addPrintString();
},
"11");
}
}

} // namespace vm

0 comments on commit 1e3b64d

Please sign in to comment.