[orx-keyframer] Add support for backticked identifier names, replace spek tests
This commit is contained in:
@@ -20,7 +20,7 @@ DECIMAL : 'Decimal';
|
||||
STRING : 'String';
|
||||
|
||||
// Identifiers
|
||||
ID : [$_]*[a-zA-Z][A-Za-z0-9_]* ;
|
||||
ID : [$_]*[a-zA-Z][A-Za-z0-9_]* | '`'[$_]*[A-Za-z0-9_-]*'`';
|
||||
FUNCTION_ID : [$_]*[a-z][A-Za-z0-9_]* ;
|
||||
|
||||
// Literals
|
||||
@@ -38,6 +38,7 @@ ASSIGN : '=' ;
|
||||
LPAREN : '(' ;
|
||||
RPAREN : ')' ;
|
||||
|
||||
|
||||
COMMA : ',' ;
|
||||
|
||||
STRING_OPEN : '"' -> pushMode(MODE_IN_STRING);
|
||||
@@ -51,40 +52,5 @@ ESCAPE_SLASH : '\\\\' ;
|
||||
ESCAPE_NEWLINE : '\\n' ;
|
||||
ESCAPE_SHARP : '\\#' ;
|
||||
STRING_CLOSE : '"' -> popMode ;
|
||||
INTERPOLATION_OPEN : '#{' -> pushMode(MODE_IN_INTERPOLATION) ;
|
||||
STRING_CONTENT : ~["\n\r\t\\#]+ ;
|
||||
|
||||
STR_UNMATCHED : . -> type(UNMATCHED) ;
|
||||
|
||||
mode MODE_IN_INTERPOLATION;
|
||||
|
||||
INTERPOLATION_CLOSE : '}' -> popMode ;
|
||||
|
||||
INTERP_WS : [\t ]+ -> channel(WHITESPACE), type(WS) ;
|
||||
|
||||
// Keywords
|
||||
INTERP_AS : 'as'-> type(AS) ;
|
||||
INTERP_INT : 'Int'-> type(INT) ;
|
||||
INTERP_DECIMAL : 'Decimal'-> type(DECIMAL) ;
|
||||
INTERP_STRING : 'String'-> type(STRING) ;
|
||||
|
||||
// Literals
|
||||
INTERP_INTLIT : ('0'|[1-9][0-9]*) -> type(INTLIT) ;
|
||||
INTERP_DECLIT : ('0'|[1-9][0-9]*) '.' [0-9]+ -> type(DECLIT) ;
|
||||
|
||||
// Operators
|
||||
INTERP_PLUS : '+' -> type(PLUS) ;
|
||||
INTERP_MINUS : '-' -> type(MINUS) ;
|
||||
INTERP_ASTERISK : '*' -> type(ASTERISK) ;
|
||||
INTERP_DIVISION : '/' -> type(DIVISION) ;
|
||||
INTERP_PERCENTAGE : '%' -> type(PERCENTAGE) ;
|
||||
INTERP_ASSIGN : '=' -> type(ASSIGN) ;
|
||||
INTERP_LPAREN : '(' -> type(LPAREN) ;
|
||||
INTERP_RPAREN : ')' -> type(RPAREN) ;
|
||||
|
||||
// Identifiers
|
||||
INTERP_ID : [_]*[a-z][A-Za-z0-9_]* -> type(ID);
|
||||
|
||||
INTERP_STRING_OPEN : '"' -> type(STRING_OPEN), pushMode(MODE_IN_STRING);
|
||||
|
||||
INTERP_UNMATCHED : . -> type(UNMATCHED) ;
|
||||
|
||||
@@ -7,7 +7,7 @@ package org.openrndr.extra.keyframer.antlr;
|
||||
|
||||
options { tokenVocab=KeyLangLexer; }
|
||||
|
||||
miniCalcFile : lines=line+ ;
|
||||
keyLangFile : lines=line+ ;
|
||||
|
||||
line : statement (NEWLINE | EOF) ;
|
||||
|
||||
|
||||
@@ -248,11 +248,11 @@ internal class ExpressionListener(val functions: FunctionExtensions = FunctionEx
|
||||
doubleStack.push(node.text.toDouble())
|
||||
}
|
||||
if (type == KeyLangParser.ID) {
|
||||
|
||||
val name = node.text.replace("`","")
|
||||
@Suppress("DIVISION_BY_ZERO")
|
||||
when (val idType = idTypeStack.pop()) {
|
||||
IDType.VARIABLE -> doubleStack.push(
|
||||
when (val name = node.text) {
|
||||
when (name) {
|
||||
"PI" -> PI
|
||||
else -> variables[name] ?: errorValue("unresolved variable: '${name}'", 0.0 / 0.0)
|
||||
}
|
||||
@@ -260,11 +260,11 @@ internal class ExpressionListener(val functions: FunctionExtensions = FunctionEx
|
||||
|
||||
IDType.FUNCTION0 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
when (name) {
|
||||
"random" -> { _ -> Double.uniform(0.0, 1.0) }
|
||||
else -> functions.functions0[candidate]?.let { { _: DoubleArray -> it.invoke() } }
|
||||
else -> functions.functions0[name]?.let { { _: DoubleArray -> it.invoke() } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}()'"
|
||||
"unresolved function: '${name}()'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
@@ -272,7 +272,7 @@ internal class ExpressionListener(val functions: FunctionExtensions = FunctionEx
|
||||
|
||||
IDType.FUNCTION1 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
when (name) {
|
||||
"sqrt" -> { x -> sqrt(x[0]) }
|
||||
"radians" -> { x -> Math.toRadians(x[0]) }
|
||||
"degrees" -> { x -> Math.toDegrees(x[0]) }
|
||||
@@ -287,48 +287,54 @@ internal class ExpressionListener(val functions: FunctionExtensions = FunctionEx
|
||||
"floor" -> { x -> floor(x[0]) }
|
||||
"ceil" -> { x -> ceil(x[0]) }
|
||||
"saturate" -> { x -> x[0].coerceIn(0.0, 1.0) }
|
||||
else -> functions.functions1[candidate]?.let { { x: DoubleArray -> it.invoke(x[0]) } }
|
||||
else -> functions.functions1[name]?.let { { x: DoubleArray -> it.invoke(x[0]) } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}(x0)'"
|
||||
"unresolved function: '${name}(x0)'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
}
|
||||
IDType.FUNCTION2 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
when (name) {
|
||||
"max" -> { x -> max(x[0], x[1]) }
|
||||
"min" -> { x -> min(x[0], x[1]) }
|
||||
"pow" -> { x -> x[0].pow(x[1]) }
|
||||
"atan2" -> { x -> atan2(x[0], x[1]) }
|
||||
"random" -> { x -> Double.uniform(x[0], x[1]) }
|
||||
"length" -> { x -> Vector2(x[0], x[1]).length }
|
||||
else -> functions.functions2[candidate]?.let { { x: DoubleArray -> it.invoke(x[0], x[1]) } }
|
||||
else -> functions.functions2[name]?.let { { x: DoubleArray -> it.invoke(x[0], x[1]) } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}(x0, x1)'"
|
||||
"unresolved function: '${name}(x0, x1)'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
}
|
||||
IDType.FUNCTION3 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
when (name) {
|
||||
"mix" -> { x -> mix(x[0], x[1], x[2]) }
|
||||
"min" -> { x -> x.minOrNull()!! }
|
||||
"max" -> { x -> x.maxOrNull()!! }
|
||||
"sum" -> { x -> x.sum() }
|
||||
"smoothstep" -> { x -> smoothstep(x[0], x[1], x[2]) }
|
||||
"length" -> { x -> Vector3(x[0], x[1], x[2]).length }
|
||||
else -> functions.functions3[candidate]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2]) } }
|
||||
else -> functions.functions3[name]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2]) } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}(x0, x1, x2)'"
|
||||
"unresolved function: '${name}(x0, x1, x2)'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
}
|
||||
IDType.FUNCTION4 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
else -> functions.functions4[candidate]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2], x[3]) } }
|
||||
when (name) {
|
||||
"min" -> { x -> x.minOrNull()!! }
|
||||
"max" -> { x -> x.maxOrNull()!! }
|
||||
"sum" -> { x -> x.sum() }
|
||||
else -> functions.functions4[name]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2], x[3]) } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}(x0, x1, x2, x3)'"
|
||||
"unresolved function: '${name}(x0, x1, x2, x3)'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
@@ -336,11 +342,14 @@ internal class ExpressionListener(val functions: FunctionExtensions = FunctionEx
|
||||
|
||||
IDType.FUNCTION5 -> {
|
||||
val function: (DoubleArray) -> Double =
|
||||
when (val candidate = node.text) {
|
||||
when (name) {
|
||||
"min" -> { x -> x.minOrNull()!! }
|
||||
"max" -> { x -> x.maxOrNull()!! }
|
||||
"sum" -> { x -> x.sum() }
|
||||
"map" -> { x -> map(x[0], x[1], x[2], x[3], x[4]) }
|
||||
else -> functions.functions5[candidate]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2], x[3], x[4]) } }
|
||||
else -> functions.functions5[name]?.let { { x: DoubleArray -> it.invoke(x[0], x[1], x[2], x[3], x[4]) } }
|
||||
?: errorValue(
|
||||
"unresolved function: '${candidate}(x0, x1, x2, x3, x4)'"
|
||||
"unresolved function: '${name}(x0, x1, x2, x3, x4)'"
|
||||
) { _ -> error("this is the error function") }
|
||||
}
|
||||
functionStack.push(function)
|
||||
@@ -374,7 +383,7 @@ fun evaluateExpression(
|
||||
}
|
||||
})
|
||||
|
||||
val root = parser.miniCalcFile()
|
||||
val root = parser.keyLangFile()
|
||||
val listener = ExpressionListener(functions)
|
||||
listener.variables.putAll(variables)
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user