1

I need to program a C++ application which will basically work as a script interpreter, but with extremely basic and limited scripts.

The scripts will have a format like this:

processedA = doProcessA(source)
processedB = doProcessB(source)
destination = mix(processedA, processedB)

This denotes that in my C++ application this should happen (pseudocode):

while(source)
{
  processedA = doProcessA(*source);
  processedB = doProcessB(*source);
  *destination = mix(processedA, processedB);
  source++;
  destination++;
}

I am not sure what my option are for interpreting my language. Parsing it should be simple. Should I build an interpreter for my language, use llvm somehow to compile the flow (I'm not sure how), use a scripting language with c++ bindings or something else entirely?

I also need this to be reasonably fast (there isn't a limit but the faster the better).

  • What kind of application are you coding? – Basile Starynkevitch Feb 20 '15 at 9:02
  • A modular audio syntesizer/processor. It gets audio (or note data) and outputs audio data. – m fran Feb 20 '15 at 9:06
  • You should have edited your question to tell that. I remember having followed some talk about such things, so it has been done already (I forgot the details).... – Basile Starynkevitch Feb 20 '15 at 9:07
  • Now, I found it: mentioned Faust in my answer. – Basile Starynkevitch Feb 20 '15 at 9:12
6

There are many easily embeddable interpreters, notably GNU guile (and other Scheme variants, e.g. libscheme), Lua, Tcl, and even Python, OCaml, Perl (e.g. with parrot), NekoVM ...

Notice that if your software becomes popular enough, and if its (advanced) users are permitted to script it (i.e. if the scripting ability is documented and accessible or configurable), there are chances that some remote user would use a lot (and even abuse) the scripting facilities.

So the implicit premises in your question ("extremely basic scripts") will eventually become false. At some point the scripts won't be basic anymore!

This is why a scripting language has to be a good enough programming language (with a familiar look). Some weird user will eventually code many thousands lines in it. (BTW, this social issue is probably what Ousterhout, the famous author of Tcl, under-estimated: he originally designed the first Tcl for small scripts, but eventually some people wrote huge Tcl scripts, and then Tcl became a burden, because it purposely lacks some features that real programming languages should have... efficient data structures, modularity, etc.. Since then, Tcl improved significantly.).

If for some reason you cannot (or do no want) to embed an existing interpreter in your product and decided to write your own scripting interpreter (which means many months of work!), study several programming and scripting languages before designing your own (and document the languages that inspired you). Take care of having good internal representation(s) of the interpreted script (at least some AST, and preferably some bytecode). Read notably Scott's book: programming language pragmatics and Queinnec's book: Lisp in Small Pieces and study several Domain Specific Languages; read about garbage collection, and perhaps application checkpointing & persistence.

You may consider using JIT compilation techniques (e.g. with llvm, libjit, libgccjit, luajit ...) and you could also consider instead generating C (or C++) code on the fly and compiling it and dlopen-ing it as a plugin (as I did in MELT). Current machines are fast enough to make that compatible with a REPL interaction.

Notice that embedding some interpreter in your application has a huge architectural impact, and should probably change or deeply affect the design of your application, and how it would be used by advanced users.

Remember that a scripting language is almost always Turing-complete (unless you take special care in its design to avoid that). Never forget about the halting problem.

In the audio processing world, read about Faustine (by Karim Barkati, Haisheng Wang, and Pierre Jouvelot) and Faust (by Grame team in France).

  • Thank you. I will try jitting generated C++ code (if it gets too complicated I will instead embed lua). Just to be sure to understand correctly what that would look like: I would generate a function containing calls to the functions of my application as specified in the script, JIT compile that function and then call it? – m fran Feb 20 '15 at 9:21
  • 1
    Are you absolutely sure that you want to design your own language? Read first the papers on Faust, there are on the same domain as you are... (audio processing). Then read all the other references. You'll need months of work, and without a good technical background about scripting languages you'll make major design mistakes! You certainly cannot "JIT generated C++ code" – Basile Starynkevitch Feb 20 '15 at 9:23
  • 1
    Ok then, I will be reading more and probably just go with lua. – m fran Feb 20 '15 at 9:30
  • Probably you'll be more happy to use Faust... – Basile Starynkevitch Feb 20 '15 at 9:31
  • I'm also reading about that :) – m fran Feb 20 '15 at 9:33
3

Use an existing one -= don't bother reinventing the wheel when there are better wheels available, that are cheaper for you to use.

Lua seems to be the most common C/C++ embedded script interpreter. There are even youtube tutorials on embeddeding it into your C++ programs, or codeproject.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.