From 453ebcb7c0f018dabf680e51f467c01bb9d2e8da Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 10:07:03 +0200 Subject: [PATCH 1/7] Create new module `MapUtil` and move existing code there --- .../src/main/rascal/lang/textmate/Conversion.rsc | 11 +---------- .../src/main/rascal/util/MapUtil.rsc | 13 +++++++++++++ 2 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 rascal-textmate-core/src/main/rascal/util/MapUtil.rsc diff --git a/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc b/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc index 62286c9..d933f68 100644 --- a/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc @@ -21,6 +21,7 @@ import lang::textmate::ConversionConstants; import lang::textmate::ConversionUnit; import lang::textmate::Grammar; import lang::textmate::NameGeneration; +import util::MapUtil; alias RscGrammar = Grammar; @@ -404,16 +405,6 @@ private list[Symbol] toTerminals(set[Segment] segs) { 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, diff --git a/rascal-textmate-core/src/main/rascal/util/MapUtil.rsc b/rascal-textmate-core/src/main/rascal/util/MapUtil.rsc new file mode 100644 index 0000000..4de83f5 --- /dev/null +++ b/rascal-textmate-core/src/main/rascal/util/MapUtil.rsc @@ -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); \ No newline at end of file From d8e8f13ce54e553d07bba296978f5ee71f8b2592 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 10:08:44 +0200 Subject: [PATCH 2/7] Create new module `ListUtil` and move existing code there --- .../rascal/grammar/analyze/Delimiters.rsc | 15 +-------- .../lang/rascal/grammar/analyze/Symbols.rsc | 13 +------- .../main/rascal/lang/textmate/Conversion.rsc | 5 +-- .../rascal/lang/textmate/ConversionUnit.rsc | 5 +-- .../src/main/rascal/util/ListUtil.rsc | 33 +++++++++++++++++++ 5 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 rascal-textmate-core/src/main/rascal/util/ListUtil.rsc diff --git a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Delimiters.rsc b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Delimiters.rsc index 70a0e6a..c9814b2 100644 --- a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Delimiters.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Delimiters.rsc @@ -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` diff --git a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc index 27ba177..1446f18 100644 --- a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc @@ -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` } diff --git a/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc b/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc index d933f68..6564247 100644 --- a/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc @@ -21,6 +21,7 @@ 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; @@ -401,10 +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? - private TmRule toTmRule(RegExp re) = match( re.string, diff --git a/rascal-textmate-core/src/main/rascal/lang/textmate/ConversionUnit.rsc b/rascal-textmate-core/src/main/rascal/lang/textmate/ConversionUnit.rsc index 9ddbf31..edf797e 100644 --- a/rascal-textmate-core/src/main/rascal/lang/textmate/ConversionUnit.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/textmate/ConversionUnit.rsc @@ -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 @@ -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* diff --git a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc new file mode 100644 index 0000000..5c834b3 --- /dev/null +++ b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc @@ -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) && !any(i <- [0..size(l1)], l1[i] != l2[i]); \ No newline at end of file From 9c77dff5e6574a6a0d3233872532df0e4e115249 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 10:09:34 +0200 Subject: [PATCH 3/7] Add explicit type to help type checker --- .../src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc index 1446f18..164d401 100644 --- a/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/rascal/grammar/analyze/Symbols.rsc @@ -47,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)]; From 6b204adbd8dd9b0ab561ea771966c94685079777 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 10:10:10 +0200 Subject: [PATCH 4/7] Remove unused code --- .../src/main/rascal/lang/textmate/Grammar.rsc | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/rascal-textmate-core/src/main/rascal/lang/textmate/Grammar.rsc b/rascal-textmate-core/src/main/rascal/lang/textmate/Grammar.rsc index 381daa7..42d3a39 100644 --- a/rascal-textmate-core/src/main/rascal/lang/textmate/Grammar.rsc +++ b/rascal-textmate-core/src/main/rascal/lang/textmate/Grammar.rsc @@ -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("#"))]; - -// 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 } From 9aa55521dd81081a23ce0bc784371b966889203a Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 15:18:51 +0200 Subject: [PATCH 5/7] Improve `isStrictPrefix` (shorter and faster!) --- rascal-textmate-core/src/main/rascal/util/ListUtil.rsc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc index 5c834b3..036a03f 100644 --- a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc +++ b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc @@ -1,6 +1,8 @@ module util::ListUtil import List; +import util::Benchmark; +import IO; @synopsis{ Representation of a traversal direction along a list @@ -30,4 +32,4 @@ list[&T] dupLast(list[&T] l) = reverse(dup(reverse(l))); // TODO: Optimize/avoid } bool isStrictPrefix(list[&T] l1, list[&T] l2) - = size(l1) < size(l2) && !any(i <- [0..size(l1)], l1[i] != l2[i]); \ No newline at end of file + = size(l1) < size(l2) && l1 == l2[..size(l2)]; \ No newline at end of file From 5514a53308d5bb8b937a89f2326b69147c0e9bb0 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 15:25:17 +0200 Subject: [PATCH 6/7] Fix typo --- rascal-textmate-core/src/main/rascal/util/ListUtil.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc index 036a03f..7c4a7a0 100644 --- a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc +++ b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc @@ -32,4 +32,4 @@ list[&T] dupLast(list[&T] l) = reverse(dup(reverse(l))); // TODO: Optimize/avoid } bool isStrictPrefix(list[&T] l1, list[&T] l2) - = size(l1) < size(l2) && l1 == l2[..size(l2)]; \ No newline at end of file + = size(l1) < size(l2) && l1 == l2[..size(l1)]; \ No newline at end of file From b0a2942496a0b1e7c4075c83c99978c4bc8fb2e5 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 10 Sep 2024 15:25:54 +0200 Subject: [PATCH 7/7] Remove unused imports --- rascal-textmate-core/src/main/rascal/util/ListUtil.rsc | 2 -- 1 file changed, 2 deletions(-) diff --git a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc index 7c4a7a0..65f6598 100644 --- a/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc +++ b/rascal-textmate-core/src/main/rascal/util/ListUtil.rsc @@ -1,8 +1,6 @@ module util::ListUtil import List; -import util::Benchmark; -import IO; @synopsis{ Representation of a traversal direction along a list