Lean2Js.Roundtrip
That the reader gives the printer's input back #
That the reader in Parse gives the printer's input back.
Js.Expr.render is not injective, so the statement is about the trees the compiler actually builds.
Renderable names the three places two trees share a text — a callee that the reader dispatches on, a
unary operator that is not ! or -, a name that is not an identifier — plus a doc comment that closes
itself early.
The fuel is bounded by the length of the text being read, so the top level passes the text's own length and no fuel caveat survives.
What the reader needs of a tree #
Lean2Js.Parse.dispatchNames
sourceThe names parseNamed gives a meaning of their own. An identifier or a callee spelled one of these
reads back as the form the reader has a constructor for.
Equations
Instances For
Used by
Lean2Js.Parse.okCallee
sourceEquations
Instances For
Used by
Lean2Js.Parse.okOp
sourceEquations
- Lean2Js.Parse.okOp s = match s.toList with | [] => false | c :: cs => (c :: cs).all Lean2Js.Parse.isOpChar
Instances For
Used by
Lean2Js.Parse.RenderableExpr
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.num i) = true
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.bigLit i) = true
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.str s) = true
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.bool b) = true
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.ident name) = Lean2Js.Parse.okCallee name
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.unary op e) = ((op == "!" || op == "-") && Lean2Js.Parse.RenderableExpr e)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.binary op lhs rhs) = (Lean2Js.Parse.okOp op && Lean2Js.Parse.RenderableExpr lhs && Lean2Js.Parse.RenderableExpr rhs)
- Lean2Js.Parse.RenderableExpr (c.cond t e) = (Lean2Js.Parse.RenderableExpr c && Lean2Js.Parse.RenderableExpr t && Lean2Js.Parse.RenderableExpr e)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.call callee args) = (Lean2Js.Parse.okCallee callee && Lean2Js.Parse.RenderableList args)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.arrowCall params body args) = (params.all Lean2Js.okName && Lean2Js.Parse.RenderableExpr body && Lean2Js.Parse.RenderableList args)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.objLit fields) = Lean2Js.Parse.RenderablePairs fields
- Lean2Js.Parse.RenderableExpr (obj.member field) = (Lean2Js.Parse.RenderableExpr obj && Lean2Js.okName field)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.arrayLit items) = Lean2Js.Parse.RenderableList items
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.dictLit entries) = Lean2Js.Parse.RenderablePairs entries
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.check d e) = Lean2Js.Parse.RenderableExpr e
- Lean2Js.Parse.RenderableExpr (arr.mapJs binder body) = (Lean2Js.Parse.RenderableExpr arr && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
- Lean2Js.Parse.RenderableExpr (arr.filterJs binder body) = (Lean2Js.Parse.RenderableExpr arr && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
- Lean2Js.Parse.RenderableExpr (arr.sortByJs binder body) = (Lean2Js.Parse.RenderableExpr arr && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
- Lean2Js.Parse.RenderableExpr (arr.findJs binder body) = (Lean2Js.Parse.RenderableExpr arr && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.quantJs op arr binder body) = (Lean2Js.Parse.RenderableExpr arr && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
- Lean2Js.Parse.RenderableExpr (Lean2Js.Js.Expr.out d e) = Lean2Js.Parse.RenderableExpr e
- Lean2Js.Parse.RenderableExpr (scrut.foldJs key spec binder body) = (Lean2Js.Parse.RenderableExpr scrut && Lean2Js.okName binder && Lean2Js.Parse.RenderableExpr body)
Instances For
Used by
Lean2Js.Parse.RenderableList
sourceEquations
Instances For
Used by
Lean2Js.Parse.RenderablePairs
sourceEquations
Instances For
Used by
The printer's equations #
Expr.render recurses on a measure, so its equations do not unfold on their own.
Lean2Js.Parse.render_num
sourceUsed by
Lean2Js.Parse.render_bigLit
sourceUsed by
Lean2Js.Parse.render_str
sourceUsed by
Lean2Js.Parse.render_bool
sourceUsed by
Lean2Js.Parse.render_ident
sourceUsed by
Lean2Js.Parse.render_unary
sourceUsed by
Lean2Js.Parse.render_binary
sourceUsed by
Lean2Js.Parse.render_cond
sourceUsed by
Lean2Js.Parse.render_call
sourceUsed by
Lean2Js.Parse.render_arrowCall
sourceUsed by
Lean2Js.Parse.render_objLit
sourceUsed by
Lean2Js.Parse.render_member
sourceUsed by
Lean2Js.Parse.render_arrayLit
sourceUsed by
Lean2Js.Parse.render_dictLit
sourceUsed by
Lean2Js.Parse.render_check
sourceUsed by
Lean2Js.Parse.render_out
sourceUsed by
Lean2Js.Parse.render_mapJs
sourceUsed by
Lean2Js.Parse.render_filterJs
sourceUsed by
Lean2Js.Parse.render_sortByJs
sourceUsed by
Lean2Js.Parse.render_findJs
sourceUsed by
Lean2Js.Parse.render_quantJs
sourceUsed by
Lean2Js.Parse.render_reduceJs
sourceUsed by
Lean2Js.Parse.render_foldJs
sourceUsed by
Separators #
The reader is greedy over names and numerals, it turns a name into a call when a ( follows, and after a
) it looks for a ., so a rendering has to be followed by a character that does none of those.
Lean2Js.Parse.Sep
sourceEquations
Instances For
Used by
Lean2Js.Parse.Sep.nil
sourceUsed by
Lean2Js.Parse.Sep.cons
sourceUsed by
Lean2Js.Parse.Sep.toIdent
sourceUsed by
Lean2Js.Parse.Sep.toDigit
sourceUsed by
Lean2Js.Parse.digit_isIdentPart
sourceUsed by
Lean2Js.Parse.natDigits_all_identPart
sourceUsed by
Names #
Lean2Js.Parse.okName_ne_nil
sourceUsed by
Lean2Js.Parse.okName_all
sourceUsed by
Lean2Js.Parse.okName_start
sourceUsed by
Lean2Js.Parse.okCallee_name
sourceUsed by
Lean2Js.Parse.okCallee_not_dispatch
sourceUsed by
Where an identifier list stops #
parseParen decides between an arrow call and the other parenthesised forms by reading ahead for
( names ) => (. What makes that decision sound is that the lookahead fails on every rendering: the
identifier list stops at the first character a name cannot contain, and in a rendering that character is
never the ) the arrow head wants.
Lean2Js.Parse.expect_arrow_ne
sourceUsed by
Lean2Js.Parse.AfterHead
sourceInstances For
Used by
Lean2Js.Parse.AfterHead.close
sourceUsed by
Lean2Js.Parse.AfterHead.cons
sourceUsed by
Lean2Js.Parse.parseIdentList_stuck
sourceUsed by
Lean2Js.Parse.parseIdentList_last
sourceUsed by
Lean2Js.Parse.identList_head
sourceThe rendering opens with a character no name can contain, so the list is empty and the lookahead stops on that character.
Used by
Lean2Js.Parse.identList_name_head
sourceThe rendering opens with a name and then a character no name can contain.
Used by
Lean2Js.Parse.identList_name_all
sourceThe rendering is a name and nothing else, so the lookahead stops where the rendering ends.
Used by
The printer's output as characters #
Everything below reads the rendering one character at a time, so each printer branch is restated as the list it writes, with the literal chunks spelled out and the recursive parts left as they are.
Lean2Js.Parse.render_num_toList
sourceUsed by
Lean2Js.Parse.render_bigLit_toList
sourceUsed by
Lean2Js.Parse.render_str_toList
sourceUsed by
Lean2Js.Parse.render_bool_true_toList
sourceUsed by
Lean2Js.Parse.render_bool_false_toList
sourceUsed by
Lean2Js.Parse.render_ident_toList
sourceUsed by
Lean2Js.Parse.render_unary_toList
sourceUsed by
Lean2Js.Parse.render_binary_toList
sourceUsed by
Lean2Js.Parse.render_cond_toList
sourceUsed by
Lean2Js.Parse.render_call_toList
sourceUsed by
Lean2Js.Parse.render_arrowCall_toList
sourceUsed by
Lean2Js.Parse.render_objLit_toList
sourceUsed by
Lean2Js.Parse.render_member_toList
sourceUsed by
Lean2Js.Parse.render_arrayLit_toList
sourceUsed by
Lean2Js.Parse.render_dictLit_toList
sourceUsed by
Lean2Js.Parse.render_check_toList
sourceUsed by
Lean2Js.Parse.render_out_toList
sourceUsed by
Lean2Js.Parse.render_mapJs_toList
sourceUsed by
Lean2Js.Parse.render_sortByJs_toList
sourceUsed by
Lean2Js.Parse.render_filterJs_toList
sourceUsed by
Lean2Js.Parse.render_findJs_toList
sourceUsed by
Lean2Js.Parse.render_allJs_toList
sourceUsed by
Lean2Js.Parse.render_anyJs_toList
sourceUsed by
Lean2Js.Parse.render_reduceJs_toList
sourceUsed by
Lean2Js.Parse.render_foldJs_toList
sourceUsed by
Lean2Js.Parse.renderList_nil_toList
sourceUsed by
Lean2Js.Parse.renderList_one_toList
sourceUsed by
Lean2Js.Parse.renderList_cons_toList
sourceUsed by
Lean2Js.Parse.renderFields_nil_toList
sourceUsed by
Lean2Js.Parse.renderFields_one_toList
sourceUsed by
Lean2Js.Parse.renderFields_cons_toList
sourceUsed by
Lean2Js.Parse.renderEntries_nil_toList
sourceUsed by
Lean2Js.Parse.renderEntries_one_toList
sourceUsed by
Lean2Js.Parse.renderEntries_cons_toList
sourceUsed by
The lookahead fails on every rendering but an arrow call #
Lean2Js.Parse.renderInt_ofNat_toList
sourceUsed by
Lean2Js.Parse.renderInt_negSucc_toList
sourceUsed by
Lean2Js.Parse.parseIdentList_render
sourceUsed by
Lean2Js.Parse.arrowHead_ne
sourceUsed by
Lean2Js.Parse.arrowHead_stuck
sourceUsed by
Lean2Js.Parse.arrowHead_head
sourceUsed by
Lean2Js.Parse.parseArrowHead_render
sourceThe lookahead that picks an arrow call fails on every other parenthesised form: member closes with
)., and binary and cond put a space where the arrow wants ).
Used by
Reaching the reader's branches #
The reader picks its branch on one character, so each case first has to say which character the rendering opens with.
Lean2Js.Parse.identStart_not_digit
sourceUsed by
Lean2Js.Parse.head_digit_of_natDigits
sourceUsed by
Lean2Js.Parse.render_head
sourceUsed by
Lean2Js.Parse.render_head_ne
sourceNo rendering opens with a character that closes a list, so a reader looking for the end of one never mistakes an element for it.
Used by
Lean2Js.Parse.parseExpr_numHead
sourceUsed by
Lean2Js.Parse.parseExpr_int
sourceUsed by
Lean2Js.Parse.parseExpr_start
sourceUsed by
Lean2Js.Parse.parseNumeral_num
sourceUsed by
Lean2Js.Parse.parseNumeral_bigLit
sourceUsed by
Lean2Js.Parse.parseNamed_other
sourceUsed by
Lean2Js.Parse.render_head_num
sourceOnly a numeral is written starting with a digit or a minus sign, which is what lets parseParen
decide by the character after ( whether a numeral reader should take the sign.
Used by
Lean2Js.Parse.descSize_le
sourceThe descriptor reader's budget, read off the text it is handed rather than off the descriptor.
Used by
Lean2Js.Parse.foldFieldsSize_le
sourceThe spec reader's budget, read off the text the same way the descriptor's is.
Used by
Lean2Js.Parse.specSize_le
sourceUsed by
Lean2Js.Parse.parseInt_neg_ofNat
sourceUsed by
Lean2Js.Parse.parseExprList_step
sourceUsed by
Name lists and operators #
Lean2Js.Parse.renderNames_nil_toList
sourceUsed by
Lean2Js.Parse.renderNames_one_toList
sourceUsed by
Lean2Js.Parse.renderNames_cons_toList
sourceUsed by
Lean2Js.Parse.parseIdent_none
sourceUsed by
Lean2Js.Parse.parseIdentList_names
sourceUsed by
Lean2Js.Parse.renderNames_length
sourceUsed by
Lean2Js.Parse.okOp_ne_nil
sourceUsed by
Lean2Js.Parse.okOp_all
sourceUsed by
Lean2Js.Parse.okOp_head
sourceUsed by
Lean2Js.Parse.parseOpChars_append
sourceUsed by
Lean2Js.Parse.parseOp_append
sourceUsed by
Lean2Js.Parse.exists_cons_of_ne_nil
sourceUsed by
Lean2Js.Parse.parseExpr_name
sourceUsed by
Lean2Js.Parse.expect_open_none
sourceUsed by
Reaching the parenthesised branches #
Lean2Js.Parse.parseParen_bang
sourceUsed by
Lean2Js.Parse.parseParen_minusDigit
sourceUsed by
Lean2Js.Parse.parseParen_minusOther
sourceUsed by
Lean2Js.Parse.parseParen_fallback
sourceUsed by
Lean2Js.Parse.parseAfterHead_member
sourceUsed by
Lean2Js.Parse.parseAfterHead_negate
sourceUsed by
Lean2Js.Parse.parseAfterHead_negate_nil
sourceUsed by
Lean2Js.Parse.parseAfterHead_neg
sourceUsed by
Lean2Js.Parse.parseAfterHead_binary
sourceUsed by
The roundtrip on expressions #
Each case reads back exactly what the matching printer branch wrote. The fuel is bounded by the length of the text, which every recursive call shortens by at least the delimiters around it.
Lean2Js.Parse.parseExpr_append
sourceUsed by
Lean2Js.Parse.parseParen_head
sourceUsed by
Lean2Js.Parse.parseLambdaCall_append
sourceUsed by
Lean2Js.Parse.parseExprList_append
sourceUsed by
Lean2Js.Parse.parseObjFields_append
sourceUsed by
Lean2Js.Parse.parseEntries_append
sourceUsed by
Statements, functions and the module #
Lean2Js.Parse.RenderableStmt
sourceEquations
Instances For
Used by
Lean2Js.Parse.noCommentClose
sourceA doc comment goes into /** */ unescaped, so it must not close the comment itself.
Equations
- Lean2Js.Parse.noCommentClose [] = true
- Lean2Js.Parse.noCommentClose [head] = true
- Lean2Js.Parse.noCommentClose [head, head_1] = true
- Lean2Js.Parse.noCommentClose [head, head_1, head_2] = true
- Lean2Js.Parse.noCommentClose (a :: b :: c :: d :: rest) = (!(' ' == a && '*' == b && '/' == c && '\n' == d) && Lean2Js.Parse.noCommentClose (b :: c :: d :: rest))
Instances For
Used by
Lean2Js.Parse.RenderableFunc
sourceEquations
Instances For
Used by
Lean2Js.Parse.RenderableModule
sourceEquations
Instances For
Used by
Lean2Js.Parse.render_const_toList
sourceUsed by
Lean2Js.Parse.render_ret_toList
sourceUsed by
Lean2Js.Parse.render_stmt_head
sourceUsed by
Lean2Js.Parse.stmtAll_nil_toList
sourceUsed by
Lean2Js.Parse.stmtAll_one_toList
sourceUsed by
Lean2Js.Parse.stmtAll_cons_toList
sourceUsed by
Lean2Js.Parse.funcAll_nil_toList
sourceUsed by
Lean2Js.Parse.funcAll_cons_toList
sourceUsed by
Lean2Js.Parse.render_func_toList
sourceUsed by
Lean2Js.Parse.render_func_split
sourceUsed by
Lean2Js.Parse.render_func_length
sourceUsed by
Reading a doc comment back #
Lean2Js.Parse.takeUntil_close
sourceUsed by
Lean2Js.Parse.noCommentClose_tail
sourceUsed by
Lean2Js.Parse.takeUntil_doc
sourceUsed by
Lean2Js.Parse.expect_docOpen
sourceUsed by
Lean2Js.Parse.expect_docClose
sourceUsed by
Lean2Js.Parse.takeUntil_doc'
sourceThe shape a doc comment takes inside a rendering, where the closing marker is spelled out.
Used by
The roundtrip on statements, functions and the module #
Lean2Js.Parse.parseStmt_append
sourceUsed by
Lean2Js.Parse.stmtAll_head
sourceUsed by
Lean2Js.Parse.parseStmts_step
sourceUsed by
Lean2Js.Parse.parseStmts_append
sourceUsed by
Lean2Js.Parse.parseFunc_append
sourceUsed by
Lean2Js.Parse.parseFuncs_step
sourceUsed by
Lean2Js.Parse.expect_self
sourceUsed by
Lean2Js.Parse.render_func_head
sourceUsed by
Lean2Js.Parse.parseFuncs_append
sourceUsed by
Lean2Js.Parse.parseModule_of
sourceThe prelude is a long literal, so it is kept opaque here: nothing about the roundtrip depends on what it says, only on its being the same text on both sides and on its leaving the reader more fuel than the functions after it need.
Used by
Lean2Js.Parse.preamble_length
sourceThe prelude opens with a comment, so it leaves the reader more fuel than the functions after it need.
Used by
Lean2Js.Parse.parseModule_render
sourceThe file the compiler writes reads back as the module it was compiled from.