Add support for passing custom parameters to script
This commit is contained in:
@@ -4,7 +4,7 @@ import io.smnp.data.entity.Note
|
||||
import io.smnp.type.model.Value
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
enum class DataType(val kotlinType: KClass<out Any>, val stringifier: (Any) -> String) {
|
||||
enum class DataType(private val kotlinType: KClass<out Any>, val stringifier: (Any) -> String) {
|
||||
INT(Int::class, { it.toString() }),
|
||||
FLOAT(Float::class, { it.toString() }),
|
||||
STRING(String::class, { it.toString() }),
|
||||
|
||||
@@ -41,6 +41,20 @@ data class Value(val type: DataType, val value: Any, val properties: Map<String,
|
||||
return Value(DataType.INT, value)
|
||||
}
|
||||
|
||||
fun wrap(obj: Any): Value {
|
||||
return when(obj) {
|
||||
is Unit -> void()
|
||||
is Int -> int(obj)
|
||||
is Float -> float(obj)
|
||||
is Boolean -> bool(obj)
|
||||
is String -> string(obj)
|
||||
is Note -> note(obj)
|
||||
is List<*> -> list((obj as List<Any>).map { wrap(it) })
|
||||
is Map<*, *> -> map((obj as Map<Any, Any>).map { (k, v) -> wrap(k) to wrap(v) }.toMap())
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
}
|
||||
|
||||
fun float(value: Float): Value {
|
||||
return Value(
|
||||
DataType.FLOAT,
|
||||
|
||||
@@ -7,22 +7,26 @@ import io.smnp.cli.model.enumeration.ModulesPrintMode
|
||||
import io.smnp.environment.DefaultEnvironment
|
||||
import io.smnp.ext.DefaultModuleRegistry
|
||||
import io.smnp.interpreter.DefaultInterpreter
|
||||
import io.smnp.type.model.Value
|
||||
|
||||
fun main(args: Array<String>): Unit = mainBody {
|
||||
ArgParser(args).parseInto(::Arguments).run {
|
||||
val interpreter = DefaultInterpreter()
|
||||
val environment = DefaultEnvironment()
|
||||
|
||||
environment.setVariable("__param__", Value.wrap(parameters.toMap()))
|
||||
|
||||
when {
|
||||
file != null -> interpreter.run(file!!, printTokens, printAst, dryRun)
|
||||
code != null -> interpreter.run(code!!, printTokens, printAst, dryRun)
|
||||
file != null -> interpreter.run(file!!, environment, printTokens, printAst, dryRun)
|
||||
code != null -> interpreter.run(code!!, environment, printTokens, printAst, dryRun)
|
||||
else -> null
|
||||
}?.let { it as DefaultEnvironment }?.let { environment ->
|
||||
}?.let { it as DefaultEnvironment }?.let { disposedEnvironment ->
|
||||
if(loadedModules != null) {
|
||||
println("Loaded modules:")
|
||||
when (loadedModules) {
|
||||
ModulesPrintMode.LIST -> environment.modules.forEach { println(it) }
|
||||
ModulesPrintMode.TREE -> environment.printModules(false)
|
||||
ModulesPrintMode.CONTENT -> environment.printModules(true)
|
||||
ModulesPrintMode.LIST -> disposedEnvironment.modules.forEach { println(it) }
|
||||
ModulesPrintMode.TREE -> disposedEnvironment.printModules(false)
|
||||
ModulesPrintMode.CONTENT -> disposedEnvironment.printModules(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,23 @@ class Arguments(parser: ArgParser) {
|
||||
"prints loaded modules as list of canonical names of each one. The 'tree' option organises modules into the tree model " +
|
||||
"and then prints them. The 'content' option is the same as tree, however, prints also contained functions and methods."
|
||||
) { ModulesPrintMode.valueOf(this.toUpperCase()) }.default<ModulesPrintMode?>(null)
|
||||
val parameters by parser.adding(
|
||||
"-P", "--parameter", help = "define parameter to be consumed in script. Default syntax for parameter " +
|
||||
"is 'key=value' (whitespaces around '=' are not allowed). In this case value will be of string type. " +
|
||||
"However, it is also possible to pass parameter without any value. In this case, value will be of bool type. " +
|
||||
"The parameters are available through global-accessible variable of map type and of '__param__' name."
|
||||
) {
|
||||
this.split("=").let {
|
||||
when (it.size) {
|
||||
1 -> it[0] to true
|
||||
else -> it[0] to it.subList(1, it.size).joinToString("=")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val code by parser.storing("-c", "--code", help = "inline code to be executed").default<String?>(null)
|
||||
val file by parser.positional("SOURCE", help = "file with SMNP language code to be executed") { File(this) }.default<File?>(null)
|
||||
val file by parser.positional(
|
||||
"SOURCE",
|
||||
help = "file with SMNP language code to be executed"
|
||||
) { File(this) }.default<File?>(null)
|
||||
}
|
||||
@@ -18,17 +18,18 @@ class DefaultInterpreter : Interpreter {
|
||||
|
||||
fun run(
|
||||
code: String,
|
||||
environment: Environment = DefaultEnvironment(),
|
||||
printTokens: Boolean = false,
|
||||
printAst: Boolean = false,
|
||||
dryRun: Boolean = false
|
||||
): Environment {
|
||||
val lines = code.split("\n")
|
||||
return run(lines, printTokens, printAst, dryRun)
|
||||
return run(lines, environment, printTokens, printAst, dryRun)
|
||||
}
|
||||
|
||||
private fun run(lines: List<String>, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
||||
private fun run(lines: List<String>, environment: Environment, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
||||
try {
|
||||
return tryToRun(lines, printTokens, printAst, dryRun)
|
||||
return tryToRun(lines, environment, printTokens, printAst, dryRun)
|
||||
} catch (e: SmnpException) {
|
||||
printError(e)
|
||||
exitProcess(1)
|
||||
@@ -40,8 +41,9 @@ class DefaultInterpreter : Interpreter {
|
||||
err.println(e.message)
|
||||
}
|
||||
|
||||
private fun tryToRun(lines: List<String>, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
||||
val environment = createEnvironment()
|
||||
private fun tryToRun(lines: List<String>, environment: Environment, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
||||
environment.loadModule("smnp.lang")
|
||||
|
||||
val tokens = tokenizer.tokenize(lines)
|
||||
val ast = parser.parse(tokens)
|
||||
|
||||
@@ -59,16 +61,9 @@ class DefaultInterpreter : Interpreter {
|
||||
return environment
|
||||
}
|
||||
|
||||
private fun createEnvironment(): Environment {
|
||||
val environment = DefaultEnvironment()
|
||||
environment.loadModule("smnp.lang")
|
||||
|
||||
return environment
|
||||
}
|
||||
|
||||
fun run(file: File, printTokens: Boolean = false, printAst: Boolean = false, dryRun: Boolean = false): Environment {
|
||||
fun run(file: File, environment: Environment = DefaultEnvironment(), printTokens: Boolean = false, printAst: Boolean = false, dryRun: Boolean = false): Environment {
|
||||
val lines = file.readLines()
|
||||
return run(lines, printTokens, printAst, dryRun)
|
||||
return run(lines, environment, printTokens, printAst, dryRun)
|
||||
}
|
||||
|
||||
override fun run(code: String) = run(code, printTokens = false, printAst = false, dryRun = false)
|
||||
|
||||
Reference in New Issue
Block a user