papercraft icon indicating copy to clipboard operation
papercraft copied to clipboard

Automatic compilation

Open noteflakes opened this issue 4 months ago • 1 comments

Compilation right now works only partially, and is based on Ruby's internal AST representation. This does have the advantage of being able to compile dynamically generated templates, but is not a very friendly API, nor is it well documented or guaranteed to be stable over the long run.

Over the long run, the Ruby ecosystem will come together around Prism, and that's why I'm working on Sirop, a complementary gem that builds on top of Prism.

So the idea is to build a compiler on top of Sirop (a big part of the functionality is already there in the test DSL compiler).

This issue is for tracking progress on this undertaking.

Still to be implemented:

  • [x] Support for dashed attributes (https://github.com/digital-fabric/papercraft?tab=readme-ov-file#tag-and-attribute-formatting)
  • [x] Support for text
  • [x] Support for emit with text
  • [x] Support for emit with proc
  • [x] Support for emit with template
  • [x] Support for emit with proc/template (with additional arguments)
  • [ ] Support for emit_yield
  • [ ] Support for defer
  • [ ] Support for emit_markdown
  • [ ] Support for various HTML-specific methods (https://github.com/digital-fabric/papercraft?tab=readme-ov-file#html-templates)
  • [ ] Support for inline method definitions
  • [ ] Support for def_tag
  • [ ] Correctly handle _for for direct iteration (https://github.com/digital-fabric/papercraft?tab=readme-ov-file#direct-iteration)
  • [ ] Correctly handle template parameters (https://github.com/digital-fabric/papercraft?tab=readme-ov-file#template-parameters)
  • [ ] Compilation of procs stored as constants (and used as method calls) (https://github.com/digital-fabric/papercraft?tab=readme-ov-file#template-composition)

JIT compilation

We want compilation to be automatic and transparent. Say, on the second call to #render for a specific template, the template is automatically compiled and the compiled code is memoized. From then on, rendering will actually use the compiled proc.

For naked procs, we can memoize the compiled version in some ivar under Papercraft, e.g. Papercraft.__compiled_proc_cache__.

Next steps

  • Create a bunch of fixtures in Papercraft test directory. We can put in basically all existing tests, plus from the examples directory.
  • Implement a harness that takes a fixture, runs it normally, then compiles the fixture, then runs the compiled version and then compare the two results, which should be identical.
  • Reimplement compiler using Sirop.

noteflakes avatar Feb 28 '24 10:02 noteflakes