Compare commits
2 Commits
23737f9b5c
...
cad6ba936d
Author | SHA1 | Date | |
---|---|---|---|
cad6ba936d | |||
cb333ab6bd |
@ -138,6 +138,7 @@ publishing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//mavenPublishing {
|
//mavenPublishing {
|
||||||
// publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
|
// publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
|
||||||
//
|
//
|
||||||
|
@ -211,11 +211,32 @@ class Compiler(
|
|||||||
private suspend fun parseTerm(): Accessor? {
|
private suspend fun parseTerm(): Accessor? {
|
||||||
var operand: Accessor? = null
|
var operand: Accessor? = null
|
||||||
|
|
||||||
|
// newlines _before_
|
||||||
|
cc.skipWsTokens()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val t = cc.next()
|
val t = cc.next()
|
||||||
val startPos = t.pos
|
val startPos = t.pos
|
||||||
when (t.type) {
|
when (t.type) {
|
||||||
Token.Type.NEWLINE, Token.Type.SEMICOLON, Token.Type.EOF, Token.Type.RBRACE, Token.Type.COMMA -> {
|
// Token.Type.NEWLINE, Token.Type.SINLGE_LINE_COMMENT, Token.Type.MULTILINE_COMMENT-> {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// very special case chained calls: call()<NL>.call2 {}.call3()
|
||||||
|
Token.Type.NEWLINE -> {
|
||||||
|
val saved = cc.savePos()
|
||||||
|
if( cc.peekNextNonWhitespace().type == Token.Type.DOT) {
|
||||||
|
// chained call continue from it
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
// restore position and stop parsing as a term:
|
||||||
|
cc.restorePos(saved)
|
||||||
|
cc.previous()
|
||||||
|
return operand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Token.Type.SEMICOLON, Token.Type.EOF, Token.Type.RBRACE, Token.Type.COMMA -> {
|
||||||
cc.previous()
|
cc.previous()
|
||||||
return operand
|
return operand
|
||||||
}
|
}
|
||||||
@ -468,7 +489,13 @@ class Compiler(
|
|||||||
// range operator
|
// range operator
|
||||||
val isEndInclusive = t.type == Token.Type.DOTDOT
|
val isEndInclusive = t.type == Token.Type.DOTDOT
|
||||||
val left = operand
|
val left = operand
|
||||||
val right = parseExpression()
|
// if it is an open end range, then the end of line could be here that we do not want
|
||||||
|
// to skip in parseExpression:
|
||||||
|
val current = cc.current()
|
||||||
|
val right = if( current.type == Token.Type.NEWLINE || current.type == Token.Type.SINLGE_LINE_COMMENT)
|
||||||
|
null
|
||||||
|
else
|
||||||
|
parseExpression()
|
||||||
operand = Accessor {
|
operand = Accessor {
|
||||||
ObjRange(
|
ObjRange(
|
||||||
left?.getter?.invoke(it)?.value ?: ObjNull,
|
left?.getter?.invoke(it)?.value ?: ObjNull,
|
||||||
@ -864,7 +891,7 @@ class Compiler(
|
|||||||
|
|
||||||
suspend fun parseAnnotation(t: Token): (suspend (Scope, ObjString, Statement) -> Statement) {
|
suspend fun parseAnnotation(t: Token): (suspend (Scope, ObjString, Statement) -> Statement) {
|
||||||
val extraArgs = parseArgsOrNull()
|
val extraArgs = parseArgsOrNull()
|
||||||
println("annotation ${t.value}: args: $extraArgs")
|
// println("annotation ${t.value}: args: $extraArgs")
|
||||||
return { scope, name, body ->
|
return { scope, name, body ->
|
||||||
val extras = extraArgs?.first?.toArguments(scope, extraArgs.second)?.list
|
val extras = extraArgs?.first?.toArguments(scope, extraArgs.second)?.list
|
||||||
val required = listOf(name, body)
|
val required = listOf(name, body)
|
||||||
@ -955,7 +982,7 @@ class Compiler(
|
|||||||
|
|
||||||
private suspend fun parseWhenStatement(): Statement {
|
private suspend fun parseWhenStatement(): Statement {
|
||||||
// has a value, when(value) ?
|
// has a value, when(value) ?
|
||||||
var t = cc.skipWsTokens()
|
var t = cc.nextNonWhitespace()
|
||||||
return if (t.type == Token.Type.LPAREN) {
|
return if (t.type == Token.Type.LPAREN) {
|
||||||
// when(value)
|
// when(value)
|
||||||
val value = parseStatement() ?: throw ScriptError(cc.currentPos(), "when(value) expected")
|
val value = parseStatement() ?: throw ScriptError(cc.currentPos(), "when(value) expected")
|
||||||
@ -978,7 +1005,7 @@ class Compiler(
|
|||||||
|
|
||||||
// loop conditions
|
// loop conditions
|
||||||
while (true) {
|
while (true) {
|
||||||
t = cc.skipWsTokens()
|
t = cc.nextNonWhitespace()
|
||||||
|
|
||||||
when (t.type) {
|
when (t.type) {
|
||||||
Token.Type.IN,
|
Token.Type.IN,
|
||||||
@ -1191,11 +1218,11 @@ class Compiler(
|
|||||||
cc.skipTokenOfType(Token.Type.LBRACE)
|
cc.skipTokenOfType(Token.Type.LBRACE)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
val t = cc.skipWsTokens()
|
val t = cc.nextNonWhitespace()
|
||||||
when (t.type) {
|
when (t.type) {
|
||||||
Token.Type.ID -> {
|
Token.Type.ID -> {
|
||||||
names += t.value
|
names += t.value
|
||||||
val t1 = cc.skipWsTokens()
|
val t1 = cc.nextNonWhitespace()
|
||||||
when (t1.type) {
|
when (t1.type) {
|
||||||
Token.Type.COMMA ->
|
Token.Type.COMMA ->
|
||||||
continue
|
continue
|
||||||
|
@ -39,7 +39,6 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
fun next() =
|
fun next() =
|
||||||
if (currentIndex < tokens.size) tokens[currentIndex++]
|
if (currentIndex < tokens.size) tokens[currentIndex++]
|
||||||
else Token("", tokens.last().pos, Token.Type.EOF)
|
else Token("", tokens.last().pos, Token.Type.EOF)
|
||||||
// throw IllegalStateException("No more tokens")
|
|
||||||
|
|
||||||
fun previous() = if (!hasPrevious()) throw IllegalStateException("No previous token") else tokens[--currentIndex]
|
fun previous() = if (!hasPrevious()) throw IllegalStateException("No previous token") else tokens[--currentIndex]
|
||||||
|
|
||||||
@ -131,6 +130,28 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
previous()
|
previous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun nextNonWhitespace(): Token {
|
||||||
|
while (true) {
|
||||||
|
val t = next()
|
||||||
|
if (t.type !in wstokens) return t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find next non-whitespace token and return it. The token is not extracted,
|
||||||
|
* is will be returned on [next] call.
|
||||||
|
* @return next non-whitespace token without extracting it from tokens list
|
||||||
|
*/
|
||||||
|
fun peekNextNonWhitespace(): Token {
|
||||||
|
while (true) {
|
||||||
|
val t = next()
|
||||||
|
if (t.type !in wstokens) {
|
||||||
|
previous()
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline fun ifNextIs(typeId: Token.Type, f: (Token) -> Unit): Boolean {
|
inline fun ifNextIs(typeId: Token.Type, f: (Token) -> Unit): Boolean {
|
||||||
val t = next()
|
val t = next()
|
||||||
@ -207,7 +228,7 @@ class CompilerContext(val tokens: List<Token>) {
|
|||||||
while (current().type in wstokens) {
|
while (current().type in wstokens) {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
return next()
|
return current()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -436,6 +436,9 @@ object ObjNull : Obj() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: get rid of it. Maybe we ise some Lyng inheritance instead
|
||||||
|
*/
|
||||||
interface Numeric {
|
interface Numeric {
|
||||||
val longValue: Long
|
val longValue: Long
|
||||||
val doubleValue: Double
|
val doubleValue: Double
|
||||||
|
@ -1184,6 +1184,35 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testOpenEndRanges2() = runTest {
|
||||||
|
eval(
|
||||||
|
"""
|
||||||
|
var r = 5..; var r2 = 6..
|
||||||
|
val r3 = 7.. // open end
|
||||||
|
assert( r::class == Range)
|
||||||
|
assert( r.end == null)
|
||||||
|
assert( r.start == 5)
|
||||||
|
|
||||||
|
assert( r3::class == Range)
|
||||||
|
assertEquals( r3.end, null)
|
||||||
|
assert( r3.start == 7)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testOpenEndRanges3() = runTest {
|
||||||
|
eval(
|
||||||
|
"""
|
||||||
|
val r3 = 7.. // open end with comment
|
||||||
|
assert( r3::class == Range)
|
||||||
|
assertEquals( r3.end, null)
|
||||||
|
assert( r3.start == 7)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCharacterRange() = runTest {
|
fun testCharacterRange() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -2991,5 +3020,20 @@ class ScriptTest {
|
|||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testNewlinesAnsCommentsInExpressions() = runTest {
|
||||||
|
assertEquals( 2, (Scope().eval("""
|
||||||
|
val e = 1 + 4 -
|
||||||
|
3
|
||||||
|
""".trimIndent())).toInt())
|
||||||
|
|
||||||
|
eval("""
|
||||||
|
val x = [1,2,3]
|
||||||
|
.map { it * 10 }
|
||||||
|
.map { it + 1 }
|
||||||
|
assertEquals( [11,21,31], x)
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user