<<>> <> <> <<>> Crank Dealer June 24, 1987 Crank and Grinder f Motivation Want to translate the Imager into Common Lisp Cedar => Common Lisp hand translation tedious f Crank reads sources, produces decorated trees Written in Cedar Uses the Interpreter's parser to build ASTs Does (imperfect) type analysis Writes Lisp-readable decorated trees f Grinder Written in Lisp Reads trees produced by Crank Writes (imperfect) Common Lisp Example Source DIRECTORY IO USING [STREAM, ROPE, ROS, PutChar, RopeFromROS], Rope; CrankExampleImpl: CEDAR PROGRAM IMPORTS IO, Rope = BEGIN OPEN IO; Reverse: PROC [a: ROPE] RETURNS [ROPE] = { s: STREAM = ROS[]; FOR i: INT DECREASING IN [0..Rope.Size[a]) DO s.PutChar[a.Fetch[i]] ENDLOOP; RETURN [RopeFromROS[s]] }; END. Example Abstract Syntax Tree (:decl (:CONSTANT :TRUE) (:id () "Reverse") (:procTC (:SAFE :TRUE) (:decl () (:id () "a") (:id () "ROPE") NIL) (:decl () NIL (:id () "ROPE") NIL)) (:body (:CHECKING :CHECKED) NIL (:decl (:CONSTANT :TRUE) (:id () "s") (:id () "STREAM") (:apply () (:id () "ROS") NIL)) (:list () (:do () (:downthru () (:decl () (:id () "i") (:id () "INT") (:cast () NIL)) (:intCO () (:mwconst () (:literal () 0)) (:apply () (:dot () (:id () "Rope") (:id () "Size")) (:id () "a"))) NIL) NIL NIL (:apply () (:dot () (:id () "s") (:id () "PutChar")) (:apply () (:dot () (:id () "a") (:id () "Fetch")) (:id () "i"))) NIL NIL) (:return () (:apply () (:id () "RopeFromROS") (:id () "s")))) NIL)) Example Decorated Tree (:decl (:TYPECLASS :PROC :CONSTANT :TRUE) (:id (:QUAL "CrankExampleImpl") "Reverse") (:procTC (:SAFE :TRUE) (:decl (:TYPECLASS :REF) (:id () "a") (:id (:QUAL "IO") "ROPE") NIL) (:decl (:TYPECLASS :REF) NIL (:id (:QUAL "IO") "ROPE") NIL)) (:body (:CHECKING :CHECKED) NIL (:decl (:TYPECLASS :REF :CONSTANT :TRUE) (:id () "s") (:id (:QUAL "IO") "STREAM") (:FUNCTIONAPPLY (:FIELDNAMES ("oldStream")) (:id (:QUAL "IO") "ROS") NIL)) (:list () (:do () . . . ) (:return () (:FUNCTIONAPPLY (:FIELDNAMES ("self" "close")) (:id (:QUAL "IO") "RopeFromROS") (:id () "s")))) NIL)) Example Decorated Tree (cont.) (:do () (:downthru () (:decl (:TYPECLASS :INT32) (:id () "i") (:id () "INT") (:cast () NIL)) (:intCO () (:mwconst () (:literal () 0)) (:FUNCTIONAPPLY (:FIELDNAMES ("base")) (:INTERFACESELECT (:SLOTNUMBER 15) (:id () "Rope") (:id (:QUAL "Rope") "Size")) (:id () "a"))) NIL) NIL NIL (:FUNCTIONAPPLY (:FIELDNAMES ("char")) (:FUNKYAPPLY (:FROMINTERFACE "IO") (:id () "s") (:id (:QUAL "IO") "PutChar")) (:FUNCTIONAPPLY (:FIELDNAMES ("index")) (:FUNKYAPPLY (:FROMINTERFACE "Rope") (:id () "a") (:id (:QUAL "Rope") "Fetch")) (:id () "i"))) NIL NIL) Data structures f Attributed Tree Like tree from interpreter parser, but with a place to add attributes for each name. f Context Stack of SymTab.Ref, keyed by identifier Entries consist (mainly) of type code and qualifier f Type table Hash table, keyed by integer type codes Entries describe the type, possibly in terms of other types Not canonicalized (2360 entries for the example) Type codes may be allocated before values are fully defined (to solve use-before-definition) f Static value table Not implemented Cranking Interfaces f The Crank always uses the source code never .bcd files or Abstract Machine calls f Caches (in memory) the result f Uses fairly simple search rules Local directory first, then version map f Has to get through nasty low-level interfaces [IO from [Cedar]IO>IO.mesa!5 [Ascii from [Cedar]Rope>Ascii.mesa!3 End Ascii ] [Atom from [Cedar]SafeStorage>Atom.mesa!3 [Rope from [Cedar]Rope>Rope.mesa!3 [Basics from [Cedar]MesaRuntime>Basics.mesa!6 [PrincOps from [Cedar]MesaRuntime>PrincOps.mesa!8 Error: Could not do this coercion Error: Could not do this coercion Error: Could not do this coercion "[Cedar]MesaRuntime>PrincOps.mesa!8|476" <> End PrincOps ] End Basics ] End Rope ] End Atom ] [BasicTime from [Cedar]BasicTime>BasicTime.mesa!4 End BasicTime ] End IO ] What else might it good for? (with more work) f Cleaning up Cedar programs removing nasty OPENs removing (or adding) "object" notation prettyprinting changing positional <=> keyword notation Checking for things the Compiler ignores PUBLIC things that are not exported use-before-initialization unused types, variables, procedures f Isosemantic editing Globally renaming field names, reordering parameters. f Crib sheet for Saffron implementation Easier to read than compiler code (?) However, not complete or correct