From 8e6a34a2317cb29e796f5228ada6058a2dba66e3 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Mon, 28 Apr 2025 13:36:24 +0200 Subject: [PATCH] Argument parsing --- build.gradle.kts | 2 ++ src/Main.kt | 42 ++++++++++++++++++---- src/interpreter/Preprocessor.kt | 2 +- src/io/GhentPrologArgParser.kt | 21 +++++++++++ src/prolog/builtins/arithmeticOperators.kt | 4 ++- 5 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 src/io/GhentPrologArgParser.kt diff --git a/build.gradle.kts b/build.gradle.kts index a50fab0..ea7f816 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,8 @@ repositories { } dependencies { + // CLI argument parsing + implementation("com.xenomachina:kotlin-argparser:2.0.7") // Parser combinator library implementation("com.github.h0tk3y.betterParse:better-parse:0.4.4") diff --git a/src/Main.kt b/src/Main.kt index 1c9e0d6..a9ea4f8 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -1,15 +1,45 @@ +import com.sun.org.apache.bcel.internal.util.Args +import com.xenomachina.argparser.ArgParser +import com.xenomachina.argparser.mainBody import interpreter.FileLoader +import io.GhentPrologArgParser import io.Logger import prolog.Program import prolog.ast.logic.Clause import repl.Repl -fun main() { - // TODO Make this a command line argument - // Turn on debug mode - Logger.level = Logger.Level.DEBUG +fun main(args: Array) = mainBody { + // Parse command line arguments + val parsedArgs = ArgParser(args).parseInto(::GhentPrologArgParser) - FileLoader().load("tests/parser/resources/parent.pl") + parsedArgs.run { + val loader = FileLoader() - Repl().start() + // Set the verbosity level + Logger.level = verbosity + + // Check if script was provided + for (file in script) { + loader.load(file) + } + + // Check if REPL was requested + if (repl) { + Repl().start() + } else { + Logger.warn("REPL not started. Use -r or --repl to start the REPL.") + } + } +} + +fun help() { + println(""" + Ghent Prolog: A Prolog interpreter in Kotlin + + Options: + -s, --source Specify the source file to load + -r, --repl Start the REPL (default) + -v, --verb + -h, --help Show this help message + """.trimIndent()) } diff --git a/src/interpreter/Preprocessor.kt b/src/interpreter/Preprocessor.kt index b05c99d..a20535d 100644 --- a/src/interpreter/Preprocessor.kt +++ b/src/interpreter/Preprocessor.kt @@ -123,7 +123,7 @@ open class Preprocessor { } if (prepped != term || prepped::class != term::class) { - Logger.debug("Preprocessed term: $term -> $prepped (${prepped::class})") + Logger.debug("Preprocessed term: $term -> $prepped (is ${prepped::class.simpleName})") } return prepped diff --git a/src/io/GhentPrologArgParser.kt b/src/io/GhentPrologArgParser.kt new file mode 100644 index 0000000..f27f579 --- /dev/null +++ b/src/io/GhentPrologArgParser.kt @@ -0,0 +1,21 @@ +package io + +import com.xenomachina.argparser.ArgParser +import com.xenomachina.argparser.default + +class GhentPrologArgParser(parser: ArgParser) { + val script by parser.adding("-s", "--script", help = "Script to run") + val repl by parser.flagging("-r", "--repl", help = "Start the REPL") + + val verbosity by parser.mapping( + "--vvv" to Logger.Level.DEBUG, + "--debug" to Logger.Level.DEBUG, + "--vv" to Logger.Level.INFO, + "--verbose" to Logger.Level.INFO, + "--info" to Logger.Level.INFO, + "-v" to Logger.Level.WARN, + "--warn" to Logger.Level.WARN, + "--error" to Logger.Level.ERROR, + help = "Set the verbosity level (default: WARN)", + ).default(Logger.defaultLevel) +} \ No newline at end of file diff --git a/src/prolog/builtins/arithmeticOperators.kt b/src/prolog/builtins/arithmeticOperators.kt index ca86a2e..306337e 100644 --- a/src/prolog/builtins/arithmeticOperators.kt +++ b/src/prolog/builtins/arithmeticOperators.kt @@ -144,7 +144,7 @@ class Divide(private val expr1: Expression, private val expr2: Expression) : // TODO Expr rem Expr class Between(private val expr1: Expression, private val expr2: Expression, private val expr3: Expression) : - Operator(Atom("between"), expr1, expr2) { + CompoundTerm(Atom("between"), listOf(expr1, expr2, expr3)), Satisfiable { override fun satisfy(subs: Substitutions): Answers { val e1 = expr1.simplify(subs) val e2 = expr2.simplify(subs) @@ -165,4 +165,6 @@ class Between(private val expr1: Expression, private val expr2: Expression, priv } } } + + override fun toString(): String = "$expr1..$expr3..$expr2" }