If you're sure you want to get the raw program source and deal with it manually, you can use the method `get-definitions-text <https://docs.racket-lang.org/tools/drracket_unit.html#(meth._(((lib._drracket%2Ftool-lib..rkt)._drracket~3aunit~3aframe~3c~25~3e)._get-definitions-text))>` on the DrRacket frame given as an argument to your button's callback function. This will give you the editor object for the definitions window. You can then use a method like `get-flattened-text <https://docs.racket-lang.org/gui/editor___.html#(meth._(((lib._mred%2Fmain..rkt)._editor~3c~25~3e)._get-flattened-text))>` to get the source as a sting or (probably better) the function ` open-input-test-editor <https://docs.racket-lang.org/gui/Editor_Functions.html#(def._((lib._mred%2Fmain..rkt)._open-input-text-editor))>` to get an input port directly. Before evaluating it, you need to convert it to an s-expression with `read` or, better, a syntax object with `read-syntax`. In either case, you will want to use ` with-module-reading-parameterization <https://docs.racket-lang.org/syntax/module-helpers.html#(def._((lib._syntax%2Fmodread..rkt)._with-module-reading-parameterization))>` to set the reading parameters properly.
However, if I understand your requirements correctly, I still think expanding to a "main" submodule would be the best way to go. To be concrete, I'll use the example I gave before of a partially-expanded version of your program, but with `shape` renamed to `result` to match your description: (module example hypothetical-lanugage (#%plain-module-begin (provide result) (define result (hypothetical-code)) (module* main racket/base (require (submod "..") hypothetical-lanugage/private/render) (render result)))) On Wed, Jun 26, 2019 at 12:05 PM Thomas Dickerson < thomas_dicker...@alumni.brown.edu> wrote: > 1. The language is a language for describing parametric 3D models, not for > rendering, and the final result of being evaluated by Racket is a module > containing a provided result value, which is a pointer to a C++ object > which represents some a low level program evaluated by our C++ runtime to > produce a triangle mesh. Hopefully it's clear how this aspect of the expansion works: ` (hypothetical-code)` evaluates to your foreign C++ representation just as it would in your current way of thinking about these programs. 2. Our C++ applications obtain the result value from a DSL program by > calling scheme_dynamic_require in the inner loop of a Racket interpreter > we've stuffed into a coroutine > <https://github.com/Geopipe/CxxBidirectionalCoroutines/>. Again, this part works just fine. In particular, because of the way Racket's submodules <https://docs.racket-lang.org/reference/eval-model.html#%28part._submodules%29> work, the code in the "main" submodule *does not* run when you instantiate the parent module, whether via `scheme_dynamic_require`, `dynamic-require`, `require`, or some other way: the compiled form of the submodule need not even be loaded into memory. So you can use rendering code in the main submodule without creating a dependency for your main application. 3. When the toolbar button is pushed in DrRacket we want to evaluate the > program in a fresh namespace, (dynamic-require ''module-name 'result), > and then pass that result value into a C++ FFI function that will handle > the C++ side of evaluation and doing the actual OpenGL calls to visualize > it in the editor. This should have similar behavior to the run button from > an evaluation standpoint, but after evaluating the program, enter a render > loop until, e.g. the button is pushed again to stop rendering. Here, the > DrRacket plugin is responsible for creating the OpenGL context, which could > be in a separate window, but as Kshitij said it would be ideal if we could > figure out how to add a pane below the REPL. > This is where I think using a submodule will be helpful. When you press the "Run" button in DrRacket, the "main" submodule is run for effect before starting the REPL. (Command-line `racket` will do similarly depending on the flags.) In the example expansion, `(render result)` would pass the value described by your DSL program to your rendering function and whatever FFI calls are needed. It could certainly open a new GUI window, and it could also return a value that renders as an embedded widget (snip) in the interactions pane. (See the plot library for an example.) I haven't looked at the DrRacket extension APIs enough to be sure whether you could open a new pane in the DrRacket window, but it certainly seems possible. Using a "main" submodule should let you take advantage of DrRacket's programming-languages-as-operating-systems capabilities for managing the programs it runs with minimal additional work. DrRacket would take care of destroying your rendering context when you click "Run" again after changing your program, it could enforce memory limits, and its "Stop"/"Kill" button could terminate misbehaved rendering code. You could re-create all of these capabilities yourself, but that's a fair amount of work, and I'm not seeing a compelling reason for this to be an extralinguistic tool. -Philip -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAH3z3gZ2DccaWO-qZ3rtzPXbRCpd%3DKp2dswug6orB-DG0VRXjQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.