121 lines
3.0 KiB
C++
121 lines
3.0 KiB
C++
#include <catch2/catch.hpp>
|
|
#include "../lib/Lexer.hpp"
|
|
#include "../lib/Parser.hpp"
|
|
|
|
class ParserTest
|
|
{
|
|
public:
|
|
explicit ParserTest() {}
|
|
virtual ~ParserTest() {}
|
|
|
|
void test_parse(std::string const& oracle,
|
|
std::string const& source)
|
|
{
|
|
wg::Lexer lex;
|
|
lex.scan(source);
|
|
auto tokens = lex.all();
|
|
|
|
wg::Parser parser;
|
|
|
|
auto node = parser.parse(tokens);
|
|
|
|
REQUIRE(oracle == node->string());
|
|
}
|
|
|
|
protected:
|
|
};
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_dir")
|
|
{
|
|
test_parse("PROG(DIR(IDENT[hello],IDENT[world]))",
|
|
"#hello world");
|
|
|
|
test_parse("PROG(DIR(IDENT[hello],IDENT[world],IDENT[boom]))",
|
|
"#hello world as boom");
|
|
}
|
|
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_int")
|
|
{
|
|
test_parse("PROG(INT[45])",
|
|
" 45; ");
|
|
|
|
test_parse("PROG(ADD(INT[1],MUL(INT[2],INT[3])))",
|
|
" 1 + 2 * 3; ");
|
|
|
|
test_parse("PROG(MUL(ADD(INT[1],INT[2]),INT[3]))",
|
|
" (1 + 2) * 3; ");
|
|
|
|
test_parse("PROG(SUB(INT[1],DIV(INT[2],INT[3])))",
|
|
" 1 - 2 / 3; ");
|
|
|
|
test_parse("PROG(DIV(SUB(INT[1],INT[2]),INT[3]))",
|
|
" (1 - 2) / 3; ");
|
|
|
|
test_parse("PROG(ADD(INT[1],MOD(INT[2],INT[3])))",
|
|
" 1 + 2 % 3; ");
|
|
|
|
test_parse("PROG(MOD(ADD(INT[1],INT[2]),INT[3]))",
|
|
" (1 + 2) % 3; ");
|
|
}
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_call")
|
|
{
|
|
test_parse("PROG(CALL(IDENT[hello],ARGS))",
|
|
" hello(); ");
|
|
|
|
test_parse("PROG(CALL(IDENT[hello_world],ARGS(IDENT[x])))",
|
|
" hello_world(x); ");
|
|
|
|
test_parse("PROG(CALL(IDENT[hello_world],ARGS(IDENT[x],INT[78])))",
|
|
" hello_world(x, 78); ");
|
|
}
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_fundecl")
|
|
{
|
|
test_parse("PROG(EXTERN(IDENT[hello],"
|
|
"PARAMS(IDENT[x],IDENT[y],TYPE[int]),RET(TYPE[int])))",
|
|
" extern fun hello(x, y int) int; ");
|
|
|
|
test_parse("PROG(FUNDECL(IDENT[couc],PARAMS,RET,BLOCK))",
|
|
" fun couc() {} ");
|
|
|
|
test_parse("PROG(FUNDECL(IDENT[couc],PARAMS("
|
|
"IDENT[x],IDENT[y],TYPE[int]"
|
|
"),RET,BLOCK(RETURN(INT[4]))))",
|
|
" fun couc(x, y int) { return 4; } ");
|
|
|
|
test_parse("PROG(FUNDECL(IDENT[couc],PARAMS("
|
|
"IDENT[x],IDENT[y],TYPE[int]"
|
|
"),RET(TYPE[int]),BLOCK(RETURN(INT[4]))))",
|
|
" fun couc(x, y int) int { return 4; } ");
|
|
|
|
test_parse("PROG(RETURN(ADD(CALL(IDENT[a],ARGS),INT[1])))",
|
|
" return a() + 1; ");
|
|
}
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_namespace")
|
|
{
|
|
test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],IDENT[d]))",
|
|
" a.b.c.d; ");
|
|
|
|
test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],"
|
|
"CALL(IDENT[d],ARGS)))",
|
|
" a.b.c.d(); ");
|
|
}
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_bool")
|
|
{
|
|
test_parse("PROG(OR(AND(NOT(BOOL[true]),BOOL[false]),BOOL[true]))",
|
|
" not true and false or true; ");
|
|
}
|
|
|
|
TEST_CASE_METHOD(ParserTest, "Parser_comparisons")
|
|
{
|
|
test_parse("PROG(AND(EQ(INT[7],INT[3]),LT(INT[3],INT[7])))",
|
|
" 7 == 3 and 3 < 7; ");
|
|
|
|
test_parse("PROG(OR(NE(INT[7],INT[3]),GE(INT[3],INT[7])))",
|
|
" 7 <> 3 or 3 >= 7; ");
|
|
}
|