Layout Guidelines

Stratego -- Strategies for Program Transformation
Good layout is important for the readability and hence maintainability of programs. This holds for any programming language. Stratego aims at not only providing a language for programming program transformations, but also doing so in an understandable way. Refactoring is an important tool to create readable specifications, but good layout is a good starting point.

Layout is not significant for the semantics. Stratego does not use the offside rule. This means that you can be liberal with placing newlines.

Of course, layout is determined by taste, but experience suggests several conventions that lead to readable specifications. This page discusses some conventions. Actual situations may call for other decisions.

Principles

Specifications should be layed out such that they

  • can be printed on standard paper
  • fit on a 80 character display (editor, browser)

Rules

Short rules are better than long ones.

Put a short rule on a single line:

   AZ : Plus(Int(0), x) -> x

Split a longer rule into a line with the label and a line with the left-hand side and right-hand side:

  TrCx : 
    Cx(e, t, f) -> CJUMP(NE, e, CONST(0), t, f)

Indent the label of a rule with two spaces and the left-hand side with another two. More is a waste of space.

Putting the label on a line by itself makes it stand out, making it easier to locate. Also it makes the appearance of the text more regular if all left-hand sides start at the same indentation.

Split long rule over multiple lines

 TrExp : 
    If(e1, e2, e3) ->
    ESEQ([Cx(e1, t, f),
          LABEL(t),
          MOVE(TEMP(tmp), e2),
          JUMP(NAME(done), [done]),
          LABEL(f),
          MOVE(TEMP(tmp), e3),
          LABEL(done)],
         TEMP(tmp))
    where new => t; new => f; new => done; new => tmp

Strategy Definitions

For strategies similar guidelines apply.

Put a short definition on a single line.

For a longer definition put the body on the line after the name operator name

  tr-stm(s, e) =
    MOVE(e,e) + EXP(e) + JUMP(e,id) + CJUMP(id,e,e,id,id) +
    SEQ(s,s) + SEQ(list(s)) + NUL + LABEL(id) + LET(id, e)

Strategy Expressions

Organize a long sequential composition (pipeline of transformations) vertically

  canonicalize-body =
    !SEQ(<id>);
    simplify-ir;
    linearize;
    listify;
    ?SEQ(<id>);
    commute-args;
    basic-blocks;
    trace-schedule;
    clean-up-traces

Sometimes the structure can be clarified by prefixing the semicolon separator:

  canonicalize-body =
    !SEQ(<id>)
  ; simplify-ir
  ; linearize
  ; listify
  ; ?SEQ(<id>)
  ; commute-args
  ; basic-blocks
  ; trace-schedule
  ; clean-up-traces

-- EelcoVisser - 28 Apr 2002


StrategoGlossary