Skip to content

Commit a97704d

Browse files
author
Nicola Pfister
committed
adapted tests
1 parent 3533f1f commit a97704d

File tree

3 files changed

+113
-81
lines changed

3 files changed

+113
-81
lines changed

src/JohnnyScript.java

Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,60 +14,86 @@ public class JohnnyScript {
1414

1515
private static final String OUTPUT_EXTENSION = ".ram";
1616
private static final String LINE_COMMENT_DELIMITER = "//";
17+
private static final String JUMP_POINT_DELIMITER = ":";
18+
private static final String VARIABLE_DELIMITER = "#";
1719

1820
public static void main(String[] args) throws IOException {
1921

2022
Path source = getFilename(args);
2123
List<String> code = Files.readAllLines(source);
22-
writeOutFile(source.getFileName().toString(), compileCode(code));
24+
try {
25+
writeOutFile(source.getFileName().toString(), compileCode(code));
26+
} catch (Exception e) {
27+
throw new CompilerHaltException("Compiler halted due to erroneous code!\n", e);
28+
}
2329

2430
}
2531

2632
/**
27-
* Generates the ram code consisting from 1000 lines of compiled JohnnyScript and "000" for empty lines
33+
* Generates ram code using RamCode object
2834
*
29-
* @param sourceLines {@link java.util.List} of String objects containing lines of JohnnyScript code
35+
* @param sourceLines {@link List} of String objects containing lines of JohnnyScript code
3036
* @return compiled numeric code for .ram file
3137
*/
32-
private static List<String> compileCode(List<String> sourceLines) {
33-
List<String> compiled = new ArrayList<>();
34-
35-
for (int i = 0; i <= 999; i++) {
36-
if (i < sourceLines.size()) {
37-
try {
38-
String compiledLine = compile(sourceLines.get(i));
39-
if (compiledLine != null) {
40-
compiled.add(compiledLine);
41-
} else {
42-
sourceLines.remove(i); // Remove comment line from source
43-
i--; // Reduce index to continue at next line without skipping
44-
}
45-
} catch (InvalidScriptException e) {
46-
throw new CompilerHaltException("Invalid code at line " + i, e);
38+
private static List<String> compileCode(List<String> sourceLines) throws InvalidScriptException, DuplicateVariableException, VariableNotInitializedException, DuplicateJumpPointException {
39+
RamCode code = new RamCode();
40+
int lineNumber = 0;
41+
for (String line:sourceLines) {
42+
line = decomment(line);
43+
if (line == null) {
44+
continue;
45+
}
46+
if (line.contains(VARIABLE_DELIMITER)) {
47+
String[] parts = line.split(VARIABLE_DELIMITER + "| ");
48+
if (parts[0].length() == 0) {
49+
// variable declaration (# at start of line)
50+
if(parts.length != 3) {
51+
throw new InvalidScriptException("Syntax error at line " + lineNumber + ": " + line + " (variable declaration: #varname [int])");
52+
} else code.addVar(parts[1],Integer.valueOf(parts[2]));
53+
} else {
54+
// reference to variable
55+
if(parts.length != 3) {
56+
throw new InvalidScriptException("Syntax error at line " + lineNumber + ": " + line + " (variable declaration: #varname [int])");
57+
} else code.addCodeWithVar(encode(parts[0], false),parts[2]);
4758
}
48-
} else compiled.add("000");
59+
} else {
60+
if (line.contains(JUMP_POINT_DELIMITER)) {
61+
String jpName = line.replace(":", "");
62+
code.addJumpPoint(jpName);
63+
} else {
64+
String[] parts = line.split(" ");
65+
if(Codes.valueOf(parts[0].toUpperCase()).codeOrdinal == Codes.JMP.codeOrdinal) {
66+
code.addJump(parts[1]);
67+
} else code.addCode(encode(line, true));
68+
}
69+
70+
}
71+
lineNumber++;
72+
4973
}
5074

51-
return compiled;
75+
try {
76+
return code.getCode();
77+
} catch (InvalidJumpsException e) {
78+
throw new CompilerHaltException("Compiler halted due to erroneous code!\n", e);
79+
}
5280
}
5381

5482
/**
55-
* Handles compiling of specific lines depending on the type of code.
83+
* Removes comments from line and trims excess whitespace
5684
*
5785
* @param line Line of JohnnyScript code
5886
* @return compiled line of .ram code or null if line is a comment
59-
* @throws InvalidScriptException on invalid JohnnyScript code
6087
*/
61-
private static String compile(String line) throws InvalidScriptException {
88+
private static String decomment(String line) {
6289
if (line.contains(LINE_COMMENT_DELIMITER)) {
6390
/* Separate code from comment */
6491
int commentStart = line.indexOf(LINE_COMMENT_DELIMITER);
6592
String nonComment = line.substring(0, commentStart);
6693
if (!nonComment.equals(""))
67-
return encode(nonComment);
94+
return nonComment.trim();
6895
else return null;
69-
} else
70-
return encode(line);
96+
} else return line.trim();
7197
}
7298

7399
/**
@@ -77,17 +103,19 @@ private static String compile(String line) throws InvalidScriptException {
77103
* @return numeric line for instruction
78104
* @throws InvalidScriptException on invalid JohnnyScript code
79105
*/
80-
private static String encode(String line) throws InvalidScriptException {
81-
String[] parts = line.trim().split(" ");
82-
if (parts.length > 2) throw new InvalidScriptException("InvalidJohnnyScript (too many parts): " + line);
106+
private static String encode(String line, boolean appendLow) throws InvalidScriptException {
107+
String[] parts = line.split(" ");
108+
if (parts.length > 2) throw new InvalidScriptException("Syntax error (too many parts): " + line);
83109
if (parts.length == 1) {
84-
return String.format("%03d", Integer.parseInt(parts[0]));
110+
String output = Codes.valueOf(parts[0].toUpperCase()).getCode();
111+
if (appendLow) output = output + "000";
112+
return output;
113+
} else {
114+
String code = parts[0].toUpperCase();
115+
String hi = Codes.valueOf(code).getCode();
116+
String lo = String.format("%03d", Integer.parseInt(parts[1]));
117+
return hi + lo;
85118
}
86-
// else there are two parts
87-
String code = parts[0].toUpperCase();
88-
String lo = String.format("%03d", Integer.parseInt(parts[1]));
89-
String hi = Codes.valueOf(code).getCode();
90-
return hi + lo;
91119

92120
}
93121

@@ -160,7 +188,6 @@ public String getCode() {
160188
class RamCode {
161189

162190
private static final int MAX_LINES = 999;
163-
private static final String JUMP_POINT_DELIMITER = ":";
164191

165192
private static int writeIndex;
166193

@@ -191,16 +218,12 @@ void addVar(String name, int value) throws DuplicateVariableException {
191218
}
192219
}
193220

194-
void addCodeWithVar(String input) throws VariableNotInitializedException {
195-
assert input.contains("#");
196-
String[] parts = input.split("#");
197-
assert parts.length == 2;
198-
String var = parts[1];
221+
void addCodeWithVar(String commandOrdinal, String var) throws VariableNotInitializedException {
199222
if (!variables.containsKey(var)) {
200223
throw new VariableNotInitializedException("Variable has not been initialized: " + var);
201224
} else {
202225
int line = varLoc.get(var);
203-
code.add(parts[0].trim() + String.format("%03d", line));
226+
code.add(commandOrdinal + String.format("%03d", line));
204227
}
205228
}
206229

@@ -232,7 +255,7 @@ private List<String> initializeZeros(List<String> code) {
232255
return code;
233256
}
234257

235-
List getCode() throws InvalidJumpsException {
258+
List<String> getCode() throws InvalidJumpsException {
236259
List<String> output = new ArrayList<>();
237260
initializeZeros(output);
238261

@@ -248,7 +271,7 @@ List getCode() throws InvalidJumpsException {
248271

249272
for (String loc : code
250273
) {
251-
output.add(writeIndex, loc);
274+
output.set(writeIndex, loc);
252275
writeIndex++;
253276
}
254277

@@ -261,7 +284,7 @@ List getCode() throws InvalidJumpsException {
261284
for (int line:jumpList) {
262285
line = 1 + variables.size() + line;
263286
assert output.get(line).equals(jpName + ":");
264-
output.set(line, JohnnyScript.Codes.JMP.codeOrdinal + String.format("%03d", line));
287+
output.set(line, JohnnyScript.Codes.JMP.codeOrdinal + String.format("%03d", 1+variables.size()+jumpPoints.get(jpName)));
265288
}
266289
}
267290
});

test/JohnnyScriptTest.java

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,13 @@ public void commentLine() throws Exception {
8080
List<String> outLines = Files.readAllLines(outputPath);
8181

8282
testCode = new ArrayList<>();
83+
testCode.add("5001");
8384
testCode.add("2000");
8485
testCode.add("2000");
8586

86-
assertEquals(1000, outLines.size());
8787
for (int i = 0; i < testCode.size(); i++) {
8888
assertEquals("Line " + i, testCode.get(i),outLines.get(i));
8989
}
90-
91-
testZeroLines(testCode.size(), outLines);
92-
9390
}
9491

9592
@Test
@@ -107,17 +104,25 @@ public void commentInline() throws Exception {
107104
List<String> outLines = Files.readAllLines(outputPath);
108105

109106
testCode = new ArrayList<>();
107+
testCode.add("5001");
110108
testCode.add("2000");
111109
testCode.add("2001");
112110
testCode.add("2000");
113111

114-
assertEquals(1000, outLines.size());
115112
for (int i = 0; i < testCode.size(); i++) {
116113
assertEquals("Line " + i, testCode.get(i),outLines.get(i));
117114
}
118115

119-
testZeroLines(testCode.size(), outLines);
116+
}
120117

118+
@Test
119+
public void testMaxLines() throws Exception {
120+
List<String> testCode = new ArrayList<>();
121+
Files.write(inputPath, testCode);
122+
123+
JohnnyScript.main(new String[]{validFile});
124+
List<String> outLines = Files.readAllLines(outputPath);
125+
assertEquals(1000, outLines.size());
121126
}
122127

123128
@Test
@@ -137,10 +142,6 @@ public void testSave() throws Exception {
137142
exhTest("SAVE");
138143
}
139144
@Test
140-
public void testJmp() throws Exception {
141-
exhTest("JMP");
142-
}
143-
@Test
144145
public void testTst() throws Exception {
145146
exhTest("TST");
146147
}
@@ -161,23 +162,12 @@ public void testHlt() throws Exception {
161162
exhTest("HLT");
162163
}
163164

164-
/**
165-
* Checks if lines after code are correctly filled with "000"
166-
* @param i start index of "000" lines
167-
* @param testCode code to test
168-
*/
169-
private void testZeroLines(int i, List<String> testCode) {
170-
for (;i < 1000; i++) {
171-
assertEquals("000",testCode.get(i));
172-
}
173-
}
174-
175165
/**
176166
* Tests conversion of all possible addresses for a code
177167
* @param code Code to test
178168
*/
179169
private void exhTest(String code) throws Exception {
180-
for (int i = 0; i < 1000; i++) {
170+
for (int i = 0; i < 999; i++) {
181171
List<String> testCode = new ArrayList<>();
182172
testCode.add(code + " " + i);
183173
Files.write(inputPath, testCode);
@@ -189,12 +179,11 @@ private void exhTest(String code) throws Exception {
189179
testCode = new ArrayList<>();
190180
testCode.add(JohnnyScript.Codes.valueOf(code).getCode()+ String.format("%03d",i));
191181

192-
assertEquals(1000, outLines.size());
193-
for (int j = 0; j < testCode.size(); j++) {
182+
assertEquals("Line " + 0, "5001",outLines.get(0));
183+
184+
for (int j = 1; j < testCode.size(); j++) {
194185
assertEquals("Line " + j, testCode.get(j),outLines.get(j));
195186
}
196-
197-
testZeroLines(testCode.size(),outLines);
198187
}
199188
}
200189
}

test/RamCodeTest.java

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void testAddVar() throws Exception {
5353
@Test(expected = VariableNotInitializedException.class)
5454
public void testAddVarRefWithoutInit() throws Exception {
5555
RamCode code = new RamCode();
56-
code.addCodeWithVar(JohnnyScript.Codes.ADD.codeOrdinal+" #tst");
56+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.ADD.codeOrdinal), "tst");
5757
}
5858

5959
@Test(expected = DuplicateVariableException.class)
@@ -67,7 +67,7 @@ public void testAddDuplicateVar() throws Exception {
6767
public void testAddVarRef() throws Exception {
6868
RamCode code = new RamCode();
6969
code.addVar("tst",5);
70-
code.addCodeWithVar(JohnnyScript.Codes.ADD.codeOrdinal+" #tst");
70+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.ADD.codeOrdinal), "tst");
7171

7272
List codeList = code.getCode();
7373

@@ -105,7 +105,7 @@ public void testAddJumpBeforeJumpPoint() throws Exception {
105105
List codeList = code.getCode();
106106

107107
assertEquals(JohnnyScript.Codes.JMP.codeOrdinal + "001",codeList.get(0));
108-
assertEquals(JohnnyScript.Codes.JMP.codeOrdinal + "001",codeList.get(1));
108+
assertEquals(JohnnyScript.Codes.JMP.codeOrdinal + "002",codeList.get(1));
109109

110110
for (int i = 2; i < 1000; i++) {
111111
assertEquals("000",codeList.get(i));
@@ -131,16 +131,36 @@ public void testInvalidJump() throws Exception {
131131
public void testProgram() throws Exception {
132132
RamCode code = new RamCode();
133133
code.addVar("z3", 0);
134-
code.addCodeWithVar(JohnnyScript.Codes.NULL.codeOrdinal + "#z3");
134+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.NULL.codeOrdinal),"z3");
135135
code.addJumpPoint("start");
136-
code.addCodeWithVar(JohnnyScript.Codes.TAKE.codeOrdinal + "#z3");
136+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.TAKE.codeOrdinal), "z3");
137137
code.addVar("z1", 5);
138-
code.addCodeWithVar(JohnnyScript.Codes.ADD.codeOrdinal + "#z1");
138+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.ADD.codeOrdinal), "z1");
139139
code.addVar("z2", 3);
140-
code.addCodeWithVar(JohnnyScript.Codes.SAVE.codeOrdinal + "#z2");
141-
code.addCodeWithVar(JohnnyScript.Codes.DEC.codeOrdinal + "#z1");
142-
code.addCodeWithVar(JohnnyScript.Codes.TST.codeOrdinal + "#z1");
140+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.SAVE.codeOrdinal), "z2");
141+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.DEC.codeOrdinal), "z1");
142+
code.addCodeWithVar(String.valueOf(JohnnyScript.Codes.TST.codeOrdinal), "z1");
143143
code.addJump("start");
144-
code.addCode(JohnnyScript.Codes.HLT.codeOrdinal + "0");
144+
code.addCode(JohnnyScript.Codes.HLT.codeOrdinal + "000");
145+
146+
List codeList = code.getCode();
147+
148+
assertEquals(JohnnyScript.Codes.JMP.codeOrdinal + "004",codeList.get(0)); //jump to first program line
149+
assertEquals("000",codeList.get(1)); //z3
150+
assertEquals("005",codeList.get(2)); //z1
151+
assertEquals("003",codeList.get(3)); //z2
152+
assertEquals(JohnnyScript.Codes.NULL.codeOrdinal + "001",codeList.get(4));
153+
assertEquals(JohnnyScript.Codes.TAKE.codeOrdinal + "001",codeList.get(5)); // jump point start set to here
154+
assertEquals(JohnnyScript.Codes.ADD.codeOrdinal + "002",codeList.get(6));
155+
assertEquals(JohnnyScript.Codes.SAVE.codeOrdinal + "003",codeList.get(7));
156+
assertEquals(JohnnyScript.Codes.DEC.codeOrdinal + "002",codeList.get(8));
157+
assertEquals(JohnnyScript.Codes.TST.codeOrdinal + "002",codeList.get(9));
158+
assertEquals(JohnnyScript.Codes.JMP.codeOrdinal + "005",codeList.get(10));
159+
assertEquals(JohnnyScript.Codes.HLT.codeOrdinal + "000",codeList.get(11));
160+
161+
162+
for (int i = 12; i < 1000; i++) {
163+
assertEquals("000",codeList.get(i));
164+
}
145165
}
146166
}

0 commit comments

Comments
 (0)