package interpreter import com.github.h0tk3y.betterParse.grammar.parseToEnd import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Nested import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import parser.grammars.TermsGrammar import prolog.ast.arithmetic.Float import prolog.ast.arithmetic.Integer import prolog.ast.terms.Atom import prolog.ast.terms.Goal import prolog.ast.terms.Structure import prolog.ast.terms.Term import prolog.ast.terms.Variable import prolog.builtins.Is import prolog.builtins.Subtract class ParserPreprocessorIntegrationTests { @Nested class `Arithmetic`() { val parser = TermsGrammar() val preprocessor = OpenPreprocessor() @ParameterizedTest @ValueSource(strings = ["-1", "-1.0", "-1.5"]) fun `can parse negative numbers`(input: String) { val number = if (input.contains('.')) { Float(input.substring(1).toFloat()) } else { Integer(input.substring(1).toInt()) } val negativeNumber = if (input.contains('.')) { Float(input.toFloat()) } else { Integer(input.toInt()) } // Check if parser returns the same result val parsed = parser.parseToEnd("X is $input") as Term assertEquals( Structure("is", Variable("X"), Structure("-",number)), parsed ) // Check if preprocessor returns the same result val prepped = preprocessor.preprocess(parsed) val expected = Is( Variable("X"), Subtract(Integer(0), number) ) assertEquals(expected, prepped) assertEquals(expected.toString(), prepped.toString()) // Check if evaluation is correct val solutions = (prepped as Is).satisfy(emptyMap()).toList() assertEquals(1, solutions.size) assertEquals(negativeNumber, solutions[0].getOrNull()!![Variable("X")]) } @ParameterizedTest @ValueSource(strings = ["X is 1 - 2", "X is 1-2"]) fun `can add negative numbers`(input: String) { val result = parser.parseToEnd(input) as Term assertEquals( Structure("is", Variable("X"), Structure("-", Integer(1), Integer(2))), result ) val prepped = preprocessor.preprocess(result) val expected = Is( Variable("X"), Subtract(Integer(1), Integer(2)) ) assertEquals(expected, prepped) assertEquals(expected.toString(), prepped.toString()) } } }