lean4-htt/src/tests/frontends/lean/scanner.cpp
Leonardo de Moura 6fc177056e refactor(tests/frontends/lean): use consistent name convention for file names
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-09-27 09:59:50 -07:00

119 lines
4 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <sstream>
#include "util/test.h"
#include "util/exception.h"
#include "util/escaped.h"
#include "frontends/lean/scanner.h"
using namespace lean;
#define st scanner::token
static void scan(char const * str, list<name> const & cmds = list<name>()) {
std::istringstream in(str);
scanner s(in);
for (name const & n : cmds) s.add_command_keyword(n);
while (true) {
st t = s.scan();
if (t == st::Eof)
break;
std::cout << t;
if (t == st::Id || t == st::CommandId)
std::cout << "[" << s.get_name_val() << "]";
else if (t == st::NatVal || t == st::DecimalVal)
std::cout << "[" << s.get_num_val() << "]";
else if (t == st::StringVal)
std::cout << "[\"" << escaped(s.get_str_val().c_str()) << "\"]";
std::cout << " ";
}
std::cout << "\n";
}
static void check(char const * str, std::initializer_list<scanner::token> const & l, list<name> const & cmds = list<name>()) {
auto it = l.begin();
std::istringstream in(str);
scanner s(in);
for (name const & n : cmds) s.add_command_keyword(n);
while (true) {
st t = s.scan();
if (t == st::Eof) {
lean_assert(it == l.end());
return;
}
lean_assert(it != l.end());
lean_assert(t == *it);
++it;
}
}
static void check_name(char const * str, name const & expected) {
std::istringstream in(str);
scanner s(in);
st t = s.scan();
lean_assert(t == st::Id);
lean_assert(s.get_name_val() == expected);
lean_assert(s.scan() == st::Eof);
}
static void tst1() {
scan("fun(x: Pi A : Type, A -> A), (* (* test *) *) x+1 = 2.0 λ");
try {
scan("(* (* foo *)");
lean_unreachable();
} catch (exception const & ex) {
std::cout << "expected error: " << ex.what() << "\n";
}
}
static void tst2() {
scan("x::name");
scan("x::10::foo");
check("x::name", {st::Id});
check("fun (x : Bool), x", {st::Lambda, st::LeftParen, st::Id, st::Colon, st::Id, st::RightParen, st::Comma, st::Id});
check("+++", {st::Id});
check("x+y", {st::Id, st::Id, st::Id});
check("(* testing *)", {});
check(" 2.31 ", {st::DecimalVal});
check(" 333 22", {st::NatVal, st::NatVal});
check("Int -> Int", {st::Id, st::Arrow, st::Id});
check("Int --> Int", {st::Id, st::Id, st::Id});
check("x := 10", {st::Id, st::Assign, st::NatVal});
check("(x+1):Int", {st::LeftParen, st::Id, st::Id, st::NatVal, st::RightParen, st::Colon, st::Id});
check("{x}", {st::LeftCurlyBracket, st::Id, st::RightCurlyBracket});
check("\u03BB \u03A0 \u2192", {st::Lambda, st::Pi, st::Arrow});
scan("++\u2295++x\u2296\u2296");
check("++\u2295++x\u2296\u2296", {st::Id, st::Id, st::Id, st::Id, st::Id});
scan("x10");
check_name("x10", name("x10"));
check_name("x::10", name(name("x"), 10));
check_name("x::10::bla::0", name(name(name(name("x"), 10), "bla"), 0u));
check("0::1", {st::NatVal, st::Colon, st::Colon, st::NatVal});
check_name("\u2296\u2296", name("\u2296\u2296"));
try {
scan("x::1000000000000000000");
lean_unreachable();
} catch (exception const & ex) {
std::cout << "expected error: " << ex.what() << "\n";
}
scan("Theorem a : Bool Axiom b : Int", list<name>({"Theorem", "Axiom"}));
check("Theorem a : Bool Axiom b : Int", {st::CommandId, st::Id, st::Colon, st::Id, st::CommandId, st::Id, st::Colon, st::Id}, list<name>({"Theorem", "Axiom"}));
scan("foo \"tst\\\"\" : Int");
check("foo \"tst\\\"\" : Int", {st::Id, st::StringVal, st::Colon, st::Id});
try {
scan("\"foo");
lean_unreachable();
} catch (exception const & ex) {
std::cout << "expected error: " << ex.what() << "\n";
}
scan("2.13 1.2 0.5");
}
int main() {
tst1();
tst2();
return has_violations() ? 1 : 0;
}