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 io.smnp.type.model.Value
|
||||||
import kotlin.reflect.KClass
|
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() }),
|
INT(Int::class, { it.toString() }),
|
||||||
FLOAT(Float::class, { it.toString() }),
|
FLOAT(Float::class, { it.toString() }),
|
||||||
STRING(String::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)
|
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 {
|
fun float(value: Float): Value {
|
||||||
return Value(
|
return Value(
|
||||||
DataType.FLOAT,
|
DataType.FLOAT,
|
||||||
|
|||||||
@@ -7,22 +7,26 @@ import io.smnp.cli.model.enumeration.ModulesPrintMode
|
|||||||
import io.smnp.environment.DefaultEnvironment
|
import io.smnp.environment.DefaultEnvironment
|
||||||
import io.smnp.ext.DefaultModuleRegistry
|
import io.smnp.ext.DefaultModuleRegistry
|
||||||
import io.smnp.interpreter.DefaultInterpreter
|
import io.smnp.interpreter.DefaultInterpreter
|
||||||
|
import io.smnp.type.model.Value
|
||||||
|
|
||||||
fun main(args: Array<String>): Unit = mainBody {
|
fun main(args: Array<String>): Unit = mainBody {
|
||||||
ArgParser(args).parseInto(::Arguments).run {
|
ArgParser(args).parseInto(::Arguments).run {
|
||||||
val interpreter = DefaultInterpreter()
|
val interpreter = DefaultInterpreter()
|
||||||
|
val environment = DefaultEnvironment()
|
||||||
|
|
||||||
|
environment.setVariable("__param__", Value.wrap(parameters.toMap()))
|
||||||
|
|
||||||
when {
|
when {
|
||||||
file != null -> interpreter.run(file!!, printTokens, printAst, dryRun)
|
file != null -> interpreter.run(file!!, environment, printTokens, printAst, dryRun)
|
||||||
code != null -> interpreter.run(code!!, printTokens, printAst, dryRun)
|
code != null -> interpreter.run(code!!, environment, printTokens, printAst, dryRun)
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { it as DefaultEnvironment }?.let { environment ->
|
}?.let { it as DefaultEnvironment }?.let { disposedEnvironment ->
|
||||||
if(loadedModules != null) {
|
if(loadedModules != null) {
|
||||||
println("Loaded modules:")
|
println("Loaded modules:")
|
||||||
when (loadedModules) {
|
when (loadedModules) {
|
||||||
ModulesPrintMode.LIST -> environment.modules.forEach { println(it) }
|
ModulesPrintMode.LIST -> disposedEnvironment.modules.forEach { println(it) }
|
||||||
ModulesPrintMode.TREE -> environment.printModules(false)
|
ModulesPrintMode.TREE -> disposedEnvironment.printModules(false)
|
||||||
ModulesPrintMode.CONTENT -> environment.printModules(true)
|
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 " +
|
"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."
|
"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)
|
) { 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 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(
|
fun run(
|
||||||
code: String,
|
code: String,
|
||||||
|
environment: Environment = DefaultEnvironment(),
|
||||||
printTokens: Boolean = false,
|
printTokens: Boolean = false,
|
||||||
printAst: Boolean = false,
|
printAst: Boolean = false,
|
||||||
dryRun: Boolean = false
|
dryRun: Boolean = false
|
||||||
): Environment {
|
): Environment {
|
||||||
val lines = code.split("\n")
|
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 {
|
try {
|
||||||
return tryToRun(lines, printTokens, printAst, dryRun)
|
return tryToRun(lines, environment, printTokens, printAst, dryRun)
|
||||||
} catch (e: SmnpException) {
|
} catch (e: SmnpException) {
|
||||||
printError(e)
|
printError(e)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
@@ -40,8 +41,9 @@ class DefaultInterpreter : Interpreter {
|
|||||||
err.println(e.message)
|
err.println(e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToRun(lines: List<String>, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
private fun tryToRun(lines: List<String>, environment: Environment, printTokens: Boolean, printAst: Boolean, dryRun: Boolean): Environment {
|
||||||
val environment = createEnvironment()
|
environment.loadModule("smnp.lang")
|
||||||
|
|
||||||
val tokens = tokenizer.tokenize(lines)
|
val tokens = tokenizer.tokenize(lines)
|
||||||
val ast = parser.parse(tokens)
|
val ast = parser.parse(tokens)
|
||||||
|
|
||||||
@@ -59,16 +61,9 @@ class DefaultInterpreter : Interpreter {
|
|||||||
return environment
|
return environment
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createEnvironment(): Environment {
|
fun run(file: File, environment: Environment = DefaultEnvironment(), printTokens: Boolean = false, printAst: Boolean = false, dryRun: Boolean = false): Environment {
|
||||||
val environment = DefaultEnvironment()
|
|
||||||
environment.loadModule("smnp.lang")
|
|
||||||
|
|
||||||
return environment
|
|
||||||
}
|
|
||||||
|
|
||||||
fun run(file: File, printTokens: Boolean = false, printAst: Boolean = false, dryRun: Boolean = false): Environment {
|
|
||||||
val lines = file.readLines()
|
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)
|
override fun run(code: String) = run(code, printTokens = false, printAst = false, dryRun = false)
|
||||||
|
|||||||
Reference in New Issue
Block a user