Files
whetstone_DSL/editor/tests/step460_test.cpp

161 lines
5.6 KiB
C++
Raw Normal View History

// Step 460: Assembly AST Nodes Tests (12 tests)
#include "ast/AssemblyNodes.h"
#include <iostream>
static int passed = 0, failed = 0;
#define TEST(name) { std::cout << " " << #name << "... "; }
#define PASS() { std::cout << "PASS\n"; ++passed; }
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
void test_instruction_node_fields() {
TEST(instruction_node_fields);
AssemblyInstruction ins("mov", {"rax", "rbx"});
CHECK(ins.conceptType == "AssemblyInstruction", "wrong conceptType");
CHECK(ins.opcode == "mov", "wrong opcode");
CHECK(ins.operands.size() == 2, "wrong operand count");
PASS();
}
void test_label_node_fields() {
TEST(label_node_fields);
AssemblyLabel label("main", true);
CHECK(label.conceptType == "AssemblyLabel", "wrong conceptType");
CHECK(label.name == "main", "wrong label name");
CHECK(label.isGlobal, "expected global label");
PASS();
}
void test_directive_node_fields() {
TEST(directive_node_fields);
AssemblyDirective d(AssemblyDirectiveType::Text, "");
CHECK(d.conceptType == "AssemblyDirective", "wrong conceptType");
CHECK(d.type == AssemblyDirectiveType::Text, "wrong directive type");
PASS();
}
void test_register_node_fields() {
TEST(register_node_fields);
AssemblyRegister r("rax", 64);
CHECK(r.conceptType == "AssemblyRegister", "wrong conceptType");
CHECK(r.name == "rax", "wrong register name");
CHECK(r.sizeBits == 64, "wrong register size");
PASS();
}
void test_memory_operand_fields() {
TEST(memory_operand_fields);
AssemblyMemoryOperand m;
m.baseRegister = "rbp";
m.offset = -8;
m.indexRegister = "rbx";
m.scale = 4;
CHECK(m.conceptType == "AssemblyMemoryOperand", "wrong conceptType");
CHECK(m.baseRegister == "rbp", "wrong base register");
CHECK(m.offset == -8, "wrong offset");
CHECK(m.scale == 4, "wrong scale");
PASS();
}
void test_directive_type_string_roundtrip() {
TEST(directive_type_string_roundtrip);
auto s = directiveTypeToString(AssemblyDirectiveType::Global);
auto t = directiveTypeFromString(s);
CHECK(s == ".global", "wrong directive string");
CHECK(t == AssemblyDirectiveType::Global, "wrong directive parse");
PASS();
}
void test_register_json_roundtrip() {
TEST(register_json_roundtrip);
AssemblyRegister r("eax", 32);
auto j = toJson(r);
auto out = registerFromJson(j);
CHECK(out.name == "eax", "wrong register from json");
CHECK(out.sizeBits == 32, "wrong register bits from json");
PASS();
}
void test_memory_operand_json_roundtrip() {
TEST(memory_operand_json_roundtrip);
AssemblyMemoryOperand m;
m.baseRegister = "rax";
m.offset = 8;
m.indexRegister = "rcx";
m.scale = 2;
auto j = toJson(m);
auto out = memoryOperandFromJson(j);
CHECK(out.baseRegister == "rax", "wrong base register from json");
CHECK(out.offset == 8, "wrong offset from json");
CHECK(out.indexRegister == "rcx", "wrong index register from json");
CHECK(out.scale == 2, "wrong scale from json");
PASS();
}
void test_instruction_json_roundtrip_with_structured_operands() {
TEST(instruction_json_roundtrip_with_structured_operands);
AssemblyInstruction i("add", {"rax", "[rbp-8]"});
i.registers.push_back(AssemblyRegister("rax", 64));
AssemblyMemoryOperand m;
m.baseRegister = "rbp";
m.offset = -8;
i.memoryOperands.push_back(m);
auto j = toJson(i);
auto out = instructionFromJson(j);
CHECK(out.opcode == "add", "wrong opcode from json");
CHECK(out.operands.size() == 2, "wrong operand count from json");
CHECK(out.registers.size() == 1, "wrong register count from json");
CHECK(out.memoryOperands.size() == 1, "wrong mem operand count from json");
PASS();
}
void test_label_json_roundtrip() {
TEST(label_json_roundtrip);
AssemblyLabel l("loop_start", false);
auto j = toJson(l);
auto out = labelFromJson(j);
CHECK(out.name == "loop_start", "wrong label from json");
CHECK(!out.isGlobal, "wrong global flag from json");
PASS();
}
void test_directive_json_roundtrip() {
TEST(directive_json_roundtrip);
AssemblyDirective d(AssemblyDirectiveType::Align, "16");
auto j = toJson(d);
auto out = directiveFromJson(j);
CHECK(out.type == AssemblyDirectiveType::Align, "wrong directive type from json");
CHECK(out.value == "16", "wrong directive value from json");
PASS();
}
void test_unknown_directive_parses_to_unknown() {
TEST(unknown_directive_parses_to_unknown);
auto t = directiveTypeFromString(".bogus");
CHECK(t == AssemblyDirectiveType::Unknown, "expected unknown directive type");
PASS();
}
int main() {
std::cout << "Step 460: Assembly AST Nodes Tests\n";
test_instruction_node_fields(); // 1
test_label_node_fields(); // 2
test_directive_node_fields(); // 3
test_register_node_fields(); // 4
test_memory_operand_fields(); // 5
test_directive_type_string_roundtrip(); // 6
test_register_json_roundtrip(); // 7
test_memory_operand_json_roundtrip(); // 8
test_instruction_json_roundtrip_with_structured_operands(); // 9
test_label_json_roundtrip(); // 10
test_directive_json_roundtrip(); // 11
test_unknown_directive_parses_to_unknown(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed)
<< " passed\n";
return failed == 0 ? 0 : 1;
}