/*
* Copyright 2012 Phil Pratt-Szeliga and other contributors
* http://chirrup.org/
*
* See the file LICENSE for copying permission.
*/
package org.trifort.rootbeer.compressor;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
public class Compressor {
private Map<String, String> compressMap;
private int compressNumber;
public Compressor(){
compressMap = new HashMap<String, String>();
compressNumber = 1;
put("__global__");
put("__device__");
put("__shared__");
put("char");
put("int");
put("boolean");
put("short");
put("long");
put("float");
put("double");
put("void");
put("unsigned");
put("signed");
put("return");
put("goto");
put("if");
put("for");
put("break");
put("continue");
put("else");
put("#define");
put("typedef");
put("switch");
put("while");
put("case");
put("default");
put("sizeof");
put("entry");
put("barrier");
put("CLK_GLOBAL_MEM_FENCE");
put("#ifndef");
put("#ifdef");
put("#endif");
put("atomicMax");
put("atomicExch");
put("atomicAdd");
put("__syncthreads");
put("blockIdx");
put("blockDim");
put("threadIdx");
put("x");
compressMap.put("true", "1");
compressMap.put("false", "0");
compressMap.put("bool", "int");
//static math functions
put("abs");
put("acos");
put("asin");
put("atan");
put("atan2");
put("cbrt");
put("ceil");
put("cos");
put("cosh");
put("exp");
put("expm1");
put("floor");
put("IEEEremainder");
put("log");
put("log10");
put("log1p");
put("max");
put("min");
put("pow");
put("random");
put("rint");
put("round");
put("signum");
put("sin");
put("sigh");
put("sqrt");
put("tan");
put("tanh");
put("toDegrees");
put("toRadians");
put("ulp");
}
private void put(String str){
compressMap.put(str, str);
}
public String compress(String input) throws RecognitionException {
List<String> list = new ArrayList<String>();
String[] tokens = input.split("\\n");
for(String token : tokens){
list.add(token);
}
return run(list);
}
public static void main(String[] args) {
Compressor m = new Compressor();
try {
String ret = m.run(m.getLines("../Product/generated.cu"));
PrintWriter writer = new PrintWriter("../Product/gencompress.cu");
writer.append(ret);
writer.flush();
} catch(NoViableAltException ex){
Token token = ex.token;
ex.printStackTrace();
} catch(Exception ex){
ex.printStackTrace();
}
}
private String run(List<String> lines) throws RecognitionException {
boolean string_state = false;
StringBuilder ret = new StringBuilder();
for(String line : lines){
if(line.startsWith("#pragma")){
ret.append(line+"\n");
continue;
}
//temp for debug to see if things compile in gcc
//else if(line.contains("barrier")){
// continue;
//}
string_state = false;
ANTLRStringStream stream = new ANTLRStringStream(line);
OpenCLLexer lexer = new OpenCLLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
OpenCLParser parser = new OpenCLParser(tokens);
OpenCLParser.program_return prog = parser.program();
List<Boolean> modify = prog.modify;
List<String> prog_tokens = prog.ret;
List<Boolean> is_string = prog.string;
for(int i = 0; i < prog_tokens.size(); ++i){
String text = prog_tokens.get(i);
boolean mod = modify.get(i);
if(is_string.get(i)) {
string_state = !string_state;
ret.append(text);
} else if(mod == false || string_state){
ret.append(text);
} else {
String new_token = compressToken(text);
ret.append(new_token);
}
if(string_state && i+1 < prog_tokens.size() && is_string.get(i+1) ){
//do nothing
} else if(string_state && is_string.get(i) ){
//do nothing
} else if(text.equals("\\")){
//do nothing
} else {
ret.append(" ");
}
}
ret.append("\n");
}
return ret.toString();
}
private List<String> getLines(String filename) throws Exception {
List<String> ret = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader(filename));
while(true){
String line = reader.readLine();
if(line == null)
break;
ret.add(line);
}
return ret;
}
private String compressToken(String text) {
if(compressMap.containsKey(text)){
return compressMap.get(text);
}
String ret;
do {
ret = toBase52(compressNumber);
compressNumber++;
} while(compressMap.containsKey(ret));
compressMap.put(text, ret);
return ret;
}
private String toBase52(int value){
String compressString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int radix = compressString.length();
String ret = "";
while(value > 0){
int mod = value % radix;
value /= radix;
ret += compressString.charAt(mod);
}
return ret;
}
}