Skip to content

Commit

Permalink
Merge pull request #18 from SWAT-engineering/utility-modules-for-list…
Browse files Browse the repository at this point in the history
…s-and-maps

Utility modules for lists and maps
  • Loading branch information
sungshik authored Sep 11, 2024
2 parents 8557e38 + b0a2942 commit 899fb3d
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,11 @@ import Grammar;
import ParseTree;
import util::Maybe;

import Prelude;

import lang::rascal::grammar::Util;
import util::ListUtil;

alias DelimiterPair = tuple[Maybe[Symbol] begin, Maybe[Symbol] end];

data Direction // Traverse lists of symbols (in productions)...
= forward() // - ...from left to right;
| backward() // - ...from right to left.
;

@synopsis{
Reorder a list according to the specified direction
}

list[&T] reorder(list[&T] l, forward()) = l;
list[&T] reorder(list[&T] l, backward()) = reverse(l);

@synopsis{
Gets the unique leftmost delimiter (`begin`) and the unique rightmost
delimiter `end`, if any, that occur **inside** productions of symbol `s`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,9 @@ import util::Math;
import util::Maybe;

import lang::rascal::grammar::Util;
import util::ListUtil;
import util::MaybeUtil;

@synopsis{
Representation of a traversal direction along a list of symbols
}

data Direction // Traverse lists of symbols (in productions)...
= forward() // - ...from left to right;
| backward() // - ...from right to left.
;

private list[&T] reorder(list[&T] l, forward()) = l;
private list[&T] reorder(list[&T] l, backward()) = reverse(l);

@synopsis{
Computes the *last* set of symbol `s` in grammar `g`
}
Expand All @@ -58,8 +47,8 @@ private map[Symbol, Maybe[set[Symbol]]] firstBySymbol(Grammar g, bool(Symbol) pr
Maybe[set[Symbol]] firstOf([])
= just({});
Maybe[set[Symbol]] firstOf([Symbol h, *Symbol t])
= \set: just({\empty(), *_}) := ret[delabel(h)]
Maybe[set[Symbol]] firstOf([h, *t])
= Maybe[set[Symbol]] \set: just({\empty(), *_}) := ret[delabel(h)]
? util::MaybeUtil::union(\set, firstOf(t))
: ret[delabel(h)];
Expand Down
16 changes: 2 additions & 14 deletions rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import lang::textmate::ConversionConstants;
import lang::textmate::ConversionUnit;
import lang::textmate::Grammar;
import lang::textmate::NameGeneration;
import util::ListUtil;
import util::MapUtil;

alias RscGrammar = Grammar;

Expand Down Expand Up @@ -400,20 +402,6 @@ private list[Symbol] toTerminals(set[Segment] segs) {
return terminals;
}
// TODO: This function could be moved to a separate, generic module
private list[&T] dupLast(list[&T] l)
= reverse(dup(reverse(l))); // TODO: Optimize/avoid `reverse`-ing?
// TODO: This function could be moved to a separate, generic module
private map[&K, list[&V]] insertIn(map[&K, list[&V]] m, map[&K, &V] values)
// Updates the mapping of each key `k` in map of lists `m` to be the union
// of: (1) the existing list `m[k]`, and (2) the new elements-to-be-inserted
// `values[k]`. For instance:
// - m = ("foo": [1, 2, 3], "bar": [], "baz": [1, 2])
// - values = ("foo": [4, 5], "bar": [123], "qux": [3, 4])
// - return = ("foo": [1, 2, 3, 4, 5], "bar": [123], "baz": [1, 2])
= (k: m[k] + (k in values ? [values[k]] : []) | k <- m);
private TmRule toTmRule(RegExp re)
= match(
re.string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import lang::rascal::grammar::analyze::Delimiters;
import lang::textmate::ConversionConstants;
import lang::textmate::Grammar;
import lang::textmate::NameGeneration;
import util::ListUtil;

@synopsis{
Representation of a production in a Rascal grammar to be converted to a rule
Expand Down Expand Up @@ -164,10 +165,6 @@ set[ConversionUnit] removeStrictPrefixes(set[ConversionUnit] units)
bool isStrictPrefix(ConversionUnit u1, ConversionUnit u2)
= isStrictPrefix(u1.prod.symbols, u2.prod.symbols);

// TODO: This function could be moved to a separate, generic module
private bool isStrictPrefix(list[&T] l1, list[&T] l2)
= size(l1) < size(l2) && !any(i <- [0..size(l1)], l1[i] != l2[i]);

@synopsis{
Representation of a *decomposition* of a list of units (i.e., the lists of
symbols of their productions) into their maximally common *prefix*
Expand Down
13 changes: 0 additions & 13 deletions rascal-textmate-core/src/main/rascal/lang/textmate/Grammar.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,6 @@ str toJSON(TmGrammar g, int indent = 2, loc l = |unknown:///|) {
return asJSON(g, indent = indent);
}

@synopsis{
Adds a TextMate rule to both the repository and the patterns of TextMate
grammar `g`
}

TmGrammar addRule(TmGrammar g, TmRule r)
= g [repository = g.repository + (r.name: r)]
[patterns = appendIfAbsent(g.patterns, include("#<r.name>"))];

// TODO: This function could be moved to a separate, generic module
private list[&T] appendIfAbsent(list[&T] vs, &T v)
= v in vs ? vs : vs + v;

@synopsis{
Converts list of strings `names` (typically categories) to a map of captures
}
Expand Down
33 changes: 33 additions & 0 deletions rascal-textmate-core/src/main/rascal/util/ListUtil.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module util::ListUtil

import List;

@synopsis{
Representation of a traversal direction along a list
}

data Direction // Traverse lists...
= forward() // - ...from left to right;
| backward() // - ...from right to left.
;

@synopsis{
Reorder a list according to the specified direction
}

list[&T] reorder(list[&T] l, forward()) = l;
list[&T] reorder(list[&T] l, backward()) = reverse(l);

@synopsis{
Removes multiple occurrences of elements in a list. The last occurrence
remains (cf. `List::dup`).
}

list[&T] dupLast(list[&T] l) = reverse(dup(reverse(l))); // TODO: Optimize/avoid `reverse`-ing?

@synopsis{
Checks if list `l1` is a strict prefix of list `l2`
}

bool isStrictPrefix(list[&T] l1, list[&T] l2)
= size(l1) < size(l2) && l1 == l2[..size(l1)];
13 changes: 13 additions & 0 deletions rascal-textmate-core/src/main/rascal/util/MapUtil.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module util::MapUtil

@synopsis{
Updates the mapping of each key `k` in map of lists `m` to be the union of:
(1) the existing list `m[k]`, and (2) the new elements-to-be-inserted
`values[k]`. For instance:
- m = ("foo": [1, 2, 3], "bar": [], "baz": [1, 2])
- values = ("foo": [4, 5], "bar": [123], "qux": [3, 4])
- return = ("foo": [1, 2, 3, 4, 5], "bar": [123], "baz": [1, 2])
}

map[&K, list[&V]] insertIn(map[&K, list[&V]] m, map[&K, &V] values)
= (k: m[k] + (k in values ? [values[k]] : []) | k <- m);

0 comments on commit 899fb3d

Please sign in to comment.