Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Show changes
Showing
with 1615 additions and 695 deletions
......@@ -6,7 +6,7 @@ aspect PPIndentation {
inh String Field.pp_indent();
inh String StructType.pp_indent();
eq StructType.getField(int index).pp_indent() = pp_indent() + " ";
eq Program.getDecl(int index).pp_indent() = "";
eq Specification.getDecl(int index).pp_indent() = "";
}
......@@ -18,7 +18,7 @@ aspect PrettyPrint {
" not declared");
}
public void Program.pp(PrintStream out) {
public void Specification.pp(PrintStream out) {
for(int i = 0; i < getNumDecl(); i++) {
getDecl(i).pp(out);
}
......@@ -27,24 +27,24 @@ aspect PrettyPrint {
// Pretty print declarations
public void TypeDecl.pp(PrintStream out) {
out.print("typedef ");
getType().ppIdentifier(out, getName());
getDataType().ppIdentifier(out, getName());
out.println(";");
}
public void SampleDecl.pp(PrintStream out) {
out.print("sample ");
getType().ppIdentifier(out, getName());
getDataType().ppIdentifier(out, getName());
out.println(";");
}
public void Field.pp(PrintStream out) {
out.print(pp_indent());
getType().ppIdentifier(out, getName());
getDataType().ppIdentifier(out, getName());
out.println(";");
}
// Pretty print variable of a given type
public void Type.ppIdentifier(PrintStream out, String id) {
public void DataType.ppIdentifier(PrintStream out, String id) {
ppPrefix(out);
out.print(" ");
out.print(id);
......@@ -58,7 +58,7 @@ aspect PrettyPrint {
}
// PrettyPrint prefix type info
public void Type.ppPrefix(PrintStream out) {
public void DataType.ppPrefix(PrintStream out) {
throw new Error(this.getClass().getName() +
".ppPrefix(PrintStream out)" +
" not declared");
......@@ -68,6 +68,10 @@ aspect PrettyPrint {
out.print("void");
}
// public void SampleRefType.ppPrefix(PrintStream out) {
// out.print("sample");
// }
public void PrimType.ppPrefix(PrintStream out) {
out.print(getName());
}
......@@ -77,7 +81,7 @@ aspect PrettyPrint {
}
public void ArrayType.ppPrefix(PrintStream out) {
getType().ppPrefix(out);
getDataType().ppPrefix(out);
}
public void StructType.ppPrefix(PrintStream out) {
......@@ -90,7 +94,7 @@ aspect PrettyPrint {
}
// PrettyPrint suffix type info (array dimensions)
public void Type.ppSuffix(PrintStream out) { }
public void DataType.ppSuffix(PrintStream out) { }
public void ArrayType.ppSuffix(PrintStream out) {
out.print("[");
......@@ -99,7 +103,7 @@ aspect PrettyPrint {
getExp(i).pp(out);
}
out.print("]");
getType().ppSuffix(out);
getDataType().ppSuffix(out);
}
public void IntegerLiteral.pp(PrintStream out) {
......
aspect Python_CodeGenEnv {
// Environment wrapper for Python code generation
// handles qualid nesting, indentation, file writing and
// prefix propagation
public class Python_env extends PrintEnv {
final private class Python_printer extends PrintEnv.Printer {
// public C_printer(PrintStream out) {
// super(out, " ");
// }
}
public Python_env(PrintStream out) {
super(out);
}
}
}
aspect Python_CodeGen {
public void Specification.Python_gen(PrintStream out, String baseName, int version) {
Python_env env = new Python_env(out);
env.println("#!/usr/bin/python");
env.println("# Auto generated " + baseName);
env.println();
env.println("import labcomm2014");
env.println();
Python_genTypes(env);
env.println("typedef = tuple([");
env.indent();
for (int i = 0 ; i < getNumDecl() ; i++) {
getDecl(i).Python_genTypedefListEntry(env);
}
env.unindent();
env.println("])");
env.println("sample = tuple([");
env.indent();
for (int i = 0 ; i < getNumDecl() ; i++) {
getDecl(i).Python_genSampleListEntry(env);
}
env.unindent();
env.println("])");
}
}
aspect PythonTypes {
public void Specification.Python_genTypes(Python_env env) {
for (int i = 0 ; i < getNumDecl() ; i++) {
getDecl(i).Python_genSignatureAndTypedef(env);
}
}
public void Decl.Python_genSignatureAndTypedef(Python_env env) {
throw new Error(this.getClass().getName() +
".Python_genSignatureAndTypedef(Python_env env)" +
" not declared");
}
public void TypeDecl.Python_genSignatureAndTypedef(Python_env env) {
env.println("class " + getName() + "(object):");
env.indent();
env.print("typedef = labcomm2014.typedef(");
Python_genIntentions(env);
env.println(",");
env.indent();
getTypeInstance().Python_genTypedef(env);
env.unindent();
env.println(")");
env.unindent();
env.println();
}
public void SampleDecl.Python_genSignatureAndTypedef(Python_env env) {
env.println("class " + getName() + "(object):");
env.indent();
env.print("signature = labcomm2014.sample(");
Python_genIntentions(env);
env.println(",");
env.indent();
getDataType().Python_genSignature(env);
env.unindent();
env.println(")");
env.print("typedef = labcomm2014.sample(");
Python_genIntentions(env);
env.println(",");
env.indent();
getTypeInstance().Python_genTypedef(env);
env.unindent();
env.println(")");
env.unindent();
env.println();
}
public void Decl.Python_genIntentions(Python_env env) {
getTypeInstance().Python_genIntentions(env);
}
public void TypeInstance.Python_genIntentions(Python_env env) {
// env.print("{");
// for(Intention i : sortedIntentions()) {
// env.print("'"+i.getKey()+"':'"+new String(i.getValue())+"', ");
// }
// env.print("}");
env.print("tuple((");
for(Intention i : sortedIntentions()) {
env.print("('"+i.getKey()+"','"+new String(i.getValue())+"'), ");
}
env.print("))");
}
public void TypeInstance.Python_genTypedef(Python_env env) {
getDataType().Python_genTypedef(env);
}
public void UserType.Python_genSignature(Python_env env) {
lookupType(getName()).getDataType().Python_genSignature(env);
}
public void DataType.Python_genSignature(Python_env env) {
throw new Error(this.getClass().getName() +
".Python_genSignature(Python_env env)" +
" not declared");
}
public void PrimType.Python_genSignature(Python_env env) {
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.print("labcomm2014.BOOLEAN()"); } break;
case LABCOMM_BYTE: { env.print("labcomm2014.BYTE()"); } break;
case LABCOMM_SHORT: { env.print("labcomm2014.SHORT()"); } break;
case LABCOMM_INT: { env.print("labcomm2014.INTEGER()"); } break;
case LABCOMM_LONG: { env.print("labcomm2014.LONG()"); } break;
case LABCOMM_FLOAT: { env.print("labcomm2014.FLOAT()"); } break;
case LABCOMM_DOUBLE: { env.print("labcomm2014.DOUBLE()"); } break;
case LABCOMM_STRING: { env.print("labcomm2014.STRING()"); } break;
case LABCOMM_SAMPLE: { env.print("labcomm2014.SAMPLE()"); } break;
}
}
public void ArrayType.Python_genSignature(Python_env env) {
env.print("labcomm2014.array([");
for (int i = 0 ; i < getNumExp() ; i++) {
if (i > 0) { env.print(", "); }
env.print(getExp(i).Python_getValue());
}
env.println("],");
env.indent();
getDataType().Python_genSignature(env);
env.print(")");
env.unindent();
}
public void StructType.Python_genSignature(Python_env env) {
env.println("labcomm2014.struct([");
env.indent();
for (int i = 0 ; i < getNumField() ; i++) {
if (i > 0) { env.println(","); }
getField(i).Python_genSignature(env);
}
env.print("])");
env.unindent();
}
public void VoidType.Python_genSignature(Python_env env) {
env.println("labcomm2014.struct([])");
}
public void Field.Python_genSignature(Python_env env) {
env.print("(");
Python_genIntentions(env);
env.print(", ");
getDataType().Python_genSignature(env);
env.print(")");
}
public void UserType.Python_genTypedef(Python_env env) {
env.println(getName() + ".typedef");
}
public void DataType.Python_genTypedef(Python_env env) {
throw new Error(this.getClass().getName() +
".Python_genTypedef(Python_env env)" +
" not declared");
}
public void PrimType.Python_genTypedef(Python_env env) {
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.print("labcomm2014.BOOLEAN()"); } break;
case LABCOMM_BYTE: { env.print("labcomm2014.BYTE()"); } break;
case LABCOMM_SHORT: { env.print("labcomm2014.SHORT()"); } break;
case LABCOMM_INT: { env.print("labcomm2014.INTEGER()"); } break;
case LABCOMM_LONG: { env.print("labcomm2014.LONG()"); } break;
case LABCOMM_FLOAT: { env.print("labcomm2014.FLOAT()"); } break;
case LABCOMM_DOUBLE: { env.print("labcomm2014.DOUBLE()"); } break;
case LABCOMM_STRING: { env.print("labcomm2014.STRING()"); } break;
case LABCOMM_SAMPLE: { env.print("labcomm2014.SAMPLE()"); } break;
}
}
public void ArrayType.Python_genTypedef(Python_env env) {
env.print("labcomm2014.array([");
for (int i = 0 ; i < getNumExp() ; i++) {
if (i > 0) { env.print(", "); }
env.print(getExp(i).Python_getValue());
}
env.println("],");
env.indent();
getDataType().Python_genTypedef(env);
env.print(")");
env.unindent();
}
public void StructType.Python_genTypedef(Python_env env) {
env.println("labcomm2014.struct([");
env.indent();
for (int i = 0 ; i < getNumField() ; i++) {
if (i > 0) { env.println(","); }
getField(i).Python_genTypedef(env);
}
env.print("])");
env.unindent();
}
public void VoidType.Python_genTypedef(Python_env env) {
env.println("labcomm2014.struct([])");
}
public void Field.Python_genTypedef(Python_env env) {
env.print("(");
Python_genIntentions(env);
env.print(", ");
getDataType().Python_genTypedef(env);
env.print(")");
}
public void Decl.Python_genTypedefListEntry(Python_env env) {
}
public void TypeDecl.Python_genTypedefListEntry(Python_env env) {
env.println(getName() + ",");
}
public void Decl.Python_genSampleListEntry(Python_env env) {
}
public void SampleDecl.Python_genSampleListEntry(Python_env env) {
env.println(getName()+ ",");
}
public String Exp.Python_getValue() {
throw new Error(this.getClass().getName() +
".Python_getValue()" +
" not declared");
}
public String IntegerLiteral.Python_getValue() {
return getValue();
}
public String VariableSize.Python_getValue() {
return "0";
}
}
aspect RAPID_env {
public class RAPID_env {
public final int version;
private String prefix;
private StringBuilder types;
private StringBuilder constants;
private StringBuilder procedures;
private PrintStream ps;
public RAPID_env(PrintStream ps, String prefix, int version)
{
this.version = version;
this.types = new StringBuilder();
this.constants = new StringBuilder();
this.procedures = new StringBuilder();
this.prefix = prefix;
this.ps = ps;
}
public String prefix() { return this.prefix; }
public String addRecord(String name, java.util.List<String> components)
{
String recordName = this.prefix + "_" + name;
types.append("\tRECORD " + recordName);
types.append("\n");
for (String c : components) {
types.append("\t\t" + c + "\n");
}
types.append("\tENDRECORD");
types.append("\n\n");
return recordName;
}
public void addConstant(String type, String name, String value) {
this.constants.append("\tLOCAL CONST " + type + " " + name +
" := " + value + ";\n");
}
public void addProc(String name, java.util.List<String> params,
java.util.List<String> stmts)
{
this.procedures.append("\tLOCAL PROC " + name + "(");
for (int i = 0; i < params.size(); i++) {
this.procedures.append(params.get(i));
if (i < params.size() - 1) {
this.procedures.append(", ");
}
}
this.procedures.append(")\n");
for (String stmt : stmts) {
this.procedures.append("\t\t" + stmt + "\n");
}
this.procedures.append("\tERROR\n\t\tRAISE ;\n\tENDPROC\n\n");
}
public void flush()
{
ps.println("MODULE " + prefix() + "(SYSMODULE)");
ps.println();
ps.print(types.toString());
ps.println();
ps.println("\tLOCAL CONST string prefix:=\"" + this.prefix + "\";");
ps.print(constants.toString());
ps.println();
ps.print(procedures.toString());
ps.println();
ps.print("ENDMODULE");
}
}
}
aspect RAPID_CodeGen {
public void ASTNode.RAPID_gen(RAPID_env env) {
throw new UnsupportedOperationException();
}
public void Specification.RAPID_gen(String file, String prefix, int version)
throws IOException
{
PrintStream ps = new PrintStream(new FileOutputStream(new File(file)));
RAPID_env env = new RAPID_env(ps, prefix, version);
RAPID_gen(env);
}
public void Specification.RAPID_gen(RAPID_env env)
{
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).RAPID_gen(env);
}
env.flush();
}
public void Decl.RAPID_gen(RAPID_env env) {
throw new UnsupportedOperationException("RAPID code generation (currently) does not support "+getClass().getSimpleName());
}
public void TypeDecl.RAPID_gen(RAPID_env env) {
System.out.println("***WARNING! TypeDecl.RapidGen(.) a NOP after sig reorganization.");
System.out.println(" (Tell a developer to) remove this warning when tested");
}
public void Decl.RAPID_emitFlatSignature(RAPID_env env, String sig_len_name, String sig_name) {
System.out.println("***WARNING! Code not tested after reorganization of signatures.");
System.out.println(" (Tell a developer to) remove this warning when tested");
SignatureList sig = flatSignature(env.version);
StringBuilder sb = new StringBuilder();
sb.append("[");
byte[] d = null;
int sig_len = 0;
for (int i = 0; i < sig.size(); i++) {
d = sig.getData(i, env.version);
for (int j = 0; d != null && j < d.length; j++) {
sb.append(d[j] + ",");
sig_len++;
}
}
sb.delete(sb.length() - 1, sb.length());
sb.append("]");
env.addConstant("num", sig_len_name, "" + sig_len);
env.addConstant("byte", sig_name + "{" + sig_len_name + "}",
sb.toString());
}
public void SampleDecl.RAPID_gen(RAPID_env env) {
// Add type declarations
String fullName = getDataType().RAPID_AddType(env, getName());
// Add signature constants
String sig_len_name = "signature_len_" + getName();
String sig_name = "signature_" + getName();
RAPID_emitFlatSignature(env, sig_len_name, sig_name);
// Add decode procedures
ArrayList<String> params = new ArrayList<String>();
ArrayList<String> stmts = new ArrayList<String>();
params.add("VAR LabComm_Decoder_Sample s");
params.add("string handler");
stmts.add("s.prefix := prefix;");
stmts.add("s.name := \"" + getName() + "\";");
stmts.add("s.handler := handler;");
env.addProc("Dec_Reg_" + getName(), params, stmts);
params.clear();
stmts.clear();
params.add("VAR LabComm_Decoder_Sample s");
params.add("VAR rawbytes sig");
params.add("num user_id");
stmts.add("VAR byte tmp_sig{" + sig_len_name + "};");
stmts.add("IF RawBytesLen(sig)<>" + sig_len_name + " THEN");
stmts.add("\tRETURN;");
stmts.add("ENDIF");
stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
stmts.add("\tUnpackRawBytes sig, i, tmp_sig{i}, \\Hex1;");
stmts.add("ENDFOR");
stmts.add("IF tmp_sig<>" + sig_name + " THEN");
stmts.add("\tRETURN;");
stmts.add("ENDIF");
stmts.add("s.user_id := user_id;");
env.addProc("Reg_If_Signature_Of_" + getName(), params, stmts);
params.clear();
stmts.clear();
params.add("VAR Decoder d");
params.add("VAR LabComm_Stream st");
params.add("VAR LabComm_Decoder_Sample s");
stmts.add("VAR " + fullName + " tmp;");
getDataType().RAPID_AddDecodeInstr(env, stmts, "tmp", "st");
stmts.add("% s.handler % tmp;");
env.addProc("Decode_And_Handle_" + getName(), params, stmts);
params.clear();
stmts.clear();
params.add("VAR Encoder e");
params.add("VAR LabComm_Stream st");
params.add("VAR LabComm_Encoder_Sample s");
stmts.add("s.prefix := prefix;");
stmts.add("s.name := \"" + getName() + "\";");
stmts.add("Encoder_Register_Sample e, st, s;");
env.addProc("Enc_Reg_" + getName(), params, stmts);
params.clear();
stmts.clear();
params.add("VAR Encoder e");
params.add("VAR LabComm_Stream s");
stmts.add("VAR rawbytes buffer;");
stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
stmts.add("\tPackRawBytes " + sig_name +
"{i}, buffer, \\Network, i, \\Hex1;");
stmts.add("ENDFOR");
stmts.add("SocketSend s.soc, \\RawData:=buffer, \\NoOfBytes:=" +
sig_len_name + ";");
env.addProc("Encode_Signature_" + getName(), params, stmts);
params.clear();
stmts.clear();
params.add("VAR Encoder e");
params.add("VAR LabComm_Stream st");
params.add("VAR LabComm_Encoder_Sample s");
params.add("VAR " + fullName + " val");
stmts.add("Encode_Packed st, s.user_id;");
getDataType().RAPID_AddEncodeInstr(env, stmts, "val", "st");
env.addProc("Encode_" + getName(), params, stmts);
}
public String DataType.RAPID_AddType(RAPID_env env, String name) {
throw new UnsupportedOperationException("RAPID code generation does (currently) not support "+getClass().getSimpleName());
}
public String StructType.RAPID_AddType(RAPID_env env, String name) {
ArrayList<String> components = new ArrayList<String>();
for (int i = 0; i < getNumField(); i++) {
Field f = getField(i);
components.add(
f.getDataType().RAPID_AddType(env, name + "_" + f.getName()) +
" " + f.getName() + ";");
}
String typeName = env.addRecord(name, components);
return typeName;
}
public String FixedArrayType.RAPID_AddType(RAPID_env env, String name) {
String typeName = getDataType().RAPID_AddType(env, name + "_e");
if (getNumExp() > 1) {
throw new UnsupportedOperationException("RAPID generation only (currently) supports one-dimensional arrays");
}
ArrayList<String> components = new ArrayList<String>();
for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
components.add(typeName + " e" + i + ";");
}
String completeName = env.addRecord("list_" + name, components);
return completeName;
}
public String PrimType.RAPID_AddType(RAPID_env env, String name) {
if (getToken() == LABCOMM_SHORT ||
getToken() == LABCOMM_FLOAT ||
getToken() == LABCOMM_INT) {
return "num";
} else if (getToken() == LABCOMM_LONG) {
return "dnum";
} else if (getToken() == LABCOMM_STRING) {
return "string";
} else if (getToken() == LABCOMM_BOOLEAN) {
return "bool";
} else if (getToken() == LABCOMM_BYTE) {
return "byte";
}
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
}
public void DataType.RAPID_AddDecodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
}
public void StructType.RAPID_AddDecodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
for (int i = 0; i < getNumField(); i++) {
getField(i).getDataType().RAPID_AddDecodeInstr(env, instrs,
var_name + "." + getField(i).getName(), stream_name);
}
}
public void FixedArrayType.RAPID_AddDecodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
getDataType().RAPID_AddDecodeInstr(env, instrs,
var_name + ".e" + i, stream_name);
}
}
public void PrimType.RAPID_AddDecodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
switch(getToken()) {
case LABCOMM_BYTE:
instrs.add("Decode_Byte " + stream_name + "," + var_name + ";");
break;
case LABCOMM_BOOLEAN:
instrs.add("Decode_Bool " + stream_name + "," + var_name + ";");
break;
case LABCOMM_SHORT:
instrs.add("Decode_Short " + stream_name + "," + var_name + ";");
break;
case LABCOMM_INT:
instrs.add("Decode_Int " + stream_name + "," + var_name + ";");
break;
case LABCOMM_LONG:
instrs.add("Decode_Long " + stream_name + "," + var_name + ";");
break;
case LABCOMM_FLOAT:
instrs.add("Decode_Float " + stream_name + "," + var_name + ";");
break;
case LABCOMM_STRING:
instrs.add("Decode_String " + stream_name + "," + var_name + ";");
break;
default:
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
}
}
public void DataType.RAPID_AddEncodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
}
public void StructType.RAPID_AddEncodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
for (int i = 0; i < getNumField(); i++) {
getField(i).getDataType().RAPID_AddEncodeInstr(env, instrs,
var_name + "." + getField(i).getName(), stream_name);
}
}
public void FixedArrayType.RAPID_AddEncodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
getDataType().RAPID_AddEncodeInstr(env, instrs,
var_name + ".e" + i, stream_name);
}
}
public void PrimType.RAPID_AddEncodeInstr(RAPID_env env,
java.util.List<String> instrs,
String var_name, String stream_name) {
switch(getToken()) {
case LABCOMM_BYTE:
instrs.add("Encode_Byte " + stream_name + "," + var_name + ";");
break;
case LABCOMM_BOOLEAN:
instrs.add("Encode_Bool " + stream_name + "," + var_name + ";");
break;
case LABCOMM_SHORT:
instrs.add("Encode_Short " + stream_name + "," + var_name + ";");
break;
case LABCOMM_INT:
instrs.add("Encode_Int " + stream_name + "," + var_name + ";");
break;
case LABCOMM_LONG:
instrs.add("Encode_Long " + stream_name + "," + var_name + ";");
break;
case LABCOMM_FLOAT:
instrs.add("Encode_Float " + stream_name + "," + var_name + ";");
break;
case LABCOMM_STRING:
instrs.add("Encode_String " + stream_name + "," + var_name + ";");
break;
default:
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
}
}
public int Exp.RAPID_getValue() {
throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
}
public int IntegerLiteral.RAPID_getValue() {
return Integer.parseInt(getValue());
}
}
/* Temporary aspect with forwarding methods */
aspect Refactoring {
syn int ArrayType.getNumExp() = getDim().getNumExp();
syn Exp ArrayType.getExp(int i) = getDim().getExp(i);
syn String Decl.getName() = getTypeInstance().getName();
syn DataType Decl.getDataType() = getTypeInstance().getDataType();
syn String TypeInstance.getName() = getAnnotations().getName();
public Annotations Annotations.addName(String n) {
//XXX TODO: check if name already exists
addAnnotation(new Intention("",n.getBytes()));
return this;
}
public Field.Field(TypeInstance t) {
this(t.getDataType(), t.getAnnotations());
}
public TypeInstance.TypeInstance(DataType t, String n, Annotations a) {
this(t, a.addName(n));
}
public TypeInstance.TypeInstance(DataType t, String n) {
this(t, new Annotations().addName(n));
System.out.println("WARNING! TypeInstance(DataType, String) ignoring intention list");
}
syn Annotation TypeInstance.getAnnotation(int i) = getAnnotations().getAnnotation(i);
}
import java.util.*;
aspect Signature {
syn boolean Decl.isSampleDecl();
eq TypeDecl.isSampleDecl() = false;
eq SampleDecl.isSampleDecl() = true;
syn boolean Decl.sendOnlyFlatSignatures(Java_env env) = (env.version==2006);
eq Decl.getSignature().parentDecl() = this;
eq Signature.getSignatureList().parentDecl() = parentDecl();
inh Decl Signature.parentDecl();
inh Decl SignatureList.parentDecl();
syn nta Signature Decl.getSignature() {
SignatureList sl = new SignatureList();
genSigLineForDecl(sl, true, this);
SignatureList fsl = new SignatureList();
flatSignature(fsl);
Signature sig = new Signature();
sig.setSignatureList(sl);
sig.setFlatSignatureList(fsl);
setSignature(sig);
return sig;
}
public String SignatureLine.getIndentString() {
StringBuffer result = new StringBuffer();
int indent = getIndent();
for (int i = 0 ; i < indent ; i++) {
result.append(" ");
}
return result.toString();
}
syn byte[] SignatureLine.getData(int version) = null;
// return new byte[0];
private Decl TypeRefSignatureLine.decl;
public TypeRefSignatureLine.TypeRefSignatureLine(int indent, Decl decl, String comment) {
super(indent, comment);
this.decl = decl;
}
public void SignatureList.addTypeRef(Decl type, String comment) {
addSignatureLine(new TypeRefSignatureLine(indent, type, comment));
}
public ByteArraySignatureLine.ByteArraySignatureLine(int indent, byte[] data, String comment) {
super(indent, comment);
setData(data);
}
public IntSignatureLine.IntSignatureLine(int indent, int data, String comment) {
super(indent, comment);
setData(data);
}
public void SignatureList.add(byte[] data, String comment) {
addSignatureLine(new ByteArraySignatureLine(indent, data, comment));
}
public void SignatureList.addInt(int data, String comment) {
addSignatureLine(new IntSignatureLine(indent, data, comment));
}
protected byte[] DataSignatureLine.getIntBytes(int value, int version) {
byte data[];
switch(version) {
case 2006: // Use old encoding with 32 bit integers
data = new byte[4];
for (int i = 0 ; i < 4 ; i++) {
data[3 - i] = (byte)((value >> (8 * i)) & 0xff);
}
//add(data, comment);
break;
case 2014: // Use new encoding with varints
byte[] tmp = new byte[5];
long v = value & 0xffffffff;
int i, j;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp[i] = (byte)(v & 0x7f);
}
byte[] packed = new byte[i];
for (i = i - 1, j = 0 ; i >= 0 ; i--, j++) {
packed[j] = (byte)(tmp[i] | (i!=0?0x80:0x00));
}
//add(packed, comment);
data = packed;
break;
default:
throw new RuntimeException("Unsupported version = "+version+". This should never happen.");
}
return data;
}
eq IntSignatureLine.getData(int version) {
return getIntBytes(getData(), version);
}
public void SignatureList.addIntentions(Set<Intention> data, String comment) {
//addString(TypeInstance.getIntentionString(data), comment);
//create IntenionSignatureLine
IntentionSignatureLine line = new IntentionSignatureLine(indent, comment, new List());
//TODO: refactor out creation of sorted list of intentions
java.util.ArrayList<Intention> sorted = new ArrayList(data);
java.util.Collections.sort(sorted, TypeInstance.intentionComp);
for(Intention i : sorted) {
line.addIntention(i);
}
addSignatureLine(line);
}
eq IntentionSignatureLine.getData(int version) {
//String tmpString = TypeInstance.getIntentionString(getIntentions());
byte[] bs = TypeInstance.getIntentionBytes(getIntentions());
return bs;
}
public void SignatureList.addString(String data, String comment) {
addSignatureLine(new StringSignatureLine(indent, comment, data));
}
eq StringSignatureLine.getData(int version) {
byte[] lenBytes = getIntBytes(getData().length(), version);
byte[] data = new byte[lenBytes.length+getData().length()];
// first add the encoded length
for (int i = 0 ; i < lenBytes.length ; i++) {
data[i] = lenBytes[i];
}
// and then the actual chars
for (int i = 0 ; i < getData().length() ; i++) {
int idx = lenBytes.length + i;
data[idx] = (byte)(getData().charAt(i) & 0xff);
}
return data;
}
public int SignatureList.size() {
return getNumSignatureLine();
}
public String SignatureList.getIndent(int i) {
StringBuffer result = new StringBuffer();
int indent = getSignatureLine(i).getIndent();
for (i = 0 ; i < indent ; i++) {
result.append(" ");
}
return result.toString();
}
public byte[] SignatureList.getData(int i, int version) {
return getSignatureLine(i).getData(version);
}
public String SignatureList.getComment(int i) {
return getSignatureLine(i).getComment();
}
private int SignatureList.indent;
public void SignatureList.indent() {
indent++;
}
public void SignatureList.unindent() {
indent--;
}
public void ASTNode.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
throw new Error(this.getClass().getName() +
".genSigLineForDecl(SignatureList list)" +
" not declared");
}
public String TypeInstance.getIntentionString() {
return getIntentionString(intentions());
}
public static String TypeInstance.getIntentionString(List<Intention> intentions) {
if(intentions==null) return "";
Iterator<Intention> it = intentions.iterator();
return getIntentionString(it);
}
public static String TypeInstance.getIntentionString(Set<Intention> intentions) {
if(intentions==null) return "";
Iterator<Intention> it = intentions.iterator();
return getIntentionString(it);
}
public static String TypeInstance.getIntentionString(Iterator<Intention> it) {
StringBuilder sb = new StringBuilder();
while(it.hasNext()) {
Intention i = it.next();
sb.append(i.toString());
}
return sb.toString();
}
syn byte[] Intention.keyBytes() = getKey().getBytes();
syn byte[] Intention.valBytes() = getValue();
syn byte[] Intention.toByteArray() {
byte[] k = keyBytes();
byte[] v = valBytes();
int klen = Utilities.size_packed32(k.length);
int vlen = Utilities.size_packed32(v.length);
int tlen = k.length + v.length + Utilities.size_packed32(klen) + Utilities.size_packed32(vlen);
//int size = Utilities.size_packed32(tlen)+tlen;
byte result[] = new byte[tlen];
int pos=0;
// pos = Utilities.encodePacked32(tlen, result, pos, Utilities.size_packed32(tlen));
pos = Utilities.encodePacked32(k.length, result, pos, klen);
for(byte kb : k) {
result[pos++] = kb;
}
pos = Utilities.encodePacked32(v.length, result, pos, vlen);
for(byte vb : v) {
result[pos++] = vb;
}
return result;
}
public byte[] TypeInstance.getIntentionBytes() {
return getIntentionBytes(intentions());
}
public static byte[] TypeInstance.getIntentionBytes(List<Intention> intentions) {
if(intentions==null) return new byte[0];
Iterator<Intention> it = intentions.iterator();
return getIntentionBytes(it);
}
public static byte[] TypeInstance.getIntentionBytes(Set<Intention> intentions) {
if(intentions==null) return new byte[0];
Iterator<Intention> it = intentions.iterator();
return getIntentionBytes(it);
}
public static byte[] TypeInstance.getIntentionBytes(Iterator<Intention> it) {
java.util.ArrayList<byte[]> tmp = new java.util.ArrayList<byte[]>();
int tmpLen=0;
int numIntentions=0;
while(it.hasNext()) {
Intention i = it.next();
byte[] bs = i.toByteArray();
tmp.add(bs);
tmpLen+=bs.length;
numIntentions++;
}
byte result[] = new byte[tmpLen + Utilities.size_packed32(numIntentions)];
int pos = 0;
pos = Utilities.encodePacked32(numIntentions, result, 0, Utilities.size_packed32(numIntentions));
for(byte[] bs : tmp) {
for(byte b : bs) {
result[pos++] = b;
}
}
return result;
}
syn Set<Intention> Specification.emptyIntentions() = new HashSet<Intention>();
inh Set<Intention> ASTNode.noIntentions();
eq Specification.getChild(int i).noIntentions() = emptyIntentions();
syn Set<Intention> ASTNode.intentions();
eq ASTNode.intentions() = noIntentions();
eq TypeInstance.intentions() = intentionSet();
public void TypeInstance.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
// debugAnnotations(this.getName());
// list.addString(inst.getIntentionString(), "intention string");
if(addIntentions()) {
list.addIntentions(intentionSet(), "intentions");
}
getDataType().genSigLineForDecl(list, decl, this);
}
public void TypeDecl.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
//TODO intent
if(decl){
getTypeInstance().genSigLineForDecl(list, decl, this);
}else{
list.addTypeRef(this, "//TODO (from list.addTypeRef)");
}
}
public void SampleDecl.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
//TODO intent
getTypeInstance().genSigLineForDecl(list, decl, this);
}
public void VoidType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(LABCOMM_STRUCT, "void");
list.addInt(0, null);
}
// public void SampleRefType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
// list.addInt(LABCOMM_SAMPLE_REF, "sample");
// }
public void PrimType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(getToken(), null);
}
/* For UserType, the decl parameter is ignored, as a UserType
* will always be a TypeRef
*/
public void UserType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
TypeDecl thet = lookupType(getName());
list.addTypeRef(thet, null);
}
public void ArrayType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(LABCOMM_ARRAY, signatureComment());
list.indent();
list.addInt(getNumExp(), null);
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).genSigLineForDecl(list, false, null);
}
getDataType().genSigLineForDecl(list, false, null);
list.unindent();
list.add(null, "}");
}
public void StructType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(LABCOMM_STRUCT, "struct { " + getNumField() + " fields");
list.indent();
list.addInt(getNumField(), null);
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).genSigLineForDecl(list, false, inst);
}
list.unindent();
list.add(null, "}");
}
// public void Field.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
// //XXX make intention
// list.addString(getName(), signatureComment());
// super.genSigLineForDecl(list, decl, inst);
// //TODOintent
// //getDataType().genSigLineForDecl(list, decl, inst);
// }
public void IntegerLiteral.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(Integer.parseInt(getValue()), null);
}
public void VariableSize.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) {
list.addInt(0, null);
}
}
aspect TypeCheck {
public void ASTNode.typeCheck() {
// calls to the different type checks to be performed
nullTypeCheck();
}
// void is not allowed as a field in a struct or an array element
syn boolean DataType.isNull();
eq DataType.isNull() = false;
eq VoidType.isNull() = true;
eq UserType.isNull() = decl().isNull();
syn boolean TypeDecl.isNull();
eq TypeDecl.isNull() = getDataType().isNull();
public void ASTNode.nullTypeCheck() {}
public void Field.nullTypeCheck() {
if(getDataType().isNull()) {
error("field " + getName() + " of struct "+ declName()+ " may not be of type void");
}
}
public void ParseArrayType.nullTypeCheck() {
if(getDataType().isNull()) {
error("elements of array "+declName()+" may not be of type void");
}
}
public void ArrayType.nullTypeCheck() {
if(getDataType().isNull()) {
error("elements of array "+declName()+" may not be of type void");
}
}
}
aspect AnnotationCheck {
refine TypeCheck void ASTNode.typeCheck() {
refined(); // similar to call to super
annotationCheck();
}
public void ASTNode.annotationCheck() {}
public void TypeDecl.annotationCheck() {
Iterator<Intention> it = getTypeInstance().intentions().iterator();;
while(it.hasNext()) {
if(!it.next().getKey().equals("")) {
error("TypeDecl " + getName() + " has intentions. (Not allowed for typedefs)");
}
}
}
}
aspect User_Types {
syn String DataType.getTypeName();
eq DataType.getTypeName() = getClass().getName();
eq PrimType.getTypeName() = getName();
eq UserType.getTypeName() = getName();
syn boolean DataType.isUserType();
eq DataType.isUserType() = false;
eq UserType.isUserType() = true;
}
aspect Type_References {
// The dependencies on other type declarations for a Decl.
coll Set<Decl> Decl.type_dependencies() [new HashSet<Decl>()] with add;
Field contributes ((UserType)getDataType()).decl()
when parentDecl() != null && getDataType().isUserType()
to Decl.type_dependencies()
for parentDecl();
UserType contributes decl()
when parentDecl() != null
to Decl.type_dependencies()
for parentDecl();
/*
Field contributes getDataType().decl()
when parentDecl() != null && getDataType().isLeafType()
to Decl.type_dependencies()
for parentDecl();
*/
// The references from other type declarations to a Decl.
coll Set<Decl> Decl.type_references() [new HashSet<Decl>()] with add;
Decl contributes this
to Decl.type_references()
for each type_dependencies();
syn boolean Decl.hasDependencies();
eq Decl.hasDependencies() = !type_dependencies().isEmpty();
syn boolean Decl.isReferenced();
eq Decl.isReferenced() = !type_references().isEmpty();
}
aspect Encoding {
public class Utilities {
/* Size of packed32 variable */
public static int size_packed32(long data)
{
long d = data & 0xffffffff;
int result = 0;
int i;
for (i = 0 ; i == 0 || d != 0; i++, d = (d >>> 7)) {
result++;
}
return result;
}
public static int encodePacked32(long value, byte[] buf, int start, int len) {
int pos = start;
byte[] tmp = new byte[5];
long v = value & 0xffffffff;
int i;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp[i] = (byte)(v & 0x7f);
}
if(i != len) {
throw new Error("wrong length, was: "+i+", expected "+len);
}
for (i = i - 1 ; i >= 0 ; i--) {
buf[pos++] = (byte)(tmp[i] | (i!=0?0x80:0x00));
}
return pos;
}
}
}
aspect PrintEnv {
public abstract class PrintEnv {
protected static class Printer {
private final String indentString = " ";
private boolean newline = true; // last print ended with newline
protected PrintStream out;
private Printer printer;
/** dummy constructor motivated by the FilePrinter subclass */
protected Printer() {
this.out = null;
}
public Printer(PrintStream out) {
this.out = out;
}
public void print(PrintEnv env, String s) {
if (newline) {
newline = false;
for (int i = 0 ; i < env.getIndent() ; i++) {
out.print(indentString);
}
}
out.print(s);
}
public void println(PrintEnv env, String s) {
print(env, s);
out.println();
newline = true;
}
public void println(PrintEnv env) {
out.println();
newline = true;
}
public PrintStream getPrintStream() {
return(out);
}
public void close() throws IOException {
//do nothing
}
}
protected static class FilePrinter extends Printer {
private File file;
private IOException exception;
public FilePrinter(PrintStream out) {
super(out);
}
public FilePrinter(File f) {
file = f;
File parentFile = f.getParentFile();
if(parentFile != null) {
parentFile.mkdirs();
}
}
public void close() throws IOException {
if (out != null) {
out.close();
}
if (exception != null) {
throw exception;
}
}
public void checkOpen() {
if (out == null && exception == null) {
try {
out = new PrintStream(new FileOutputStream(file));
} catch (IOException e) {
exception = e;
}
}
}
public void print(PrintEnv env, String s) {
checkOpen();
super.print(env,s);
}
public void println(PrintEnv env, String s) {
checkOpen();
super.println(env, s);
}
}
public final int version; //labcomm version (2006 or 2014)
public final String verStr; // version suffix to append (currently _2006 and empty string)
private Printer printer;
private int indent;
private int depth;
protected PrintEnv(PrintStream out) {
this(new Printer(out));
}
protected PrintEnv(Printer printer) {
this(printer, 2014);
}
protected PrintEnv(Printer printer, int version) {
this(0, printer, version);
}
protected PrintEnv(int indent, Printer printer, int version) {
this(indent, printer, version, 0);
}
protected PrintEnv(int indent, Printer printer, int version, int depth) {
this.version = version;
this.indent = indent;
this.printer = printer;
this.verStr = LabCommVersion.versionString(version);
this.depth = depth;
}
public void close() throws IOException {
printer.close();
}
public PrintStream getPrintStream() {
return printer.getPrintStream();
}
public void indent(int amount) {
indent += amount;
}
public void indent() {
indent(1);
}
public void unindent(int amount) {
indent -= amount;
if (indent < 0) {
throw new Error("Negative indent level");
}
}
public void unindent() {
unindent(1);
}
public void print(String s) {
printer.print(this, s);
}
public void println(String s) {
printer.println(this, s);
}
public void println() {
printer.println(this, "");
}
public void incDepth() {
depth++;
}
public void decDepth() {
if(depth<=0) {
throw new RuntimeException("decDepth() called when depth = "+depth);
}
depth--;
}
public int getDepth() {
return depth;
}
public int getVersion() {
return version;
}
public int getIndent() {
return indent;
}
public Printer getPrinter() {
return printer;
}
public boolean versionHasMetaData() {
return version != 2006;
}
}
}
aspect Version {
/* An auxilliary class for handling naming and prefixes connected
* to the LabComm version
*/
class LabCommVersion {
public static String versionString(int version) {
switch(version) {
case 2006:
return "2006";
case 2014:
return "2014";
default:
throw new Error("no versionString for version "+version);
}
}
public static boolean versionHasPragma(int version) {
return version != 2006;
}
}
}
import java.util.Collection;
aspect ErrorCheck {
syn int ASTNode.lineNumber() = getLine(getStart());
protected String ASTNode.errors = null;
protected void ASTNode.error(String s) {
s = "Error at " + lineNumber() + ": " + s;
if(errors == null) {
errors = s;
} else {
errors = errors + "\n" + s;
}
}
protected boolean ASTNode.hasErrors() {
return errors != null;
}
public void ASTNode.errorCheck(Collection collection) {
nameCheck();
if(hasErrors())
collection.add(errors);
for(int i = 0; i < getNumChild(); i++) {
getChild(i).errorCheck(collection);
}
}
}
Program ::= Decl*;
abstract Decl ::= Type <Name:String>;
TypeDecl : Decl;
SampleDecl : Decl;
Field ::= Type <Name:String>;
abstract Type;
VoidType : Type;
PrimType : Type ::= <Name:String> <Token:int>;
UserType : Type ::= <Name:String>;
StructType : Type ::= Field*;
ParseArrayType : Type ::= Type Dim*;
abstract ArrayType : Type ::= Type Exp*;
VariableArrayType : ArrayType;
FixedArrayType : ArrayType;
Dim ::= Exp*;
abstract Exp;
IntegerLiteral : Exp ::= <Value:String>;
VariableSize : Exp;
import AST.*;
import java.io.*;
import java.util.*;
public class LabComm {
private static void println(String s) {
System.out.println(s);
}
private static void print_help() {
println("\n Usage: java -jar labcom.jar [options*] FILE");
println("");
println(" --help Shows this help text");
println(" -v Be verbose");
println("[ C options ]");
println(" -C Generates C/H code in FILE.[ch]");
println(" --cprefix=PREFIX Prefixes C types with PREFIX");
println(" --cinclude=FILE Include FILE in generated .c");
println(" --c=CFILE Generates C code in CFILE");
println(" --h=HFILE Generates H code in HFILE");
println("[ C# options]");
println(" --cs Generates C# code in FILE.cs");
println(" --cs=CSFILE Generates C# code in CSFILE");
println(" --csnamespace=NAMESPACE Place C# classes in NAMESPACE");
println("[ Java options ]");
println(" --java=JDIR Generates Java files in JDIR");
println(" --javapackage=PACKAGE Place Java classes in PACKAGE");
println("[ Python options ]");
println(" -P Generates Python code in FILE.py");
println(" --python=PFILE Generates Python code in PFILE");
println("[ Misc options ]");
println(" --pretty Pretty prints on standard output");
println(" --typeinfo=TIFILE Generates typeinfo in TIFILE");
}
private static String getCoreName(String s) {
int i = s.lastIndexOf('.');
return s.substring(0, i > 0 ? i : s.length());
}
private static String getFileName(String s) {
return s.substring(s.lastIndexOf('/') + 1, s.length());
}
private static String getBaseName(String s) {
s = getFileName(s);
int i = s.lastIndexOf('.');
return s.substring(0, i > 0 ? i : s.length());
}
private static String getPrefix(String s) {
return s.substring(s.lastIndexOf('/') + 1, s.length());
}
public static void main(String[] args) {
String fileName = null;
// Scan for first non-option
for (int i = 0 ; i < args.length ; i++) {
if (! args[i].startsWith("-")) {
fileName = args[i];
break;
}
}
String coreName = null;
String prefix = null;
if (fileName != null) {
coreName = getBaseName(fileName);
prefix = getPrefix(coreName);
}
boolean verbose = false;
String cFile = null;
String hFile = null;
Vector cIncludes = new Vector();
String cPrefix = prefix;
String csFile = null;
String csNamespace = null;
String javaDir = null;
String javaPackage = "";
String pythonFile = null;
String prettyFile = null;
String typeinfoFile = null;
for (int i = 0 ; i < args.length ; i++) {
if (fileName == null ||
args[i].equals("-help") ||
args[i].equals("-h") ||
args[i].equals("--help")) {
print_help();
System.exit(0);
} else if (args[i].equals("-v")) {
verbose=true;
} else if (args[i].equals("-C")) {
cFile = coreName + ".c";
hFile = coreName + ".h";
} else if (args[i].startsWith("--cinclude=")) {
cIncludes.add(args[i].substring(11));
} else if (args[i].startsWith("--cprefix=")) {
cPrefix = args[i].substring(10);
} else if (args[i].startsWith("--c=")) {
cFile = args[i].substring(4);
} else if (args[i].startsWith("--h=")) {
hFile = args[i].substring(4);
} else if (args[i].equals("--cs")) {
csFile = coreName + ".cs";
} else if (args[i].startsWith("--cs=")) {
csFile = args[i].substring(5);
} else if (args[i].startsWith("--csnamespace=")) {
csNamespace = args[i].substring(14);
} else if (args[i].startsWith("--java=")) {
javaDir = args[i].substring(7);
} else if (args[i].startsWith("--javapackage=")) {
javaPackage = args[i].substring(14);
} else if (args[i].equals("-P")) {
pythonFile = coreName + ".py";
} else if (args[i].startsWith("--python=")) {
pythonFile = args[i].substring(9);
} else if (args[i].startsWith("--pretty=")) {
prettyFile = args[i].substring(9);
} else if (args[i].startsWith("--typeinfo=")) {
typeinfoFile = args[i].substring(11);
} else if (i == args.length - 1) {
fileName = args[i];
} else {
System.err.println(" Unknown argument " + args[i]);
print_help();
System.exit(2);
}
}
if (fileName == null) {
print_help();
System.exit(1);
} else {
Program ast = null;
try {
// Check for errors
LabCommScanner scanner = new LabCommScanner(new FileReader(fileName));
LabCommParser parser = new LabCommParser();
Program p = (Program)parser.parse(scanner);
Collection errors = new LinkedList();
p.errorCheck(errors);
if (errors.isEmpty()) {
ast = p;
} else {
for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
String s = (String)iter.next();
System.out.println(s);
}
}
} catch (FileNotFoundException e) {
System.err.println("Could not find file: " + fileName);
} catch (IOException e) {
System.err.println("IOException: " + fileName + " " + e);
} catch (beaver.Parser.Exception e) {
System.err.println(e.getMessage());
}
if (ast != null) {
Vector hIncludes = new Vector(cIncludes);
if (hFile != null) {
cIncludes.add(hFile);
}
boolean prettyOnStdout = true;
if (cFile != null) {
if (verbose) { System.err.println("Generating C: " + cFile); }
genC(ast, cFile, cIncludes, coreName, cPrefix);
prettyOnStdout = false;
}
if (hFile != null) {
if (verbose) { System.err.println("Generating H: " + hFile); }
genH(ast, hFile, hIncludes, coreName, cPrefix);
prettyOnStdout = false;
}
if (csFile != null) {
if (verbose) { System.err.println("Generating C#: " + csFile); }
genCS(ast, csFile, csNamespace);
prettyOnStdout = false;
}
if (javaDir != null) {
if (verbose) { System.err.println("Generating Java: " + javaDir); }
genJava(ast, javaDir, javaPackage);
prettyOnStdout = false;
}
if (pythonFile != null) {
if (verbose) {
System.err.println("Generating Python: " + pythonFile);
}
genPython(ast, pythonFile, prefix);
prettyOnStdout = false;
}
if (prettyFile != null) {
if (verbose) {
System.err.println("Generating Pretty: " + prettyFile);
}
try {
FileOutputStream f = new FileOutputStream(prettyFile);
PrintStream out = new PrintStream(f);
ast.pp(out);
out.close();
prettyOnStdout = false;
} catch (IOException e) {
System.err.println("IOException: " + prettyFile + " " + e);
}
}
if (typeinfoFile != null) {
if (verbose) {
System.err.println("Generating TypeInfo: " + typeinfoFile);
}
try {
FileOutputStream f = new FileOutputStream(typeinfoFile);
PrintStream out = new PrintStream(f);
ast.C_info(out, cPrefix);
ast.Java_info(out);
ast.CS_info(out, csNamespace);
prettyOnStdout = false;
} catch (IOException e) {
System.err.println("IOException: " + typeinfoFile + " " + e);
}
}
if (prettyOnStdout) {
ast.pp(System.out);
}
}
}
}
private static void genH(Program p, String hName,
Vector cIncludes, String coreName, String prefix) {
try {
FileOutputStream f;
PrintStream out;
f = new FileOutputStream(hName);
out = new PrintStream(f);
p.C_genH(out, cIncludes, coreName, prefix);
out.close();
} catch (IOException e) {
System.err.println("IOException: " + hName + " " + e);
}
}
private static void genC(Program p, String cName,
Vector cIncludes, String coreName, String prefix) {
try {
FileOutputStream f;
PrintStream out;
f = new FileOutputStream(cName);
out = new PrintStream(f);
p.C_genC(out, cIncludes, coreName, prefix);
out.close();
} catch (IOException e) {
System.err.println("IOException: " + cName + " " + e);
}
}
private static void genCS(Program p, String csName, String csNamespace) {
try {
p.CS_gen(csName, csNamespace);
} catch (IOException e) {
System.err.println("IOException: " + csName + " " +
csNamespace + " " + e);
}
}
private static void genJava(Program p, String dirName, String packageName) {
try {
p.J_gen(dirName, packageName);
} catch (IOException e) {
System.err.println("IOException: " + dirName + " " +
packageName + " " + e);
}
}
private static void genPython(Program p, String filename, String prefix) {
try {
FileOutputStream f;
PrintStream out;
f = new FileOutputStream(filename);
out = new PrintStream(f);
p.Python_gen(out, prefix);
out.close();
} catch (IOException e) {
System.err.println("IOException: " + filename + " " + e);
}
}
}
aspect LabCommTokens {
public static final int ASTNode.LABCOMM_TYPEDEF = 0x01;
public static final int ASTNode.LABCOMM_SAMPLE = 0x02;
public static final int ASTNode.LABCOMM_ARRAY = 0x10;
public static final int ASTNode.LABCOMM_STRUCT = 0x11;
public static final int ASTNode.LABCOMM_BOOLEAN = 0x20;
public static final int ASTNode.LABCOMM_BYTE = 0x21;
public static final int ASTNode.LABCOMM_SHORT = 0x22;
public static final int ASTNode.LABCOMM_INT = 0x23;
public static final int ASTNode.LABCOMM_LONG = 0x24;
public static final int ASTNode.LABCOMM_FLOAT = 0x25;
public static final int ASTNode.LABCOMM_DOUBLE = 0x26;
public static final int ASTNode.LABCOMM_STRING = 0x27;
}
\ No newline at end of file
.PHONY: all
all: ant-all
.PHONY: test
test: ant-test
.PHONY: clean
clean: ant-clean
rm -f *~
.PHONY: distclean
distclean: clean ant-distclean
.PHONY: ant-%
ant-%:
ant $*
aspect Python_CodeGenEnv {
// Environment wrapper for Python code generation
// handles qualid nesting, indentation, file writing and
// prefix propagation
public class Python_env {
final private class Python_printer {
private boolean newline = true;
private PrintStream out;
public Python_printer(PrintStream out) {
this.out = out;
}
public void print(Python_env env, String s) {
if (newline) {
newline = false;
for (int i = 0 ; i < env.indent ; i++) {
out.print(" ");
}
}
out.print(s);
}
public void println(Python_env env, String s) {
print(env, s);
out.println();
newline = true;
}
public void println(Python_env env) {
out.println();
newline = true;
}
}
private int indent;
private Python_printer printer;
public Python_env(PrintStream out) {
this.indent = 0;
this.printer = new Python_printer(out);
}
public void indent() {
indent++;
}
public void unindent() {
indent--;
}
public void print(String s) {
printer.print(this, s);
}
public void println(String s) {
printer.println(this, s);
}
public void println() {
printer.println(this);
}
}
}
aspect Python_CodeGen {
public void Program.Python_gen(PrintStream out, String baseName) {
Python_env env = new Python_env(out);
env.println("#!/usr/bin/python");
env.println("# Auto generated " + baseName);
env.println();
env.println("import labcomm");
env.println();
Python_genTypes(env);
}
}
aspect PythonTypes {
public void Program.Python_genTypes(Python_env env) {
for (int i = 0 ; i < getNumDecl() ; i++) {
env.println("class " + getDecl(i).getName() + "(object):");
env.indent();
getDecl(i).Python_genSignature(env);
env.unindent();
env.println();
}
}
public void Decl.Python_genSignature(Python_env env) {
throw new Error(this.getClass().getName() +
".Python_genSignature(Python_env env)" +
" not declared");
}
public void TypeDecl.Python_genSignature(Python_env env) {
env.println("no_signature = labcomm.typedef('" + getName() + "',");
env.indent();
getType().Python_genSignature(env);
env.unindent();
env.println(")");
}
public void SampleDecl.Python_genSignature(Python_env env) {
env.println("signature = labcomm.sample('" + getName() + "', ");
env.indent();
getType().Python_genSignature(env);
env.unindent();
env.println(")");
}
public void UserType.Python_genSignature(Python_env env) {
lookupType(getName()).getType().Python_genSignature(env);
}
public void Type.Python_genSignature(Python_env env) {
throw new Error(this.getClass().getName() +
".Python_genSignature(Python_env env)" +
" not declared");
}
public void PrimType.Python_genSignature(Python_env env) {
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.print("labcomm.BOOLEAN()"); } break;
case LABCOMM_BYTE: { env.print("labcomm.BYTE()"); } break;
case LABCOMM_SHORT: { env.print("labcomm.SHORT()"); } break;
case LABCOMM_INT: { env.print("labcomm.INTEGER()"); } break;
case LABCOMM_LONG: { env.print("labcomm.LONG()"); } break;
case LABCOMM_FLOAT: { env.print("labcomm.FLOAT()"); } break;
case LABCOMM_DOUBLE: { env.print("labcomm.DOUBLE()"); } break;
case LABCOMM_STRING: { env.print("labcomm.STRING()"); } break;
}
}
public void ArrayType.Python_genSignature(Python_env env) {
env.print("labcomm.array([");
for (int i = 0 ; i < getNumExp() ; i++) {
if (i > 0) { env.print(", "); }
env.print(getExp(i).Python_getValue());
}
env.println("],");
env.indent();
getType().Python_genSignature(env);
env.print(")");
env.unindent();
}
public void StructType.Python_genSignature(Python_env env) {
env.println("labcomm.struct([");
env.indent();
for (int i = 0 ; i < getNumField() ; i++) {
if (i > 0) { env.println(","); }
getField(i).Python_genSignature(env);
}
env.print("])");
env.unindent();
}
public void VoidType.Python_genSignature(Python_env env) {
env.println("labcomm.struct([])");
env.unindent();
}
public void Field.Python_genSignature(Python_env env) {
env.print("('" + getName() + "', ");
getType().Python_genSignature(env);
env.print(")");
}
public String Exp.Python_getValue() {
throw new Error(this.getClass().getName() +
".Python_getValue()" +
" not declared");
}
public String IntegerLiteral.Python_getValue() {
return getValue();
}
public String VariableSize.Python_getValue() {
return "0";
}
}
\ No newline at end of file
......@@ -6,101 +6,223 @@
gen - generates java files
cleanGen - removes all generated files and their class files
-->
<project name="LabComm" default="build" basedir=".">
<!-- "package" is the directory where generated files will be stored -->
<property name="package" value="AST"/>
<project name="LabComm" default="all" basedir=".">
<!-- "tools" is the directory where generators and libraries are located. -->
<property name="tools" value="tools"/>
<!-- "test" is the directory where tests are located. -->
<property name="test" value="../test"/>
<!-- "jflex" is an ant task class for the scanner generator in JFlex.jar -->
<taskdef name="jflex" classname="JFlex.anttask.JFlexTask" classpath="tools/JFlex.jar"/>
<!-- "beaver" is an ant task class for the parser generator in beaver.jar -->
<taskdef name="beaver" classname="beaver.comp.run.AntTask" classpath="tools/beaver.jar"/>
<taskdef name="beaver" classname="beaver.comp.run.AntTask" classpath="tools/beaver-ant.jar"/>
<!-- "jastadd" is an ant task class in jastadd2.jar -->
<taskdef name="jastadd" classname="jastadd.JastAddTask"
classpath="tools/jastadd2.jar"/>
classpath="tools/jastadd2.jar"/>
<target name="jastadd.cu">
<uptodate property="jastadd.u">
<srcfiles dir='.'>
<include name="${version}/*.ast"/>
<include name="${version}/*.jrag"/>
<include name="${version}/*.jadd"/>
</srcfiles>
<mapper type="merge"
to="${outdir}/${package_path}/jastadd.uptodate"/>
</uptodate>
</target>
<!-- compile sources -->
<target name="build" depends="gen">
<javac debug="true" nowarn="true" srcdir="." includes="**/*.java" excludes="test/** examples/**" classpath=".:${tools}/beaver-rt.jar:${tools}/junit.jar"
fork="true" memoryMaximumSize="128M"/>
<target name="jastadd" depends="jastadd.cu" unless="jastadd.u">
<echo message = "Running JastAdd"/>
<jastadd package="${package}" rewrite="true" beaver="true"
novisitcheck="true" lazyMaps="true" outdir="${outdir}">
<fileset dir=".">
<include name="${version}/*.ast"/>
<include name="${version}/*.jrag"/>
<include name="${version}/*.jadd"/>
</fileset>
</jastadd>
<touch file="${outdir}/${package_path}/jastadd.uptodate"/>
</target>
<!-- generate compiler source files -->
<target name="gen">
<!-- create AST node types and weave aspect modules -->
<echo message = "Running JastAdd"/>
<jastadd package="${package}" rewrite="true" beaver="true" novisitcheck="true" lazyMaps="true" outdir="${basedir}">
<fileset dir=".">
<include name="**/*.ast"/>
<include name="**/*.jrag"/>
<include name="**/*.jadd"/>
</fileset>
</jastadd>
<!-- generate the scanner -->
<echo message = "Running jflex"/>
<jflex file="LabCommScanner.flex" outdir="AST" nobak="yes"/>
<!-- generate the parser phase 1, create a full .lalr specification from fragments-->
<echo message = "Running parser phase 1"/>
<concat destfile="AST/LabCommParser.all" binary="true">
<fileset dir=".">
<include name="*.parser"/>
</fileset>
</concat>
<!-- generate the parser phase 2, translating .lalr to .beaver -->
<java fork="true" dir="${basedir}" classpath="${tools}/proj.jar:${tools}/beaver-rt.jar" classname="Main">
<arg line="AST/LabCommParser.all AST/LabCommParser.beaver"/>
</java>
<!-- generate the parser phase 3, translating .beaver to .java -->
<beaver file="AST/LabCommParser.beaver" terminalNames="yes" compress="yes" useSwitch="yes"/>
</target>
<!-- compile sources -->
<target name="test" depends="jar">
<echo message = "Running tests"/>
<exec executable="./run" dir="../test">
<env key="PYTHONPATH" value="../lib/python"/>
<!--arg value="hej"/-->
</exec>
<target name="scanner.cu">
<uptodate property="scanner.u">
<srcfiles dir='.'>
<include name="${version}/LabCommScanner.flex"/>
<!--include name="${tools}/JFlex.jar"/-->
</srcfiles>
<mapper type="merge"
to="${outdir}/${package_path}/LabCommScanner.java"/>
</uptodate>
</target>
<target name="scanner" depends="scanner.cu" unless="scanner.u">
<echo message = "Generating scanner ${version}"/>
<echo message = "Running jflex -> ${package} ${outdir}/${package_path}"/>
<jflex file="${version}/LabCommScanner.flex"
outdir="${outdir}/${package_path}" nobak="yes"/>
</target>
<!-- remove generated source files and .class files -->
<target name="clean" depends="cleanGen">
<!-- delete all .class files recursively -->
<delete>
<fileset dir="." includes="**/*.class"/>
<fileset dir="." includes="labComm.jar"/>
</delete>
<target name="parser.1.cu">
<uptodate property="parser.1.u">
<srcfiles dir='.'>
<include name="${version}/*.parser"/>
</srcfiles>
<mapper type="merge"
to="${outdir}/${package_path}/LabCommParser.all"/>
</uptodate>
</target>
<target name="parser.1" depends="parser.1.cu" unless="parser.1.u">
<!-- generate the parser phase 1, create a full .lalr specification
from fragments-->
<echo message = "Joining parser fragments"/>
<concat destfile="${outdir}/${package_path}/LabCommParser.all" binary="true">
<fileset dir=".">
<include name="${version}/*.parser"/>
</fileset>
</concat>
</target>
<!-- remove generated source files and their .class files -->
<target name="cleanGen">
<delete dir="${package}"/>
<target name="parser.2.cu">
<uptodate property="parser.2.u">
<srcfiles dir='.'>
<include name="${outdir}/${package_path}/LabCommParser.all"/>
</srcfiles>
<mapper type="merge"
to="${outdir}/${package_path}/LabCommParser.beaver"/>
</uptodate>
</target>
<target name="parser.2" depends="parser.1, parser.2.cu" unless="parser.2.u">
<!-- generate the parser phase 2, translating .lalr to .beaver -->
<echo message = "translating .lalr to .beaver"/>
<java fork="true" dir="${basedir}"
classpath="${tools}/proj.jar:${tools}/beaver-rt.jar" classname="Main">
<arg line="${outdir}/${package_path}/LabCommParser.all
${outdir}/${package_path}/LabCommParser.beaver"/>
</java>
</target>
<target name="parser.3.cu">
<uptodate property="parser.3.u">
<srcfiles dir='.'>
<include name="${outdir}/${package_path}/LabCommParser.beaver"/>
</srcfiles>
<mapper type="merge"
to="${outdir}/${package_path}/LabCommParser.java"/>
</uptodate>
</target>
<target name="parser.3" depends="parser.2, parser.3.cu" unless="parser.3.u">
<echo message = "translating .beaver to .java"/>
<beaver file="${outdir}/${package_path}/LabCommParser.beaver"
terminalNames="yes" compress="yes" useSwitch="yes"/>
</target>
<target name="all.version" depends="jastadd, scanner, parser.3">
</target>
<target name="jar" depends="build">
<jar destfile="labComm.jar">
<fileset dir="." includes="LabComm*.class"/>
<fileset dir="." includes="AST/*.class"/>
<target name="compile.cu">
<uptodate property="compile.u">
<srcfiles dir='.'>
<include name="*.java"/>
<include name="2014/*.java"/>
<include name="${outdir}/**/*.java"/>
</srcfiles>
<mapper type="merge"
to="${outdir}/compile.uptodate"/>
</uptodate>
</target>
<target name="compile" depends="compile.cu" unless="compile.u">
<echo message = "compiling"/>
<javac debug="true" srcdir="." destdir="${outdir}"
includes="*.java 2014/*.java gen/**/*.java"
classpath="${outdir}:${tools}/beaver-rt.jar:${tools}/junit.jar"
includeantruntime="false"
fork="true" memoryMaximumSize="128M">
<!--compilerarg value="-Xlint"/-->
</javac>
<touch file="${outdir}/compile.uptodate"/>
</target>
<target name="jar.version.cu">
<uptodate property="jar.version.u">
<srcfiles dir=".">
<include name="${outdir}/${package_path}/*.class"/>
</srcfiles>
<mapper type="merge"
to="labcomm${version}_compiler.jar"/>
</uptodate>
</target>
<target name="jar.version" depends="jar.version.cu" unless="jar.version.u">
<echo message = "Generating labcomm${version}_compiler.jar"/>
<jar destfile="labcomm${version}_compiler.jar">
<fileset dir="${outdir}"
includes="${package_path}/*.class"/>
<zipfileset src="tools/beaver-rt.jar" includes="beaver/*.class"/>
<manifest>
<attribute name="Main-Class" value="LabComm"/>
<attribute name="Main-Class"
value="${package}.LabComm"/>
</manifest>
</jar>
</target>
<target name="do.version">
<!-- Wrapper that sets up package and package_path based on ${version} -->
<local name="package"/>
<local name="package_path"/>
<property name="package" value="se.lth.control.labcomm${version}.compiler"/>
<loadresource property="package_path">
<propertyresource name="package"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="." to="/"/>
</tokenfilter>
</filterchain>
</loadresource>
<echo>${do} ${version} ${outdir}</echo>
<mkdir dir="${outdir}"/>
<antcall target="${do}">
<param name="version" value="${version}"/>
<param name="outdir" value="${outdir}"/>
<param name="package" value="${package}"/>
<param name="package_path" value="${package_path}"/>
</antcall>
</target>
<target name="all">
<antcall target="do.version">
<param name="do" value="all.version"/>
<param name="version" value="2014"/>
<param name="outdir" value="gen"/>
</antcall>
<antcall target="compile">
<param name="outdir" value="gen"/>
</antcall>
<antcall target="do.version">
<param name="do" value="jar.version"/>
<param name="version" value="2014"/>
<param name="outdir" value="gen"/>
</antcall>
</target>
<target name="clean">
<delete dir="gen"/>
</target>
<target name="distclean" depends="clean">
<delete>
<fileset dir="." includes="labcomm*_compiler.jar"/>
</delete>
</target>
<target name="test">
<echo>No tests defined yet</echo>
</target>
</project>
*** CS_CodeGen.old 2010-06-03 13:46:00.000000000 +0200
--- CS_CodeGen.jrag 2010-06-03 14:05:00.000000000 +0200
***************
*** 419,424 ****
--- 419,426 ----
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = getExp(i).CS_emitEncoder(env,
name + ".GetLength(" + i + ")");
+ env.println("{");
+ env.indent();
env.println("int i_" + (baseDepth + i) + "_max = " + limit + ";");
}
String index = null;
***************
*** 434,439 ****
--- 436,443 ----
for (int i = 0 ; i < getNumExp() ; i++) {
env.print_for_end();
}
+ env.unindent();
+ env.println("}");
}
public String Exp.CS_emitEncoder(CS_env env, String name) {
***************
*** 725,730 ****
--- 729,735 ----
public void PrimType.CS_emitType(CS_env env) {
switch (getToken()) {
case LABCOMM_STRING: { env.print("String"); } break;
+ case LABCOMM_BOOLEAN: { env.print("bool"); } break;
default: { env.print(getName()); } break;
}
}
*** Java_CodeGen.old 2010-05-31 10:13:44.000000000 +0200
--- Java_CodeGen.jrag 2010-05-31 10:22:55.000000000 +0200
***************
*** 445,450 ****
--- 445,452 ----
String prefix = "";
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = getExp(i).Java_emitEncoder(env, name + prefix);
+ env.println("{");
+ env.indent();
env.println("int i_" + (baseDepth + i) + "_max = " + limit + ";");
prefix = prefix + "[0]";
}
***************
*** 456,461 ****
--- 458,465 ----
for (int i = 0 ; i < getNumExp() ; i++) {
env.print_for_end();
}
+ env.unindent();
+ env.println("}");
}
public String Exp.Java_emitEncoder(Java_env env, String name) {
#!/bin/sh
java -jar /lib/labcomm2014_compiler.jar "$@"
File added