Skip to content

Refactoring of PascaLIGO and JsLIGO

Christian Rinderknecht requested to merge rinderknecht@transpilation into dev

Motivation and Context

We want to transpile PascaLIGO contracts into JsLIGO contracts, to help the community port their code base. This MR is a first step in that direction.


We refactored the CSTs of PascaLIGO and JsLIGO so that transpilation is as smooth as possible. Breaking changes in the grammar of JsLIGO had to be made also (like multiple assignments and parenthesised statements) to fix issues that popped up when trying syntactic transpilation, which is described as follows.

First, on the self-passes on lexical units,

  1. we filter the comments that start their line and we tokenise the comments (instead of remaining markup and be normally discarded just before applying the self-passes on tokens). Others are discarded.

Second, on the self-passes on tokens,

  1. Comments are transformed into a [@comment "..."] attribute, except comments followed by a preprocessing directive, which are then embedded into them. All others are discarded. This is achieved by a right-to-left self-pass, so we match first against the keywords, directives and other tokens. (In theory, all tokens can withhold attributes, thanks to the [Wrap.t] type used for their definitions, and whose field [attributes] is not used yet, but it would be too complicated to pretty-print the JsLIGO CST if attributes potentially can occur everywhere.)

  2. We embed directives into the token that follows. There is always one because we start right to left from EOF. Those can be "EOF", "type", "const", "recursive", "function", "module" or an attribute [@...]. Preprocessing directives are kept in place, but #include and #import have the extension of their file names changed to .jsligo.

  3. We write the transformation from the PascaLIGO CST to the JsLIGO CST, while taking care, in particular, that PascaLIGO loops are transformed into while and for loops in JsLIGO. The CST of JsLIGO may have to be rewritten to hold more attributes (I did not get to refactor it.) We take care of preserving any directive embedded in the keywords "type", "const", "recursive", "function" and "module", which are the only tokens that can start a top-level declaration in PascaLIGO (remember that directives can only occur between top-level declarations).

  4. The pretty-printer for JsLIGO should be modified to process embedded directives in attributes, "EOF" and keywords "let", "const", "namespace", "import" and "type".

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Performance improvement (non-breaking change that improves performance)
  • None (change with no changelog)



  • Changes follow the existing coding style (use dune @fmt to check).
  • Tests for the changes have been added (for bug fixes / feature).
  • Documentation has been updated.
  • Changelog description has been added (if appropriate).
  • Start titles under ## Changelog section with #### (if appropriate).
  • There is no image or uploaded file in changelog
  • Examples in changed behaviour have been added to the changelog (for breaking change / feature).
Edited by Christian Rinderknecht

Merge request reports