Commit 452b29e8 authored by xx1219's avatar xx1219
Browse files

xx1219: add more test cases

parent a6b7bb83
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
......@@ -69,23 +70,26 @@ public class PreCompiler {
int lineCounter = 1;
while (br.ready()) {
String str = br.readLine();
if (str.contains(defineRuleContext) && !str.contains(commentMark)) {
str = str.split(commentMark, 2)[0];
if (str.contains(defineRuleContext)) {
/* process and store the macros info */
String[] macro = str.split(" ");
if (macro.length != 3) {
if (macro.length != 3 || macro[0].length() != defineRuleContext.length() - 1) {
mediateFile.delete();
System.out.println("Invalid macro at line " + lineCounter);
System.exit(INTERNAL_ERROR_CODE);
System.exit(SYNTAX_ERROR_CODE);
}
macros.add(new MacroInfo(macro[1], macro[2]));
} else if (str.contains(includeRuleContext) && !str.contains(commentMark)) {
} else if (str.contains(includeRuleContext)) {
/* process and store the stdlib including info */
String[] tokens = str.split("<", 2);
/* e.g. include lib<a, b, c>, tokens[0] = include lib, tokens[1] = a, b, c> */
String libName = tokens[0].split(" ", 2)[1];
List<String> generics = (tokens.length > 1) ? getTypeParam(tokens[1]) : new ArrayList<>();
imports.add(new IncludeInfo(libName, generics));
} else if (str.contains(programBodyMark) && !str.contains(commentMark)) {
String[] prefix = tokens[0].split(" ", 2);
String libName = prefix[1];
List<String> typeParams = (tokens.length == 1) ? new ArrayList<>() : getTypeParam(tokens[1],
lineCounter, prefix[0].length() == includeRuleContext.length() - 1, mediateFile);
imports.add(new IncludeInfo(libName, typeParams, lineCounter));
} else if (str.contains(programBodyMark)) {
bw.write(str + "\n");
break; /* reach the end of file header */
} else {
......@@ -107,9 +111,10 @@ public class PreCompiler {
/* only concat the contents of program body */
while (br.ready()) {
String str = br.readLine();
str = str.split(commentMark, 2)[0];
if (isInProgramBody) {
bw.write(str + "\n");
} else if (str.contains(programBodyMark) && !str.contains(commentMark)) {
} else if (str.contains(programBodyMark)) {
isInProgramBody = true;
}
}
......@@ -121,19 +126,27 @@ public class PreCompiler {
private void concatAllLibs(File mediateFile) throws IOException {
imports.sort((importInfo, t1) -> t1.getMaxTypeLen() - importInfo.getMaxTypeLen());
for (IncludeInfo i : imports) {
String libName = i.getLibName();
List<String> typeParams = i.getTypeParams();
concatOneLib(new File(stdlibPath + libName + stdlibFormatName), mediateFile, typeParams);
concatOneLib(new File(stdlibPath + i.getLibName() + stdlibFormatName),
mediateFile, typeParams, i.getLineNum());
}
}
/* helper function which is used to concat the contents of one lib to the dst file */
private void concatOneLib(File lib, File dst, List<String> typeParams) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(lib));
private void concatOneLib(File lib, File dst, List<String> typeParams, int lineNum) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(lib));
} catch (FileNotFoundException e) {
dst.delete();
System.out.println("Library: " + lib.getPath() + " at line " + lineNum + " not found");
System.exit(SEMANTIC_ERROR_CODE);
}
BufferedWriter bw = new BufferedWriter(new FileWriter(dst, true));
while (br.ready()) {
String str = br.readLine();
str = str.split(commentMark, 2)[0];
/* replace all the generics with the given typeParams */
if (typeParams.size() == 1) {
str = str.replace(genericMark, typeParams.get(0));
......@@ -143,7 +156,7 @@ public class PreCompiler {
}
}
if (str.contains(defineRuleContext) && !str.contains(commentMark)) {
if (str.contains(defineRuleContext)) {
/* get the lib's macro info, assume macros in stdlib are all valid */
String[] macro = str.split(" ");
macros.add(new MacroInfo(macro[1], macro[2]));
......@@ -164,11 +177,12 @@ public class PreCompiler {
/* only do text replacement in the program body */
while (br.ready()) {
String str = br.readLine();
str = str.split(commentMark, 2)[0];
if (isInProgramBody) {
for (MacroInfo m : macros) {
str = str.replace(m.getKey(), m.getValue());
}
} else if (str.contains(programBodyMark) && !str.contains(commentMark)) {
} else if (str.contains(programBodyMark)) {
isInProgramBody = true;
}
bw.write(str + "\n");
......@@ -179,11 +193,13 @@ public class PreCompiler {
}
/* helper function which is used to get the corresponding type params */
private List<String> getTypeParam(String str) {
private List<String> getTypeParam(String str, int lineNum, boolean matchInclude, File mediateFile) {
List<String> typeParams = new ArrayList<>();
int depth = 1;
int i;
StringBuilder token = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
for (i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '<') depth++;
if (c == '>') depth--;
......@@ -199,17 +215,33 @@ public class PreCompiler {
}
}
boolean hasJunkAtEnd = false;
for (i = i + 1; i < str.length(); i++) {
if (str.charAt(i) != ' ') {
hasJunkAtEnd = true;
break;
}
}
if (hasJunkAtEnd || !matchInclude || depth != 0) {
mediateFile.delete();
System.out.println("Invalid include statement at line " + lineNum);
System.exit(SYNTAX_ERROR_CODE);
}
return typeParams;
}
private static class IncludeInfo {
private final String libName;
private final List<String> typeParams;
private final int lineNum;
private int maxTypeLen;
private IncludeInfo(String libName, List<String> typeParams) {
private IncludeInfo(String libName, List<String> typeParams, int lineNum) {
this.libName = libName;
this.typeParams = typeParams;
this.lineNum = lineNum;
maxTypeLen = 0;
for (String p : typeParams) {
if (p.length() > maxTypeLen) {
......@@ -226,6 +258,10 @@ public class PreCompiler {
return typeParams;
}
public int getLineNum() {
return lineNum;
}
public int getMaxTypeLen() {
return maxTypeLen;
}
......
include Sth
begin
skip
end
\ No newline at end of file
binclude List<int>
begin
skip
end
\ No newline at end of file
include List<int>junk...
begin
skip
end
\ No newline at end of file
include List<abc
begin
skip
end
\ No newline at end of file
adefine abc efg
begin
skip
end
\ No newline at end of file
define a b c
begin
skip
end
\ No newline at end of file
define TEST 1
begin
println TEST
end
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment