package feathercalculator import uk.co.nickthecoder.feather.core.* import java.lang.reflect.* import uk.co.nickthecoder.featureful.Scripts class FeatherCalculatorBehaviour : TextBehaviour( "Calc" ) { val clear = Action( "Clear", this:>clearAll ) .icon( "clean" ).description( "Clear : Ctrl+A then Ctrl+X" ) val eval = Action( "=", this:>eval ) .shortcut( FeatherCalculator.evalShortcut ) .description( "Evaluates the current line, or the selected block of text" ) override meth toolbar() = listOf( clear, spacer, eval, spacer ) init { append( "// Type an expression, then press Ctrl+ENTER to evaluate the current line.\n" ) append( "// Or select a block of text, then press Ctrl+ENTER to evaluate the block.\n" ) append( "// Variables are not remembered from one calculation to the next.\n" ) } meth clearAll() { clear() } meth eval() { val selection = selection() val toEvaluate = if ( selection.selection == "" ) { line(selection.fromRow) } else { selection.selection } val insertAtRow = selection.toRow val insertAtColumn = if (selection.selection == "") { line(selection.fromRow).size() } else { selection.toColumn } val config = Scripts.configuration() val compiler = FeatherCompiler( config ) val script = """ class Repl { func eval() = if (true) { ${toEvaluate} } else { null } } """ try { val results = compiler.compile( StringFeatherScript( script, "FROM_STRING" ) ) //println( "Results" ) val klass = results.classLoader.loadClass( "Repl" ) //println( "klass = $klass" ) val methods = klass.getMethods() for (method in methods) { if (method.name == "eval") { val result = method.invoke( null ) insertResult( result, insertAtRow, insertAtColumn ) } } } catch (e : Exception) { // Make this a status message println( "ERROR : $e" ) } } meth insertResult( result : Object, row : int, column : int ) { if (result == null) return val toInsert = if ( result is String ) { "\n\"$result\"\n" } else { "\n$result\n" } insert( row, column, toInsert ) } }