1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package bjc.utils.dicelang.v2;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.FunctionalStringTokenizer;
import bjc.utils.funcdata.IList;
import bjc.utils.funcdata.IMap;
import bjc.utils.funcutils.ListUtils;
import java.util.Deque;
import java.util.LinkedList;
public class DiceLangEngine {
// Input rules for processing tokens
private Deque<IPair<String, String>> opExpansionTokens;
private Deque<IPair<String, String>> deaffixationTokens;
// ID for generation of string literal variables
private int nextLiteral;
// Debug indicator
private boolean debugMode;
public DiceLangEngine() {
opExpansionTokens = new LinkedList<>();
opExpansionTokens.add(new Pair<>("+", "\\+"));
opExpansionTokens.add(new Pair<>("-", "-"));
opExpansionTokens.add(new Pair<>("*", "\\*"));
opExpansionTokens.add(new Pair<>("/", "/"));
opExpansionTokens.add(new Pair<>(":=", ":="));
opExpansionTokens.add(new Pair<>("=>", "=>"));
deaffixationTokens = new LinkedList<>();
deaffixationTokens.add(new Pair<>("(", "\\("));
deaffixationTokens.add(new Pair<>(")", "\\("));
deaffixationTokens.add(new Pair<>("[", "\\["));
deaffixationTokens.add(new Pair<>("]", "\\]"));
nextLiteral = 1;
// @TODO make configurable
debugMode = true;
}
public boolean runCommand(String command) {
// Split the command into tokens
IList<String> tokens = FunctionalStringTokenizer
.fromString(currentLine)
.toList();
// Will hold tokens with string literals removed
IList<String> destringed = new FunctionalList<>();
// Where we keep the string literals
// @TODO put these in the sym-table early instead
// once there is a sym-table
IMap<String, String> stringLiterals = new FunctionalMap<>();
boolean success = destringTokens(tokens, stringLiterals,
destringed);
if(!success) return success;
if(debugMode)
System.out.println("Command after destringing: "
+ destringed.toString());
}
private boolean destringTokens(IList<String> tokens,
IMap<String, String> stringLiterals,
IList<String> destringed) {
// Are we parsing a string literal?
boolean stringMode = false;
// The current string literal
StringBuilder currentLiteral = new StringBuilder();
for(String token : tokens.toIterable()) {
String[] tokenParts = token.split("^(?!\\\\\")\"");
if(tokenParts.length == 1) {
// Insert token into correct place
if(stringMode) {
currentLiteral.add(tokenParts[0]);
} else {
destringed.add(tokenParts[0]);
}
} else {
// Handle multiple "'s in a token
for(String stringPart : tokenParts) {
// Insert token into correct place
if(stringMode) {
currentLiteral.add(stringPart);
} else {
destringed.add(stringPart);
}
// We found a quote. Toggle string mode
// and collect the literal
stringMode = !stringMode;
if(debugMode)
System.out.printf("DEBUG: Parsed string"
+ " literal ("
+ currentLiteral.toString() + ")");
stringLiterals.put("stringLiteral"
+ nextLiteral,
currentLiteral.toString());
destringed.add("stringLiteral" + nextLiteral);
nextLiteral += 1;
currentLiteral = new StringBuilder();
}
}
}
if(stringMode) {
System.out.printf("\tERROR: Unclosed string literal (%s"
+ ").\n", currentLiteral.toString());
return false;
}
return true;
}
}
|