Skip to content

Commit 1960eff

Browse files
author
Patrick Scheibe
committed
Merge pull request #23 from rsmenon/feat_named_slots
Support for named slots
2 parents f38c57a + bf3eabc commit 1960eff

12 files changed

Lines changed: 388 additions & 198 deletions

File tree

src/de/halirutan/mathematica/codeinsight/highlighting/MathematicaHighlightingAnnotator.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@
3030
import com.intellij.openapi.editor.markup.TextAttributes;
3131
import com.intellij.psi.PsiElement;
3232
import com.intellij.psi.ResolveState;
33+
import com.intellij.psi.tree.IElementType;
3334
import com.intellij.psi.util.PsiTreeUtil;
3435
import de.halirutan.mathematica.codeinsight.completion.SymbolInformationProvider;
36+
import de.halirutan.mathematica.parsing.MathematicaElementTypes;
3537
import de.halirutan.mathematica.parsing.psi.MathematicaRecursiveVisitor;
3638
import de.halirutan.mathematica.parsing.psi.MathematicaVisitor;
3739
import de.halirutan.mathematica.parsing.psi.api.MessageName;
38-
import de.halirutan.mathematica.parsing.psi.api.Slot;
40+
import de.halirutan.mathematica.parsing.psi.api.slots.Slot;
3941
import de.halirutan.mathematica.parsing.psi.api.StringifiedSymbol;
4042
import de.halirutan.mathematica.parsing.psi.api.Symbol;
4143
import de.halirutan.mathematica.parsing.psi.api.function.Function;
44+
import de.halirutan.mathematica.parsing.psi.api.slots.SlotExpression;
4245
import de.halirutan.mathematica.parsing.psi.util.LocalDefinitionResolveProcessor;
4346
import de.halirutan.mathematica.parsing.psi.util.LocalizationConstruct;
4447
import org.jetbrains.annotations.NotNull;
@@ -122,6 +125,16 @@ public void visitFunction(final Function function) {
122125
public void visitSlot(final Slot slot) {
123126
setHighlighting(slot, myHolder, MathematicaSyntaxHighlighterColors.PATTERN);
124127
}
128+
129+
@Override
130+
public void visitSlotExpression(final SlotExpression slotExpr) {
131+
IElementType head = slotExpr.getFirstChild().getNode().getElementType();
132+
if (head.equals(MathematicaElementTypes.ASSOCIATION_SLOT)) {
133+
setHighlighting(slotExpr, myHolder, MathematicaSyntaxHighlighterColors.PATTERN);
134+
} else {
135+
setHighlighting(slotExpr.getFirstChild(), myHolder, MathematicaSyntaxHighlighterColors.PATTERN);
136+
}
137+
}
125138
};
126139
function.accept(slotVisitor);
127140

src/de/halirutan/mathematica/lexer/Mathematica.flex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ ScientificNumber = {PrecisionNumber} "\*^"(-?){Digits}
5252
BaseScientificNumber = {BasePrecisionNumber} "\*^"(-?){Digits}
5353

5454
Slot = "#" [0-9]*
55-
AssociationSlot = "#" [a-zA-Z\$][a-zA-Z0-9\$]*
55+
AssociationSlot = "#" {Identifier} | "#\"" {Identifier} "\"" | "#\\[" {Identifier} "\\]"
5656
SlotSequence = "##" [0-9]*
5757

5858
Out = "%"+

src/de/halirutan/mathematica/lexer/_MathematicaLexer.java

Lines changed: 198 additions & 178 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/de/halirutan/mathematica/parsing/MathematicaElementTypes.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import de.halirutan.mathematica.parsing.psi.impl.rules.ReplaceRepeatedImpl;
5151
import de.halirutan.mathematica.parsing.psi.impl.rules.RuleDelayedImpl;
5252
import de.halirutan.mathematica.parsing.psi.impl.rules.RuleImpl;
53+
import de.halirutan.mathematica.parsing.psi.impl.slots.SlotExpressionImpl;
54+
import de.halirutan.mathematica.parsing.psi.impl.slots.SlotImpl;
5355
import de.halirutan.mathematica.parsing.psi.impl.string.StringExpressionImpl;
5456
import de.halirutan.mathematica.parsing.psi.impl.string.StringImpl;
5557
import de.halirutan.mathematica.parsing.psi.impl.string.StringJoinImpl;
@@ -97,7 +99,6 @@ public interface MathematicaElementTypes {
9799
STRING_LITERAL, STRING_LITERAL_END, STRING_LITERAL_BEGIN, STRING_NAMED_CHARACTER
98100
);
99101
IElementType IDENTIFIER = new MathematicaElementType("IDENTIFIER");
100-
IElementType ASSOCIATION_SLOT = new MathematicaElementType("ASSOCIATION_SLOT");
101102
IElementType STRINGIFIED_IDENTIFIER = new MathematicaElementType("STRINGIFIED_IDENTIFIER");
102103
IElementType NUMBER = new MathematicaElementType("NUMBER");
103104
TokenSet LITERALS = TokenSet.create(
@@ -183,9 +184,8 @@ public interface MathematicaElementTypes {
183184
IElementType QUESTION_MARK = new MathematicaElementType("QUESTION_MARK");
184185
IElementType SLOT = new MathematicaElementType("SLOT");
185186
IElementType SLOT_SEQUENCE = new MathematicaElementType("SLOT_SEQUENCE");
186-
TokenSet SLOTS = TokenSet.create(
187-
SLOT, SLOT_SEQUENCE, ASSOCIATION_SLOT
188-
);
187+
IElementType ASSOCIATION_SLOT = new MathematicaElementType("ASSOCIATION_SLOT");
188+
TokenSet SLOTS = TokenSet.create(SLOT, SLOT_SEQUENCE);
189189
IElementType FUNCTION = new MathematicaElementType("FUNCTION");
190190
IElementType BACK_TICK = new MathematicaElementType("BACK_TICK");
191191
IElementType INFIX_CALL = new MathematicaElementType("INFIX_CALL");
@@ -239,6 +239,7 @@ public interface MathematicaElementTypes {
239239
// THIS SECTION IS AUTOMATICALLY CREATED WITH MATHEMATICA
240240
IElementType LIST_EXPRESSION = new MathematicaElementType("LIST_EXPRESSION");
241241
IElementType ASSOCIATION_EXPRESSION = new MathematicaElementType("ASSOCIATION_EXPRESSION");
242+
IElementType SLOT_EXPRESSION = new MathematicaElementType("SLOT_EXPRESSION");
242243
IElementType NUMBER_EXPRESSION = new MathematicaElementType("NUMBER_EXPRESSION");
243244
IElementType SYMBOL_EXPRESSION = new MathematicaElementType("SYMBOL_EXPRESSION");
244245
IElementType STRINGIFIED_SYMBOL_EXPRESSION = new MathematicaElementType("STRINGIFIED_SYMBOL_EXPRESSION");
@@ -331,6 +332,7 @@ public static PsiElement create(ASTNode node) {
331332
if (type.equals(SYMBOL_EXPRESSION)) return new SymbolImpl(node);
332333
if (type.equals(STRINGIFIED_SYMBOL_EXPRESSION)) return new StringifiedSymbolImpl(node);
333334
if (SLOTS.contains(type)) return new SlotImpl(node);
335+
if (type.equals(SLOT_EXPRESSION) || type.equals(ASSOCIATION_SLOT)) return new SlotExpressionImpl(node);
334336
if (type.equals(NUMBER_EXPRESSION)) return new NumberImpl(node);
335337
if (type.equals(STRING_LITERAL_EXPRESSION)) return new StringImpl(node);
336338

src/de/halirutan/mathematica/parsing/prattparser/ParseletProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class ParseletProvider {
5959

6060
register(MathematicaElementTypes.SLOT_SEQUENCE, MathematicaElementTypes.SLOT_SEQUENCE, new SlotParselet(77)); // ##n expressions
6161
register(MathematicaElementTypes.SLOT, MathematicaElementTypes.SLOT, new SlotParselet(77)); // ##n expressions
62-
register(MathematicaElementTypes.ASSOCIATION_SLOT, MathematicaElementTypes.ASSOCIATION_SLOT, new SlotParselet(77)); // #foo123 expressions
62+
register(MathematicaElementTypes.ASSOCIATION_SLOT, MathematicaElementTypes.ASSOCIATION_SLOT, new SlotExpressionParselet(77)); // #foo123 expressions
6363

6464
register(MathematicaElementTypes.BLANK, MathematicaElementTypes.BLANK_EXPRESSION, new BlankParselet(76)); // Blank(_)
6565
register(MathematicaElementTypes.BLANK, MathematicaElementTypes.BLANK_EXPRESSION, new PrefixBlankParselet(76)); // Blank(_)

src/de/halirutan/mathematica/parsing/prattparser/parselets/FunctionCallParselet.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
import de.halirutan.mathematica.parsing.prattparser.MathematicaParser;
3030

3131
/**
32-
* Parses functions calls like f[x] and array element access like l[[i]] since both start with an opening bracket.
32+
* Parses functions calls like f[x] or slot expressions like #["name"] or #[name] (used often with Associations)
33+
* and array element access like l[[i]] since they all start with an opening bracket.
3334
*
3435
* @author patrick (3/27/13)
3536
*/
@@ -50,12 +51,19 @@ public MathematicaParser.Result parse(MathematicaParser parser, MathematicaParse
5051

5152
PsiBuilder.Marker mainMark = left.getMark().precede();
5253

53-
// parse the start. Either a Part expression like list[[ or a function call f[
54+
// parse the start. Could be one of the following:
55+
// 1. a Part expression like list[[
56+
// 2. a function call f[
57+
// 3. a slot expression like #[ which could be a function call or an Association lookup
5458
boolean isPartExpr = false;
59+
boolean isAssociationSlot = false;
5560
if (parser.matchesToken(MathematicaElementTypes.LEFT_BRACKET, MathematicaElementTypes.LEFT_BRACKET)) {
5661
isPartExpr = true;
5762
parser.advanceLexer();
5863
parser.advanceLexer();
64+
} else if (left.getToken().equals(MathematicaElementTypes.SLOT)) {
65+
isAssociationSlot = true;
66+
parser.advanceLexer();
5967
} else {
6068
parser.advanceLexer();
6169
}
@@ -81,6 +89,10 @@ public MathematicaParser.Result parse(MathematicaParser parser, MathematicaParse
8189
parser.error(ParserBundle.message("General.closing", "']]'"));
8290
mainMark.done(MathematicaElementTypes.PART_EXPRESSION);
8391
return MathematicaParser.result(mainMark, MathematicaElementTypes.PART_EXPRESSION, false);
92+
} else if (isAssociationSlot) {
93+
parser.advanceLexer();
94+
mainMark.done(MathematicaElementTypes.SLOT_EXPRESSION);
95+
return MathematicaParser.result(mainMark, MathematicaElementTypes.SLOT_EXPRESSION, true);
8496
} else {
8597
parser.advanceLexer();
8698
mainMark.done(MathematicaElementTypes.FUNCTION_CALL_EXPRESSION);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2015 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.parsing.prattparser.parselets;
23+
24+
import com.intellij.lang.PsiBuilder;
25+
import com.intellij.psi.tree.IElementType;
26+
import de.halirutan.mathematica.parsing.MathematicaElementTypes;
27+
import de.halirutan.mathematica.parsing.prattparser.CriticalParserError;
28+
import de.halirutan.mathematica.parsing.prattparser.MathematicaParser;
29+
30+
/**
31+
* Parselet for Association style slots
32+
* Created by rsmenon on 11/8/15.
33+
*/
34+
public class SlotExpressionParselet implements PrefixParselet {
35+
36+
private final int myPrecedence;
37+
38+
public SlotExpressionParselet(int precedence) {
39+
this.myPrecedence = precedence;
40+
}
41+
42+
@Override
43+
public MathematicaParser.Result parse(MathematicaParser parser) throws CriticalParserError {
44+
PsiBuilder.Marker symbolMark = parser.mark();
45+
final IElementType tokenType = parser.getTokenType();
46+
if (tokenType.equals(MathematicaElementTypes.ASSOCIATION_SLOT)) {
47+
parser.advanceLexer();
48+
symbolMark.done(tokenType);
49+
return MathematicaParser.result(symbolMark, tokenType, true);
50+
} else {
51+
return MathematicaParser.notParsed();
52+
}
53+
54+
}
55+
56+
public int getPrecedence() {
57+
return myPrecedence;
58+
}
59+
}

src/de/halirutan/mathematica/parsing/psi/MathematicaVisitor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import de.halirutan.mathematica.parsing.psi.api.rules.ReplaceRepeated;
3535
import de.halirutan.mathematica.parsing.psi.api.rules.Rule;
3636
import de.halirutan.mathematica.parsing.psi.api.rules.RuleDelayed;
37+
import de.halirutan.mathematica.parsing.psi.api.slots.Slot;
38+
import de.halirutan.mathematica.parsing.psi.api.slots.SlotExpression;
3739

3840

3941
/**
@@ -169,6 +171,10 @@ public void visitSlot(Slot slot) {
169171
visitElement(slot);
170172
}
171173

174+
public void visitSlotExpression(SlotExpression slotExpr) {
175+
visitElement(slotExpr);
176+
}
177+
172178
public void visitUndirectedEdge(final UndirectedEdge undirectedEdge) {
173179
visitElement(undirectedEdge);
174180
}

src/de/halirutan/mathematica/parsing/psi/api/Slot.java renamed to src/de/halirutan/mathematica/parsing/psi/api/slots/Slot.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014 Patrick Scheibe
2+
* Copyright (c) 2015 Patrick Scheibe
33
* Permission is hereby granted, free of charge, to any person obtaining a copy
44
* of this software and associated documentation files (the "Software"), to deal
55
* in the Software without restriction, including without limitation the rights
@@ -19,7 +19,9 @@
1919
* THE SOFTWARE.
2020
*/
2121

22-
package de.halirutan.mathematica.parsing.psi.api;
22+
package de.halirutan.mathematica.parsing.psi.api.slots;
23+
24+
import de.halirutan.mathematica.parsing.psi.api.Expression;
2325

2426
/**
2527
* Created with IntelliJ IDEA. User: patrick Date: 3/28/13 Time: 12:33 AM Purpose:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2015 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.parsing.psi.api.slots;
23+
24+
import de.halirutan.mathematica.parsing.psi.api.Expression;
25+
26+
/**
27+
* Created by rsmenon on 11/8/15.
28+
*/
29+
public interface SlotExpression extends Expression {
30+
31+
}

0 commit comments

Comments
 (0)