summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/v2/DiceLangEngine.java
blob: a5a9ca4841cc6ffd6551cb2ef8a2af462fef39b3 (plain)
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
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<>();

		// 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());
		}

		if(debugMode)
			System.out.println("Command after destringing: "
					+ destringed.toString());
	}
}