Last active
September 11, 2019 04:19
-
-
Save hikaMaeng/a00d3826cf4bde2922be81a9aee91ce2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ein.core.core | |
import ein.core.regex.eReg | |
interface ePrimitive { | |
companion object { | |
val EMPTY = ePrimitive("") | |
operator fun invoke(v:String) = eString(v) | |
operator fun invoke(v:Long) = eLong(v) | |
operator fun invoke(v:Double) = eDouble(v) | |
operator fun invoke(v:Boolean) = eBoolean(v) | |
fun store(v:String) = eStore(v) | |
fun record(v:String) = eRecord(v) | |
fun json(v:String) = eReg.json.parse(v) | |
} | |
} | |
class eString(val v:String):ePrimitive | |
class eLong(val v:Long):ePrimitive | |
class eDouble(val v:Double):ePrimitive | |
class eBoolean(val v:Boolean):ePrimitive | |
class eStore(val v:String):ePrimitive | |
class eRecord(val v:String):ePrimitive | |
class eJsonArray:MutableList<ePrimitive> by mutableListOf(), ePrimitive | |
class eJsonObject:MutableMap<String, ePrimitive> by mutableMapOf(), ePrimitive{ | |
operator fun invoke(key:String) = invoke(key.split(".")) | |
operator fun invoke(key:List<String>)= key.fold(this as ePrimitive){target, k-> | |
when(target){ | |
is eJsonObject->target[k] | |
is eJsonArray->target[k.toInt()] | |
else->null | |
} ?: throw Throwable("invalid key:$k") | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ein.core.regex | |
abstract class eReg(r:String){ | |
internal val re = r.toRegex() | |
companion object{ | |
val value = ein.core.regex.value | |
val json = ein.core.regex.json | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ein.core.regex | |
import ein.core.core.eJsonArray | |
import ein.core.core.eJsonObject | |
import ein.core.core.ePrimitive | |
object json{ | |
private val atom = """\s*(\{[^\{\}\[\]]*\}|\[[^\{\}\[\]]*\])\s*""".toRegex(RegexOption.MULTILINE) | |
private val jsonAtomKey = """<@#([0-9]+)!\$>""".toRegex() | |
private val jsonKey = """^\s*("(?:[^":]*)"|(?:[^:,\s"`]+)|`(?:[^`:]*)`)\s*:""".toRegex() | |
fun parse(txt:String):ePrimitive{ | |
if(txt.isBlank()) return ePrimitive.EMPTY | |
if(value.re.matches(txt)) return value(txt) ?: ePrimitive.EMPTY | |
val kv = mutableMapOf<String, String>() | |
var v = txt | |
var idx = 0 | |
while(atom.find(v) != null) v = atom.replace(v) { | |
val k = "<@#${idx++}!$>" | |
kv.put(k, it.groupValues[1]) | |
k | |
} | |
val map = mutableMapOf<String, ePrimitive>() | |
var last:ePrimitive = ePrimitive.EMPTY | |
kv.forEach {(k, v)-> | |
var txt = v.substring(1, v.length - 1) | |
last = if(v[0] == '{') { | |
val obj = eJsonObject() | |
while(jsonKey.find(txt) != null){ | |
val k = jsonKey.find(txt)?.groupValues?.get(1) ?: "" | |
txt = jsonKey.replaceFirst(txt, "") | |
if(value.re.find(txt) != null){ | |
obj[k] = value(txt) ?: ePrimitive.EMPTY | |
txt = value.re.replaceFirst(txt, "") | |
}else if(jsonAtomKey.find(txt) != null){ | |
obj[k] = map[jsonAtomKey.find(txt)?.groupValues?.get(0) ?: ""] ?: ePrimitive.EMPTY | |
txt = jsonAtomKey.replaceFirst(txt, "") | |
}else break | |
if(txt[0] == ',') txt = txt.substring(1) else break | |
} | |
obj | |
}else{ | |
val arr = eJsonArray() | |
do{ | |
if(value.re.find(txt) != null) { | |
arr += value(txt) ?: ePrimitive.EMPTY | |
txt = value.re.replaceFirst(txt, "") | |
}else if(jsonAtomKey.find(txt) != null){ | |
arr += map[jsonAtomKey.find(txt)?.groupValues?.get(0) ?: ""] ?: ePrimitive.EMPTY | |
txt = jsonAtomKey.replaceFirst(txt, "") | |
}else break | |
if(txt[0] == ',') txt = txt.substring(1) else break | |
}while(true) | |
arr | |
} | |
map[k] = last | |
} | |
return last | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ein.core.regex | |
import ein.core.core.ePrimitive | |
object value: eReg("""^\s*""" + | |
//1,2-string | |
"""(?:"((?:[^\\"]+|\\["\\bfnrt]|\\u[0-9a-fA-invoke]{4})*)"|`((?:[^`]+|\\[`\\bfnrt]|\\u[0-9a-fA-invoke]{4})*)`|""" + | |
//3-long | |
"""(-?(?:0|[1-9]\d*)(?:dp|sp|%w|%h)?)|""" + | |
//4-double | |
"""(-?(?:0|[1-9]\d*)(?:\.\d+)(?:[eE][-+]?\d+)?(?:dp|%w|%h)?)|"""+ | |
//5-bool | |
"""(true|false)|""" + | |
//6-store, 7-record | |
"""(?:\@\{([^}]+)\})|(?:\$\{([^}]*)\}))\s*""" | |
){ | |
operator fun invoke(v:String) = re.find(v)?.let{ | |
val g = it.groups | |
g[1]?.let{ePrimitive(it.value)} ?: | |
g[2]?.let{ePrimitive(it.value)} ?: | |
g[3]?.let{ePrimitive(group3(it))} ?: | |
g[4]?.let{ePrimitive(group4(it))} ?: | |
g[5]?.let{ePrimitive(it.value.toBoolean())} ?: | |
g[6]?.let{ePrimitive.store(it.value)} ?: | |
g[7]?.let{ePrimitive.record(it.value)} | |
} | |
fun group3(it:MatchGroup):Long{ | |
val v = it.value | |
return when { | |
v.endsWith("dp")->(v.substring(0, v.length - 2).toDouble()).toLong() | |
v.endsWith("sp")->(v.substring(0, v.length - 2).toDouble()).toLong() | |
v.endsWith("%w")->(v.substring(0, v.length - 2).toDouble()).toLong() | |
v.endsWith("%h")->(v.substring(0, v.length - 2).toDouble()).toLong() | |
else->v.toLong() | |
} | |
} | |
fun group4(it:MatchGroup):Double{ | |
val v = it.value | |
return when { | |
v.endsWith("dp") -> v.substring(0, v.length - 2).toDouble() | |
v.endsWith("sp") -> v.substring(0, v.length - 2).toDouble() | |
v.endsWith("%w") -> v.substring(0, v.length - 2).toDouble() | |
v.endsWith("%h") -> v.substring(0, v.length - 2).toDouble() | |
else -> v.toDouble() | |
} | |
} | |
fun num(it:String):Number? = re.find(it)?.let{it.groups[3]?.let{group3(it)} ?: it.groups[4]?.let{group4(it)}} as Number? | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment