1

I am creating a GUI using Scala which should play a signal dependent on the algorithm but into the textField, eg. sin(2*Pi*400*t). The playing function works perfectly, however the issue is the input for the GUI. The textField takes the function and converts it to a string, now I was wondering is there a simple way to convert the string back into a function. I was considering matching the input to various valid functions, however I don't want to restrict the possible functions, as I want the user to be more create

I am still relatively new to Scala, hopefully one of you have a better idea. Here is the code I have so far, its a basic setup focusing on functionality.

object PlayApp extends SimpleGUIApplication {
  def top = new MainFrame {
    title = "Play Function App"
    val label = new Label("Type in function to be played")

    object Function extends TextField ( columns = 10)
    val label2 = new Label("Type in length of time to play")
    object Time extends TextField { columns = 10}  
    val button = new Button("Play")

    contents = new BoxPanel(Orientation.Vertical) {
      contents += label
      contents += Function
      contents += label2
      contents += Time
      contents += button
      border = Swing.EmptyBorder(50, 50, 20, 50)
    }

    var f = "sin(t)"
    var x = 0

    listenTo(Function, Time, button) 
    reactions += {
      case EditDone(Function) =>
        f = Function.text.toString
      case EditDone(Time)     =>
        x = Time.text.toInt
      case ButtonClicked(b)   =>
        play(t => f.toDouble,0,x)
    }
  }
}
3
  • What is the permitted grammar of the input? Check out parser combinators. The GUI aspect of this question seems to be irrelevant & may put people off reading it. Commented Dec 20, 2012 at 15:00
  • Agree with Luigi: I expected a lonely unloved Swing question. Also agree that depending on what you mean by "creative", parse the expr yourself. Commented Dec 20, 2012 at 18:07
  • The input needs to be a mathematical expression, most likely a combination of sines and cosines at different frequencies. Thanks for the tip, I'll remove the GUI comments. By creative I meant that I didn't want to restrict the number or combination of sine and cosine, or limit other possible combinations by putting in cases for each option. Commented Dec 20, 2012 at 22:53

1 Answer 1

1

You want to compile the line of code that the user enters, with some useful preamble.

I haven't done this so I don't have a snippet handy (but try searching), but you can embed the REPL, have it compile the line of code, and then extract the result.

Here is a snippet that uses ILoop to get some output, but you want to use IMain to get a result with the result class that wraps the user function.

import scala.tools.nsc.interpreter.ILoop
import java.io.StringReader
import java.io.StringWriter
import java.io.PrintWriter
import java.io.BufferedReader
import scala.tools.nsc.Settings

object FuncRunner extends App {

  val line = "sin(2 * Pi * 400 * t)"

  val lines = """import scala.math._
    |var t = 1""".stripMargin

  val in = new StringReader(lines + "\n" + line + "\nval f = (t: Int) => " + line)
  val out = new StringWriter

  val settings = new Settings

  val looper = new ILoop(new BufferedReader(in), new PrintWriter(out))
  val res = looper process settings
  Console println s"[$res] $out"
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.