Changeset 824


Ignore:
Timestamp:
Aug 3, 2012 2:31:09 AM (12 years ago)
Author:
biz002
Message:

groupings support for pgf

groupings are a way to apply operations on token ranges for producing
or adjusting formatting directives

support for defining groupings and a grouping for 'group' operation

integrate grouping functionality

implement FmtSt FmtSt_cons(FmtSt st, Tseq s) and use it;
this abstracts away from having to deal with grouping related
things when unshifting input

workaround for current Rascal being unhappy with tseqGet;
'tseqGet' simplified and implemented using a 'switch' now;
seemed Rascal was not considering ADT overload alternatives
at all in some cases, and would not match say 'ListTseq'
based on dynamic type

internal pgf grouping types and functions

support for running rascal modules from command-line without
Magnolia compiler instance, using the exact same version of Rascal
as used with Magnolia

all test cases passing again

more test cases

fix import in test cases

Location:
trunk/magnolia-eclipse
Files:
3 added
7 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/magnolia-eclipse/src/org/magnolialang/pgf/Token.rsc

    r808 r824  
    2727  | Space(str s)
    2828  | Width(num w)
     29  | BeginGr(str s) // grouping start
     30  | EndGr(str s) // grouping end
    2931  | NilToken()
    3032  | Eof();
     
    6365  = NilTseq()
    6466  | ListTseq(list[value] lst)
    65   | RestTseq(list[value] lst, int i)
    6667  | LazyTseq(Tseq (value) f, value v);
    6768
     
    113114    case NilTseq(): ;
    114115    case ListTseq(l): lst += l;
    115     case RestTseq(l, i): lst += tail(l, size(l) - i);
    116116    case list[value] x: lst += x;
    117117    default: lst += [x];
     
    121121}
    122122
    123 public tuple[Token, Tseq] tseqGet(false) {
    124   return <eofTok, nilSeq>;
    125 }
    126 
    127 public tuple[Token, Tseq] tseqGet(Token t) {
    128   return <t, nilSeq>;
    129 }
    130 
    131 public tuple[Token, Tseq] tseqGet(str s) {
    132   return <Text(s), nilSeq>;
    133 }
    134 
    135 public tuple[Token, Tseq] tseqGet([]) {
    136   return <eofTok, nilSeq>;
    137 }
    138 
    139 public tuple[Token, Tseq] tseqGet([x]) {
    140   return tseqGet(x);
    141 }
    142 
    143 public tuple[Token, Tseq] tseqGet(list[value] lst, int i) {
     123/**
     124   With current Rascal this will not work if the choices are
     125   implemented using overloading. (See "TestToken.rsc".) Instead we
     126   use a 'switch', and specify the 'default' modifier to allow for
     127   extending through overloading.
     128 */
     129public default tuple[Token, Tseq] tseqGet(x) {
     130  switch (x) {
     131  case Token t: return <t, nilSeq>;
     132  case str s: return <Text(s), nilSeq>;
     133  case NilTseq(): return <eofTok, nilSeq>;
     134  case ListTseq(lst): return tseqGetList(lst);
     135  case list[value] lst: return tseqGetList(lst);
     136  case LazyTseq(_, _): return tseqGetLazy(x);
     137  case false: return <eofTok, nilSeq>;
     138  default:
     139    throw "attempt to tseqGet from unsupported value <x>";
     140  }
     141}
     142
     143public tuple[Token, Tseq] tseqGetList(list[value] lst) {
     144  int i = 0;
    144145  int len = size(lst);
    145146  while (i < len) {
     
    147148    <t, rest> = tseqGet(h);
    148149    if (t != Eof())
     150      // 2nd arg of 'tail' is number of elements to include
    149151      return <t, tseq(rest, ListTseq(tail(lst, size(lst) - (i+1))))>;
    150152    i += 1;
     
    153155}
    154156
    155 public tuple[Token, Tseq] tseqGet(list[value] lst) {
    156   return tseqGet(lst, 0);
    157 }
    158 
    159 public tuple[Token, Tseq] tseqGet(s : NilTseq()) {
    160   return <eofTok, s>;
    161 }
    162 
    163 public tuple[Token, Tseq] tseqGet(ListTseq(lst)) {
    164   return tseqGet(lst);
    165 }
    166 
    167 public tuple[Token, Tseq] tseqGet(RestTseq(lst, i)) {
    168   return tseqGet(lst, i);
    169 }
    170 
    171 public tuple[Token, Tseq] tseqGet(s : LazyTseq(_, _)) {
     157public tuple[Token, Tseq] tseqGetLazy(s : LazyTseq(_, _)) {
    172158  do {
    173159    Tseq (value) f = s.f;
     
    188174}
    189175
     176public bool isEmpty(Tseq ts) {
     177  <t, ts> = tseqGet(ts);
     178  return (t == Eof());
     179}
     180
    190181// deprecated (use emptyTseq)
    191182public Tseq newTokenStream() {
  • trunk/magnolia-eclipse/src/org/magnolialang/pgf/engines/FmtEngine.rsc

    r792 r824  
    6464
    6565// --------------------------------------------------
    66 // formatting algorithm
    67 // --------------------------------------------------
     66// groupings
     67// --------------------------------------------------
     68
     69/*
     70  The operations that must be defined for each grouping.
     71
     72  These Grouping functions:
     73
     74  begin:: creates fresh state for this grouping;
     75          returns state for GrpSt (any value)
     76
     77  put:: buffers a token within region
     78
     79  accept:: accepts a token from an inner grouping into this one
     80
     81  end:: ends this grouping
     82
     83  eof:: handles an EOF within this grouping
     84
     85  The way we do this is that we have both an input stream and grouping
     86  state in the algorithm. If there is any grouping state then the
     87  input is fed into the grouping machinery. Some input may be held in
     88  the grouping state before it becomes available to the algorithm
     89  proper. Calling 'flush' will cause an error if there's an incomplete
     90  grouping.
     91*/
     92
     93data Grouping =
     94    Grouping(
     95             str name,
     96             value () begin,
     97             tuple[value, Tseq] (value, Token) put,
     98             tuple[value, Tseq] (value, Token) accept,
     99             Tseq (value) end,
     100             void (value, str) eof
     101             );
     102
     103public map[str, Grouping] grpMap = ();
     104
     105public void addGrouping(str name, Grouping g) {
     106  grpMap[name] = g;
     107}
     108
     109public Grouping groupingByName(str name) {
     110  return grpMap[name];
     111}
     112
     113// tp:: grouping type (Grouping)
     114// st:: grouping-specific state (any)
     115data Token = GrpSt(Grouping tp, value st) |
     116  NoGrpSt();
    68117
    69118// cw:: specified page width (constant)
     
    75124// i:: nesting string
    76125// bt:: backtracking state (if any; can be chained)
     126// grp:: grouping state (may be NoGrpSt)
     127// grps:: grouping stack
    77128data FmtSt = FmtSt(int cw, num w, Tseq outDoc, Tseq inDoc,
    78                    int k, LvStack lvStack, str i, FmtSt bt) |
     129                   int k, LvStack lvStack, str i, FmtSt bt,
     130                   Token grp, list[Token] grps) |
    79131  NoFmtSt();
     132
     133// Emits the specified tokens from a source group to an outer group.
     134// The outer group (if any) is assumed to be in the 'grp' field, and
     135// the source group need not be in the state any longer (it must be
     136// specified as 'sg'). The outer group may further emit tokens
     137// forward, all the way up to the top-level (i.e. beyond all the
     138// groupings).
     139//
     140// st:: formatting state (FmtSt)
     141// sg:: source group (Token)
     142// s:: token stream to receive (Tseq or NilTseq())
     143// Returns:: formatting state (FmtSt)
     144FmtSt grpEmit(FmtSt st, Token sg, Tseq s) {
     145  FmtSt to_top() {
     146    inDoc = tseq(s, st.inDoc);
     147    return FmtSt(st.cw, st.w, st.outDoc, inDoc,
     148                 st.k, st.lvStack, st.i, st.bt,
     149                 st.grp, st.grps);
     150  }
     151
     152  FmtSt to_outer(str name, Token tg) {
     153    g_type = tg.tp;
     154    g_st = tg.st;
     155    <n_g_st, r> = g_type.accept(g_st, s, name);
     156    n_grp = GrpSt(tg, n_g_st);
     157    n_st = FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     158                 st.k, st.lvStack, st.i, st.bt,
     159                 n_grp, st.grps);
     160    if (r == NilTseq())
     161      return n_st;
     162    // Since the current grouping produced output, that
     163    // belongs to the next grouping, if any. Hence we make
     164    // the next grouping the current one, and then prepend
     165    // the tokens to be received.
     166    st = grpUnshift(n_st);
     167    inDoc = tseq(r, st.inDoc);
     168    n_st = FmtSt(st.cw, st.w, st.outDoc, inDoc,
     169                 st.k, st.lvStack, st.i, st.bt,
     170                 st.grp, st.grps);
     171    return n_st;
     172  }
     173
     174  if (s == NilTseq())
     175    return st;
     176
     177  Token tg = st.grp;
     178  if (tg == NoGrpSt())
     179    return to_top();
     180  return to_outer(sg.tp.name, tg);
     181}
     182
     183// st:: formatting state (FmtSt)
     184// Returns:: formatting state (FmtSt)
     185FmtSt grpFlush(FmtSt st) {
     186  grp = st.grp;
     187  if (grp != NoGrpSt()) {
     188    g_type = grp.tp;
     189    // Executed for side effects only.
     190    // Intended for checking state,
     191    // and reporting errors.
     192    g_type.eof(grp.st, g_type.name);
     193  }
     194  return st;
     195}
     196
     197// st:: formatting state (FmtSt)
     198// grp:: group to push (Token)
     199// Returns:: formatting state (FmtSt)
     200FmtSt grpPush(FmtSt st, Token grp) {
     201  //println("push <grp> <st.grp> <st.grps>");
     202  Token old_grp = st.grp;
     203  if (old_grp == NoGrpSt()) {
     204    return FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     205                 st.k, st.lvStack, st.i, st.bt,
     206                 grp, st.grps);
     207  } else {
     208    grps = spush(st.grps, old_grp);
     209    return FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     210                 st.k, st.lvStack, st.i, st.bt,
     211                 grp, grps);
     212  }
     213}
     214
     215// st:: formatting state (FmtSt)
     216// Returns:: formatting state (FmtSt)
     217FmtSt grpPop(FmtSt st) {
     218  //println("pop <st.grp> <st.grps>");
     219  if (st.grp == NoGrpSt())
     220    throw "no grouping to pop";
     221  grps = st.grps;
     222  if (isEmpty(grps)) {
     223    return FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     224                 st.k, st.lvStack, st.i, st.bt,
     225                 NoGrpSt(), grps);
     226  }
     227  <grps, grp> = spop(grps);
     228  return FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     229               st.k, st.lvStack, st.i, st.bt,
     230               grp, grps);
     231}
     232
     233// st:: formatting state (FmtSt)
     234// Returns:: formatting state (FmtSt)
     235FmtSt grpUnshift(FmtSt st) {
     236  Token old_grp = st.grp;
     237  st = grpPop(st);
     238  inDoc = tseq(old_grp, st.inDoc);
     239  n_st = FmtSt(st.cw, st.w, st.outDoc, inDoc,
     240               st.k, st.lvStack, st.i, st.bt,
     241               st.grp, st.grps);
     242  return n_st;
     243}
     244
     245// st:: formatting state (FmtSt)
     246// h:: Begin token (Token)
     247// Returns:: formatting state (FmtSt)
     248FmtSt grpBegin(FmtSt st, Token h) {
     249  Grouping g_type = groupingByName(h.s);
     250  Token inner = GrpSt(g_type, g_type.begin());
     251  return grpPush(st, inner);
     252}
     253
     254// st:: formatting state (FmtSt)
     255// t:: End token (Token)
     256// Returns:: formatting state (FmtSt)
     257FmtSt grpEnd(FmtSt st, Token t) {
     258  Grouping t_type = groupingByName(t.s);
     259  Token grp = st.grp;
     260  if (grp == NoGrpSt()) {
     261    t_name = t_type.name;
     262    ctx = take(5, st.inDoc);
     263    throw "close <t_name> grouping without open: before <ctx>";
     264  }
     265  Grouping g_type = grp.tp;
     266  if (g_type != t_type) {
     267    t_name = t_type.name;
     268    g_name = g_type.name;
     269    throw "close <t_name> grouping while <g_name> grouping open";
     270  }
     271  value g_st = grp.st;
     272  Tseq r = g_type.end(g_st);
     273  st = grpPop(st);
     274  if (r == NilTseq())
     275    return st;
     276  return grpEmit(st, grp, r);
     277}
     278
     279// st:: formatting state, with open groupings (FmtSt)
     280// h:: token belonging in the grouping (Token)
     281// Returns:: formatting state (FmtSt)
     282FmtSt grpPut(FmtSt st, Token h) {
     283  Token grp = st.grp;
     284  Grouping g_type = grp.tp;
     285  value g_st = grp.st;
     286  <n_g_st, r> = g_type.put(g_st, h);
     287  n_grp = GrpSt(g_type, n_g_st);
     288  n_st = FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     289               st.k, st.lvStack, st.i, st.bt,
     290               n_grp, st.grps);
     291  return grpEmit(grpUnshift(n_st), grp, r);
     292}
     293
     294// --------------------------------------------------
     295// formatting algorithm
     296// --------------------------------------------------
    80297
    81298// w:: page width (integer)
     
    83300public FmtSt newFmtSt(int w, Tseq inDoc) {
    84301  return FmtSt(w, w, emptyTseq(), inDoc,
    85                0, [], "", NoFmtSt());
     302               0, [], "", NoFmtSt(), NoGrpSt(), []);
    86303}
    87304
     
    94311// After this it is safe to consume all of 'outDoc'.
    95312public FmtSt flush(FmtSt st) {
     313  //println("flush <st.grp> <st.grps>");
     314  st = grpFlush(st);
    96315  return FmtSt(st.cw, st.w,
    97316               st.outDoc, st.inDoc,
    98                st.k, st.lvStack, st.i, NoFmtSt());
    99 }
    100 
    101 // Processes one token of input (if there is any). Note that 'outDoc'
    102 // cannot externally be considered committed for as long as
    103 // backtracking is possible. Except if one specifically wants to flush
    104 // the output.
    105 // d:: token to process
    106 // inDoc:: input after it
    107 // st:: current state
    108 FmtSt processToken(Token d, Tseq inDoc, FmtSt st) {
     317               st.k, st.lvStack, st.i, NoFmtSt(),
     318               st.grp, st.grps);
     319}
     320
     321// This function unshifts grouping state out of the way so that
     322// prepending input 's' becomes possible. Note that any tokens that
     323// have reached the algorithm proper have been past all groupings
     324// already, and have nothing to do with groupings.
     325//
     326// st:: current state (FmtSt)
     327// s:: stream to prepend to inDoc (Tseq)
     328// Returns:: new state (FmtSt)
     329public FmtSt FmtSt_cons(FmtSt st, Tseq s) {
     330  Token grp = st.grp;
     331  Tseq inDoc = st.inDoc;
     332  if (grp == NoGrpSt())
     333    return FmtSt(st.cw, st.w,
     334                 st.outDoc, tseq(s, inDoc),
     335                 st.k, st.lvStack, st.i, st.bt,
     336                 grp, st.grps);
     337  // outermost grouping will be read first
     338  inDoc = tseq(s, reverse(st.grps), grp, inDoc);
     339  return FmtSt(st.cw, st.w,
     340               st.outDoc, inDoc,
     341               st.k, st.lvStack, st.i, st.bt,
     342               NoGrpSt(), []);
     343}
     344
     345// Before calling this function ensure that all state (except for the
     346// argument token) is consistent and in 'st'. Note that this function
     347// does not deal with groupings.
     348//
     349// Note that 'outDoc' cannot externally be considered committed for as
     350// long as backtracking is possible. Except if one specifically wants
     351// to flush the output.
     352//
     353// st:: current state (FmtSt)
     354// d:: token to process (Token)
     355// Returns:: new state (FmtSt)
     356FmtSt processTokenAlgo(FmtSt st, Token d) {
    109357  k = st.k;
    110358  i = st.i;
     
    112360  case Nest(lv): {
    113361    <lvStack, i> = margin(st.lvStack, k, i, lv);
    114     return FmtSt(st.cw, st.w, st.outDoc, inDoc, k, lvStack, i, st.bt);
     362    return FmtSt(st.cw, st.w, st.outDoc, st.inDoc, k, lvStack, i, st.bt,
     363                 st.grp, st.grps);
    115364  }
    116365  case Text(s): {
     
    121370      return st.bt; // backtrack
    122371    else
    123       return FmtSt(st.cw, st.w, put(d, st.outDoc), inDoc,
    124                    k, st.lvStack, i, st.bt);
     372      return FmtSt(st.cw, st.w, put(d, st.outDoc), st.inDoc,
     373                   k, st.lvStack, i, st.bt, st.grp, st.grps);
    125374  }
    126375  case Line(): {
     
    131380    // right won't fit either, the right choice is still taken if
    132381    // backtracking is not possible.
    133     lineDoc = tseq(Line(), Text(i));
    134     outDoc = concat(st.outDoc, lineDoc);
    135     return FmtSt(st.cw, st.w, outDoc, inDoc,
    136                  size(i), st.lvStack, i, NoFmtSt());
     382    outDoc = tseq(st.outDoc, Line(), Text(i));
     383    return FmtSt(st.cw, st.w, outDoc, st.inDoc,
     384                 size(i), st.lvStack, i, NoFmtSt(), st.grp, st.grps);
    137385  }
    138386  case Union(l, r): {
    139387    // Pick left option, leave right for backtracking.
    140     r_st = FmtSt(st.cw, st.w, st.outDoc, concat(r, inDoc),
    141                  k, st.lvStack, i, st.bt);
    142     inDoc = concat(l, inDoc);
    143     return FmtSt(st.cw, st.w, st.outDoc, inDoc,
    144                  k, st.lvStack, i, r_st);
     388    r_st = FmtSt_cons(st, r);
     389    l_st = FmtSt(st.cw, st.w, st.outDoc, st.inDoc,
     390                 k, st.lvStack, i, r_st, st.grp, st.grps);
     391    return FmtSt_cons(l_st, l);
    145392  }
    146393  case Width(w): {
    147     return FmtSt(st.cw, w, st.outDoc, inDoc,
    148                  k, st.lvStack, i, st.bt);
    149   }
    150 
     394    return FmtSt(st.cw, w, st.outDoc, st.inDoc,
     395                 k, st.lvStack, i, st.bt, st.grp, st.grps);
     396  }
     397  case NilToken(): {
     398    return st;
     399  }
    151400    // Spacer compat. Space(str s);
    152401  case Space(s): {
    153     return FmtSt(st.cw, st.w, st.outDoc,
    154                  tseq(union(Text(s), Line()), inDoc),
    155                  k, st.lvStack, i, st.bt);
     402    return FmtSt_cons(st, tseq(union(Text(s), Line())));
    156403  }
    157404  default:
    158         throw "FmtEngine::processToken: unknown token: <d>";
    159   }
    160 }
    161 
    162 // Processes tokens for as long as there is input.
    163 FmtSt processTokens(FmtSt st) {
    164   Token d;
    165   Tseq inDoc;
     405        throw "FmtEngine::processTokenAlgo: unknown token: <d>";
     406  }
     407}
     408
     409// Processes a token (if there is input). Supports groupings.
     410//
     411// st:: current state (FmtSt)
     412// Returns:: new state (FmtSt)
     413FmtSt processToken(FmtSt st) {
     414  <d, inDoc> = tseqGet(st.inDoc);
     415  if (d == Eof())
     416    return st;
     417  st = FmtSt(st.cw, st.w, st.outDoc, inDoc,
     418             st.k, st.lvStack, st.i, st.bt, st.grp, st.grps);
     419  switch (d) {
     420  case GrpSt(_, _): return grpPush(st, d);
     421  case BeginGr(_): return grpBegin(st, d);
     422  case EndGr(_): return grpEnd(st, d);
     423  }
     424  if (st.grp != NoGrpSt())
     425    return grpPut(st, d);
     426  return processTokenAlgo(st, d);
     427}
     428
     429// Whether the state has any more data that can be processed (without
     430// additional input).
     431public bool isPending(FmtSt st) {
     432  // Any non-GrpSt tokens are always kept in inDoc, so this is enough.
     433  return !isEmpty(st.inDoc);
     434}
     435
     436// Adds a tseq to input.
     437public FmtSt write(FmtSt st, Tseq s) {
     438  inDoc = tseq(st.inDoc, s);
     439  return FmtSt(st.cw, st.w, st.outDoc, inDoc,
     440               st.k, st.lvStack, st.i, st.bt, st.grp, st.grps);
     441}
     442
     443// Adds a token to input.
     444public FmtSt put(FmtSt st, Token t) {
     445  return write(st, tseq(t));
     446}
     447
     448// Drives formatting for as long as there is anything pending.
     449public FmtSt drive(FmtSt st) {
    166450  while (true) {
    167     inDoc = st.inDoc;
    168     <d, inDoc> = tseqGet(inDoc);
    169     if (d == Eof())
     451    if (!isPending(st))
    170452      return st;
    171     st = processToken(d, inDoc, st);
     453    //println("before <st>");
     454    st = processToken(st);
     455    //println("after <st>");
    172456  }
    173457}
     
    201485  }
    202486}
    203  
     487
     488// w: output line width
     489// ts: a (complete) input document
    204490public str pretty(int w, Tseq ts) {
    205491  FmtSt st = newFmtSt(w, ts);
    206   st = processTokens(st);
     492  st = flush(drive(st));
    207493  return docToString(st.outDoc);
    208494}
    209495
     496// Clears output buffer by printing it all out. Printing is done as
     497// soon as individual tokens are converted to strings.
    210498public FmtSt printBuffered(FmtSt st) {
    211499  Tseq ts = st.outDoc;
     
    214502    if (t == Eof())
    215503      return FmtSt(st.cw, st.w, ts, st.inDoc,
    216                    st.k, st.lvStack, st.i, st.bt);
     504                   st.k, st.lvStack, st.i, st.bt,
     505                   st.grp, st.grps);
    217506    print(tokenToString(t));
    218507  }
     
    225514  while (true) {
    226515    if (st.bt == NoFmtSt())
     516      // cannot backtrack so safe to print outDoc
    227517      st = printBuffered(st);
    228     <d, inDoc> = tseqGet(st.inDoc);
    229     if (d == Eof())
     518    if (!isPending(st))
    230519      return st;
    231     st = processToken(d, inDoc, st);
     520    //println("before <st>");
     521    st = processToken(st);
     522    //println("after <st>");
    232523  }
    233524}
     
    278569  return group(tseq(x));
    279570}
    280 
    281 // --------------------------------------------------
    282 //
    283 // --------------------------------------------------
    284 
    285 public void main(list[str] args) {
    286 }
  • trunk/magnolia-eclipse/src/org/magnolialang/pgf/tests/RunTestSpacer.rsc

    r808 r824  
    1818
    1919public DecisionTable binOpTable = makeTable((
    20     //<"BINOP","*"> : Insert(Text("xxx")),
    2120    <"BINOP","*"> : Sequence([Insert(Text("x")), Insert(Text("y")), Insert(Text("z"))]),
    2221    <"*","*"> : Nothing()
     
    2423
    2524void printFormatted(Tseq ts) {
    26   prettyPrintFlush(newFmtSt(80, ts));
     25  FmtSt st = newFmtSt(80, ts);
     26  prettyPrintFlush(st);
    2727}
    2828
     
    5555}
    5656
    57 public void main(list[str] args) {
     57public void runRunTestSpacer() {
    5858  for (d <- exprTestData)
    5959    runTest(d);
    6060}
     61
     62public void main(list[str] args) {
     63  runRunTestSpacer();
     64}
  • trunk/magnolia-eclipse/src/org/magnolialang/pgf/tests/RunTestSpacerDirect.rsc

    r823 r824  
    11// run with rascal-src
    2 module org::magnolialang::pgf::tests::RunTestSpacer
     2module org::magnolialang::pgf::tests::RunTestSpacerDirect
    33
    4 import org::magnolialang::pgf::tests::ExprTestData; // generated
    5 
     4import org::magnolialang::pgf::PrettyParseTree;
     5import org::magnolialang::pgf::TableBuilder;
     6import org::magnolialang::pgf::Token;
    67import org::magnolialang::pgf::engines::FmtEngine;
    78import org::magnolialang::pgf::engines::Spacer;
    8 import org::magnolialang::pgf::TableBuilder;
    9 import org::magnolialang::pgf::Token;
     9import org::magnolialang::pgf::tests::SimpleExprLang;
    1010
    1111import IO;
     12import List;
    1213
    1314// not visible from org::magnolialang::pgf::engines::Spacer !!
     
    1819
    1920public DecisionTable binOpTable = makeTable((
    20     //<"BINOP","*"> : Insert(Text("xxx")),
    2121    <"BINOP","*"> : Sequence([Insert(Text("x")), Insert(Text("y")), Insert(Text("z"))]),
    2222    <"*","*"> : Nothing()
     
    5555}
    5656
    57 public void main(list[str] args) {
     57list[Expr] progs =
     58  [
     59   (Expr)`abc + cde`,
     60   (Expr)`abc + cde + def`,
     61   (Expr)`!a-b`,
     62   (Expr)`f(abc, cde)`,
     63   (Expr)`a * b + c / d`
     64  ];
     65
     66public void runRunTestSpacerDirect() {
     67  Tseq f(Expr e) {
     68    return prettyParseTree(emptyTseq(), e);
     69  }
     70  list[Tseq] exprTestData = mapper(progs, f);
    5871  for (d <- exprTestData)
    5972    runTest(d);
    6073}
     74
     75public void main(list[str] args) {
     76  runRunTestSpacerDirect();
     77}
  • trunk/magnolia-eclipse/src/org/magnolialang/pgf/tests/TestFmtEngine.rsc

    r792 r824  
    55import org::magnolialang::pgf::FmtUtil;
    66import org::magnolialang::pgf::FmtUtilC;
     7import org::magnolialang::pgf::Groupings;
    78import org::magnolialang::pgf::Token;
    89
     
    6566list[tuple[str, Tseq]] d_lst =
    6667  [
     68   <"grouped (with groupings)", tseq(group_, d1, _group)>,
    6769   <"many indented lines", cat("margin", indent(2), br, "first", indent(2), br, "second", br, "third", br, "fourth", dedent, dedent, br, "margin")>,
    6870   <"empty block of declarations", cat("class X ", declBlock([]), ";")>,
     
    9496  ];
    9597
    96 public void main(list[str] args) {
     98public void runTestFmtEngine() {
     99  //println(groupingByName("group"));
    97100  //println(fillWords(lorem_ipsum_paragraph)); return;
    98101  if (false) {
     
    108111    testIncremental();
    109112}
     113
     114public void main(list[str] args) {
     115  runTestFmtEngine();
     116}
  • trunk/magnolia-eclipse/src/org/magnolialang/testutil/RascalShell.java

    r807 r824  
    168168        // ---------------------------------------------------------------------------------------
    169169
     170        public static int runModule(Evaluator evaluator, IValueFactory vf, TypeFactory tf, String modName, Collection<String> args) {
     171                IListWriter w = vf.listWriter(tf.stringType());
     172                for(String s : args) {
     173                        w.append(vf.string(s));
     174                }
     175                try {
     176                        evaluator.doImport(null, modName);
     177                        IValue v = evaluator.call(null, "main", w.done());
     178                        if(v != null) {
     179                                System.out.println(v.toString());
     180                        }
     181                        return 0;
     182                }
     183                catch(ParseError pe) {
     184                        URI uri = pe.getLocation();
     185                        System.err.println("Parse error in " + uri + " from <" + (pe.getBeginLine() + 1) + "," + pe.getBeginColumn() + "> to <" + (pe.getEndLine() + 1) + "," + pe.getEndColumn() + ">");
     186                }
     187                catch(StaticError e) {
     188                        System.err.println("Static Error: " + e.getMessage());
     189                        e.printStackTrace(); // for debugging only
     190                }
     191                catch(Throw e) {
     192                        System.err.println("Uncaught Rascal Exception: " + e.getMessage());
     193                        String trace = e.getTrace();
     194                        if(trace != null) {
     195                                System.err.println(trace);
     196                        }
     197                }
     198                catch(ImplementationError e) {
     199                        e.printStackTrace();
     200                        System.err.println("ImplementationError: " + e.getMessage());
     201                }
     202                catch(Throwable e) {
     203                        System.err.println("Unexpected exception (generic Throwable): " + e.getMessage());
     204                        System.err.println(evaluator.getStackTrace());
     205                }
     206                return 1;
     207        }
     208
     209
    170210        /**
    171211         * Loads specified Rascal module in the evaluation context of the specified
     
    185225                IValueFactory vf = compiler.getVf();
    186226                TypeFactory tf = compiler.getTf();
    187                 IListWriter w = vf.listWriter(tf.stringType());
    188                 for(String s : args) {
    189                         w.append(vf.string(s));
    190                 }
    191                 try {
    192                         evaluator.doImport(null, modName);
    193                         IValue v = evaluator.call(null, "main", w.done());
    194                         if(v != null) {
    195                                 System.out.println(v.toString());
    196                         }
    197                         return 0;
    198                 }
    199                 catch(ParseError pe) {
    200                         URI uri = pe.getLocation();
    201                         System.err.println("Parse error in " + uri + " from <" + (pe.getBeginLine() + 1) + "," + pe.getBeginColumn() + "> to <" + (pe.getEndLine() + 1) + "," + pe.getEndColumn() + ">");
    202                 }
    203                 catch(StaticError e) {
    204                         System.err.println("Static Error: " + e.getMessage());
    205                         e.printStackTrace(); // for debugging only
    206                 }
    207                 catch(Throw e) {
    208                         System.err.println("Uncaught Rascal Exception: " + e.getMessage());
    209                         String trace = e.getTrace();
    210                         if(trace != null) {
    211                                 System.err.println(trace);
    212                         }
    213                 }
    214                 catch(ImplementationError e) {
    215                         e.printStackTrace();
    216                         System.err.println("ImplementationError: " + e.getMessage());
    217                 }
    218                 catch(Throwable e) {
    219                         System.err.println("Unexpected exception (generic Throwable): " + e.getMessage());
    220                         System.err.println(evaluator.getStackTrace());
    221                 }
    222                 return 1;
    223         }
     227                return runModule(evaluator, vf, tf, modName, args);
     228        }
     229
    224230}
  • trunk/magnolia-eclipse/src/org/magnolialang/testutil/core.clj

    r822 r824  
    8585  (.eval rsc-evaluator s))
    8686
     87;; Behaves better upon VoidResult.
    8788(defn reval-str [s]
    8889  (rtostring (reval s)))
     
    9293  (.evalMore rsc-evaluator s))
    9394
     95(defn reval-more-str [s]
     96  (rtostring (.evalMore rsc-evaluator s)))
     97
    9498;; E.g. (rimport "org::magnolialang::tasks::Manager")
    9599(defn rimport [s]
     
    101105(defn rcall [s & as]
    102106  (rapply s as))
     107
     108;; This produces VoidResult, which
     109;; org.rascalmpl.interpreter.result.Result.toString dislikes.
     110;; E.g. (rtostring (make-rvoid))
     111(defn make-rvoid []
     112  (reval-more ";"))
    103113
    104114;; For reloading Rascal modules individually.
  • trunk/magnolia-eclipse/test/org/magnolialang/test/core.clj

    r807 r824  
    11(ns org.magnolialang.test.core
    2   (:use [org.magnolialang.clojure.core])
     2  (:use [org.magnolialang.testutil.core])
    33  (:use [clojure.test]))
    44
     
    2323
    2424(deftest test-view-flattened-module
    25   (view-flattened-module "basic.Basic"))
     25  (view-flattened-module "basic.Basic")
     26  (view-flattened-module "basic.Integer")
     27  (view-flattened-module "errors.ConstantOverloading")
     28  (view-flattened-module "mutification.Integer")
     29  (view-flattened-module "mutification.Mutification")
     30  (view-flattened-module "mutification.Mutification2")
     31  (view-flattened-module "override.Override")
     32  (view-flattened-module "scoping.Scoping")
     33  (view-flattened-module "toplevel.Operators")
     34  (view-flattened-module "toplevel.Parens")
     35  (view-flattened-module "toplevel.Predicates")
     36  (view-flattened-module "toplevel.Renaming")
     37  (view-flattened-module "typecheck.OnDefines")
     38  (view-flattened-module "typecheck.Requires")
     39  (view-flattened-module "typecheck.TypeDecl"))
     40
     41(deftest test-rreload
     42  (rimport "org::magnolialang::pgf::tests::TestFmtEngine")
     43  (rreload "org::magnolialang::pgf::tests::TestFmtEngine"))
     44
     45(deftest test-spacer
     46  (rimport "org::magnolialang::pgf::tests::RunTestSpacerDirect")
     47  (reval-str "runRunTestSpacerDirect()"))
     48
     49(deftest test-fmt-engine
     50  (rimport "org::magnolialang::pgf::tests::TestFmtEngine")
     51  (reval-more-str "runTestFmtEngine();")
     52  )
     53
     54(deftest test-token
     55  (rimport "org::magnolialang::pgf::tests::TestToken")
     56  (reval-str "runTestToken()"))
Note: See TracChangeset for help on using the changeset viewer.