Select Git revision
C_CodeGen.jrag
Forked from
Anders Blomdell / LabComm
544 commits behind the upstream repository.
-
Sven Robertz authoredSven Robertz authored
C_CodeGen.jrag 29.02 KiB
import java.util.Vector;
aspect C_CodeGenEnv {
// Environment wrapper for C-code generation
// handles qualid nesting, indentation, file writing and
// prefix propagation
public class C_env {
final private class C_printer {
private boolean newline = true;
private PrintStream out;
public C_printer(PrintStream out) {
this.out = out;
}
public void print(C_env env, String s) {
if (newline) {
newline = false;
for (int i = 0 ; i < env.indent ; i++) {
out.print(" ");
}
}
out.print(s);
}
public void println(C_env env, String s) {
print(env, s);
out.println();
newline = true;
}
}
public final String qualid;
public final String lcName;
public final String rawPrefix;
public final String prefix;
private int indent;
public final int depth;
private C_printer printer;
private C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer) {
this.qualid = qualid;
this.lcName = lcName;
this.rawPrefix = rawPrefix;
this.prefix = rawPrefix + "_";
this.indent = indent;
this.depth = depth;
this.printer = printer;
}
public C_env(String qualid, String lcName, String rawPrefix,
PrintStream out) {
this.qualid = qualid;
this.lcName = lcName;
this.rawPrefix = rawPrefix;
this.prefix = rawPrefix + "_";
this.depth = 0;
this.indent = 0;
this.printer = new C_printer(out);
}
public C_env nestArray(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth + 1, printer);
}
public C_env nestStruct(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth, printer);
}
public void indent() {
indent++;
}
public void unindent() {
indent--;
}
public String prefix() {
return rawPrefix;
}
public void print(String s) {
printer.print(this, s);
}
public void println(String s) {
printer.println(this, s);
}
}
public C_env ArrayType.C_Nest(C_env env) {
throw new Error(this.getClass().getName() +
".C_Nest(C_env env)" +
" not declared");
}
public C_env FixedArrayType.C_Nest(C_env env) {
String index = ".a";
for (int i = 0 ; i < getNumExp() ; i++) {
index += "[i_" + env.depth + "_" + i + "]";
}
return env.nestArray(index);
}
public C_env VariableArrayType.C_Nest(C_env env) {
return env.nestArray(".a[i_" + env.depth + "]");
}
}
aspect C_IsDynamic {
// Determine if a type has dynamically allocated data
syn boolean Decl.C_isDynamic() = getType().C_isDynamic();
syn boolean Type.C_isDynamic() = false;
syn boolean PrimType.C_isDynamic() = getToken() == LABCOMM_STRING;
syn boolean UserType.C_isDynamic() =
lookupType(getName()).getType().C_isDynamic();
syn boolean StructType.C_isDynamic() {
for (int i = 0 ; i < getNumField() ; i++) {
if (getField(i).getType().C_isDynamic()) {
return true;
}
}
return false;
}
syn boolean FixedArrayType.C_isDynamic() = getType().C_isDynamic();
syn boolean VariableArrayType.C_isDynamic() = true;
}
aspect C_CodeGen {
public void Program.C_genH(PrintStream out, Vector includes,
String lcName, String prefix) {
C_env env = new C_env("", lcName, prefix, out);
// Hackish prettyprint preamble
out.println("/* LabComm declarations:");
pp(out);
out.println("*/");
env.println("");
env.println("");
env.println("#ifndef __LABCOMM_" + env.lcName + "_H__");
env.println("#define __LABCOMM_" + env.lcName + "_H__");
env.println("");
// Include
env.println("#include \"labcomm.h\"");
for (int i = 0 ; i < includes.size() ; i++) {
env.println("#include \"" + includes.get(i) + "\"");
}
env.println("");
C_emitH(env);
env.println("#endif");
}
public void Program.C_genC(PrintStream out, Vector includes,
String lcName, String prefix) {
C_env env = new C_env("", lcName, prefix, out);
// Include
env.println("#include \"labcomm.h\"");
env.println("#include \"labcomm_private.h\"");
for (int i = 0 ; i < includes.size() ; i++) {
env.println("#include \"" + includes.get(i) + "\"");
}
env.println("");
// Method Implementations
C_emitC(env);
}
public void Program.C_emitH(C_env env) {
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitType(env);
// getDecl(i).C_emitSignatureDeclaration(env);
getDecl(i).C_emitDecoderRegisterDeclaration(env);
getDecl(i).C_emitEncoderDeclaration(env);
getDecl(i).C_emitSizeofDeclaration(env);
env.println("");
}
C_emitForAll(env);
}
public void Program.C_emitC(C_env env) {
C_emitSignature(env);
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitDecoder(env);
getDecl(i).C_emitDecoderRegisterHandler(env);
getDecl(i).C_emitEncoder(env);
getDecl(i).C_emitEncoderRegisterHandler(env);
getDecl(i).C_emitSizeof(env);
}
}
}
aspect C_Common {
public void ArrayType.C_emitLoopVariables(C_env env) {
for (int i = 0 ; i < getNumExp() ; i++) {
env.println("int i_" + env.depth + "_" + i + ";");
}
}
}
aspect C_Type {
public void Decl.C_emitType(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitType(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitType(C_env env) {
env.println("#ifndef PREDEFINED_" + env.prefix + getName());
env.print("typedef ");
getType().C_emitType(env, env.prefix + getName());
env.println(";");
env.println("#endif");
}
public void SampleDecl.C_emitType(C_env env) {
env.println("#ifndef PREDEFINED_" + env.prefix + getName());
env.print("typedef ");
getType().C_emitType(env, env.prefix + getName());
env.println(";");
env.println("#endif");
}
public void Type.C_emitType(C_env env, String name) {
throw new Error(this.getClass().getName() +
".C_emitType(C_env env, String name)" +
" not declared");
}
public void VoidType.C_emitType(C_env env, String name) {
env.print("char " + name);
}
public void PrimType.C_emitType(C_env env, String name) {
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.print("unsigned char"); } break;
case LABCOMM_BYTE: { env.print("unsigned char"); } break;
case LABCOMM_STRING: { env.print("char*"); } break;
case LABCOMM_LONG: { env.print("long long"); } break;
default: { env.print(getName()); } break;
}
env.print(" " + name);
}
public void UserType.C_emitType(C_env env, String name) {
env.print(env.prefix + getName() + " " + name);
}
public void StructType.C_emitType(C_env env, String name) {
env.println("struct {");
env.indent();
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitType(env);
env.println(";");
}
env.unindent();
env.print("} " + name);
}
public void Field.C_emitType(C_env env) {
getType().C_emitType(env, getName());
}
public void FixedArrayType.C_emitType(C_env env, String name) {
env.println("struct {");
env.indent();
StringBuffer index = new StringBuffer("a");
for (int i = 0 ; i < getNumExp() ; i++) {
index.append("[" + getExp(i).C_getValue() + "]");
}
getType().C_emitType(env, index.toString());
env.println(";");
env.unindent();
env.print("} " + name);
}
public void VariableArrayType.C_emitType(C_env env, String name) {
env.println("struct {");
env.indent();
for (int i = 0 ; i < getNumExp() ; i++) {
if (getExp(i) instanceof VariableSize) {
env.println("int n_" + i + ";");
} else {
env.println("// n_" + i + "=" + getExp(i).C_getValue());
}
}
getType().C_emitType(env, "*a");
env.println(";");
env.unindent();
env.print("} " + name);
}
public String Exp.C_getValue() {
throw new Error(this.getClass().getName() +
".C_getValue()" +
" not declared");
}
public String IntegerLiteral.C_getValue() {
return getValue();
}
}
aspect C_Declarations {
public void Decl.C_emitDecoderRegisterDeclaration(C_env env) {
}
public void SampleDecl.C_emitDecoderRegisterDeclaration(C_env env) {
env.println("void labcomm_decoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_decoder *d,");
env.println("void (*handler)(");
env.indent();
env.println(env.prefix + getName() + " *v,");
env.println("void *context");
env.unindent();
env.println("),");
env.println("void *context");
env.unindent();
env.println(");");
}
public void Decl.C_emitEncoderDeclaration(C_env env) {
}
public void SampleDecl.C_emitEncoderDeclaration(C_env env) {
env.println("void labcomm_encoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e);");
env.unindent();
env.println("void labcomm_encode_" + env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e,");
env.println(env.prefix + getName() + " *v");
env.unindent();
env.println(");");
}
}
aspect C_Limit {
public String Exp.C_getLimit(C_env env, int i) {
throw new Error(this.getClass().getName() +
".C_emitDecoderLimit(C_env env, int i)" +
" not declared");
}
public String IntegerLiteral.C_getLimit(C_env env, int i) {
return getValue();
}
public String VariableSize.C_getLimit(C_env env, int i) {
return env.qualid + ".n_" + i;
}
}
aspect C_Index {
public void ArrayType.C_emitCalcIndex(C_env env) {
}
public void VariableArrayType.C_emitCalcIndex(C_env env) {
env.print("int i_" + env.depth + " = ");
String i_prefix = "i_" + env.depth + "_";
String expr = i_prefix + "0";
for (int i = 1 ; i < getNumExp() ; i++) {
expr = "(" + expr + ") * " +
getExp(i).C_getLimit(env, i) + " + " +
i_prefix + i;
}
env.println(expr + ";");
}
}
aspect C_Decoder {
public void Decl.C_emitDecoder(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitDecoder(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitDecoder(C_env env) {
}
public void SampleDecl.C_emitDecoder(C_env env) {
env = env.nestStruct("v");
env.println("static void decode_" + getName() + "(");
env.indent();
env.println("labcomm_decoder_t *d,");
env.println("void (*handle)(");
env.indent();
env.println(env.prefix + getName() + " *v,");
env.println("void *context");
env.unindent();
env.println("),");
env.println("void *context");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println(env.prefix + getName() + " v;");
getType().C_emitDecoder(env);
env.println("handle(&v, context);");
if (C_isDynamic()) {
env.println("{");
env.indent();
getType().C_emitDecoderDeallocation(env);
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
public void Type.C_emitDecoder(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitDecoder(C_env env)" +
" not declared");
}
public void VoidType.C_emitDecoder(C_env env) {
}
public void PrimType.C_emitDecoder(C_env env) {
env.println(env.qualid + " = labcomm_decode_" + getName() + "(d);");
}
public void UserType.C_emitDecoder(C_env env) {
lookupType(getName()).getType().C_emitDecoder(env);
}
public void StructType.C_emitDecoder(C_env env) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitDecoder(env);
}
}
public void ArrayType.C_emitDecoder(C_env env) {
C_emitDecoderDecodeLimit(env);
C_emitDecoderArrayAllocate(env);
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitDecoder(C_Nest(env));
for (int i = getNumExp() - 1 ; i >= 0 ; i--) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
public void Field.C_emitDecoder(C_env env) {
getType().C_emitDecoder(env.nestStruct("." + getName()));
}
public void Exp.C_emitDecoderDecodeLimit(C_env env, int i) {
}
public void VariableSize.C_emitDecoderDecodeLimit(C_env env, int i) {
//env.println(env.qualid + ".n_" + i + " = labcomm_decode_int(d);");
env.println(env.qualid + ".n_" + i + " = labcomm_decode_packed32(d);");
}
public void ArrayType.C_emitDecoderDecodeLimit(C_env env) {
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_emitDecoderDecodeLimit(env, i);
}
}
public void ArrayType.C_emitDecoderArrayAllocate(C_env env) {
}
public void VariableArrayType.C_emitDecoderArrayAllocate(C_env env) {
env.print(env.qualid + ".a = malloc(sizeof(" + env.qualid + ".a[0])");
for (int i = 0 ; i < getNumExp() ; i++) {
env.print(" * " + getExp(i).C_getLimit(env, i));
}
env.println(");");
}
// Code for deallocation of dynamically allocated data
public void Type.C_emitDecoderDeallocation(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitDecoderDeallocation(C_env env)" +
" not declared");
}
public void PrimType.C_emitDecoderDeallocation(C_env env) {
if (C_isDynamic()) {
env.println("free(" + env.qualid + ");");
}
}
public void UserType.C_emitDecoderDeallocation(C_env env) {
if (C_isDynamic()) {
lookupType(getName()).getType().C_emitDecoderDeallocation(env);
}
}
public void StructType.C_emitDecoderDeallocation(C_env env) {
if (C_isDynamic()) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitDecoderDeallocation(env);
}
}
}
public void ArrayType.C_emitDecoderDeallocation(C_env env) {
if (getType().C_isDynamic()) {
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitDecoderDeallocation(C_Nest(env));
for (int i = 0 ; i < getNumExp() ; i++) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
}
public void VariableArrayType.C_emitDecoderDeallocation(C_env env) {
super.C_emitDecoderDeallocation(env);
env.println("free(" + env.qualid + ".a);");
}
public void Field.C_emitDecoderDeallocation(C_env env) {
getType().C_emitDecoderDeallocation(env.nestStruct("." + getName()));
}
public void Decl.C_emitDecoderRegisterHandler(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitDecoderRegisterHandler(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitDecoderRegisterHandler(C_env env) {
}
public void SampleDecl.C_emitDecoderRegisterHandler(C_env env) {
env.println("void labcomm_decoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_decoder *d,");
env.println("void (*handler)(");
env.indent();
env.println(env.prefix + getName() + " *v,");
env.println("void *context");
env.unindent();
env.println("),");
env.println("void *context");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_decoder_register(");
env.indent();
env.println("d,");
env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_decoder_typecast_t)decode_" + getName() + ",");
env.println("(labcomm_handler_typecast_t)handler,");
env.println("context");
env.unindent();
env.println(");");
env.unindent();
env.println("}");
}
}
aspect C_Encoder {
public void Decl.C_emitEncoder(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitEncoder()" +
" not declared");
}
public void TypeDecl.C_emitEncoder(C_env env) {
}
public void SampleDecl.C_emitEncoder(C_env env) {
env = env.nestStruct("(*v)");
env.println("static void encode_" + getName() + "(");
env.indent();
env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println("e->writer.write(&e->writer, labcomm_writer_start);");
env.println("labcomm_encode_type_index(e, &labcomm_signature_" +
env.prefix + getName() + ");");
env.println("{");
env.indent();
getType().C_emitEncoder(env);
env.unindent();
env.println("}");
env.println("e->writer.write(&e->writer, labcomm_writer_end);");
env.unindent();
env.println("}");
// Typesafe encode wrapper
env.println("void labcomm_encode_" + env.prefix + getName() + "(");
env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_encode(e, &labcomm_signature_" +
env.prefix + getName() + ", v);");
env.unindent();
env.println("}");
}
public void Type.C_emitEncoder(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitEncoder(C_env env)" +
" not declared");
}
public void VoidType.C_emitEncoder(C_env env) {
}
public void PrimType.C_emitEncoder(C_env env) {
env.println("labcomm_encode_" + getName() + "(e, " + env.qualid + ");");
}
public void UserType.C_emitEncoder(C_env env) {
lookupType(getName()).getType().C_emitEncoder(env);
}
public void StructType.C_emitEncoder(C_env env) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitEncoder(env);
}
}
public void ArrayType.C_emitEncoder(C_env env) {
C_emitEncoderEncodeLimit(env);
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitEncoder(C_Nest(env));
for (int i = getNumExp() - 1 ; i >= 0 ; i--) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
public void Field.C_emitEncoder(C_env env) {
getType().C_emitEncoder(env.nestStruct("." + getName()));
}
public void Exp.C_emitEncoderEncodeLimit(C_env env, int i) {
}
public void VariableSize.C_emitEncoderEncodeLimit(C_env env, int i) {
//env.println("labcomm_encode_int(e, " + env.qualid + ".n_" + i + ");");
env.println("labcomm_encode_packed32(e, " + env.qualid + ".n_" + i + ");");
}
public void ArrayType.C_emitEncoderEncodeLimit(C_env env) {
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_emitEncoderEncodeLimit(env, i);
}
}
public void Decl.C_emitEncoderRegisterHandler(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitEncoderRegisterHandler(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitEncoderRegisterHandler(C_env env) {
}
public void SampleDecl.C_emitEncoderRegisterHandler(C_env env) {
env.println("void labcomm_encoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_encoder_register(");
env.indent();
env.println("e,");
env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_encode_typecast_t)encode_" + getName());
env.unindent();
env.println(");");
env.unindent();
env.println("}");
}
}
aspect C_Signature {
public void ASTNode.C_emitSignature(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitSignature(C_env env)" +
" not declared");
}
public void Program.C_emitSignature(C_env env) {
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignature(env);
}
}
public void Decl.C_emitSignature(C_env env) {
}
public void SampleDecl.C_emitSignature(C_env env) {
env.println("static unsigned char signature_bytes_" +
getName() + "[] = {");
// C_genFlatSignature(env);
SignatureList signature = signature();
for (int i = 0 ; i < signature.size() ; i++) {
String comment = signature.getComment(i);
if (comment != null) {
env.println(signature.getIndent(i) + "// " + comment);
}
byte[] data = signature.getData(i);
if (data != null) {
env.print(signature.getIndent(i));
for (int j = 0 ; j < data.length ; j++) {
env.print(data[j] + ", ");
}
env.println("");
}
}
env.println("};");
env.println("labcomm_signature_t labcomm_signature_" +
env.prefix + getName() + " = {");
env.indent();
env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
env.println("(int (*)(void *))labcomm_sizeof_" +
env.prefix + getName() + ",");
env.println("sizeof(signature_bytes_" + getName() + "),");
env.println("signature_bytes_"+ getName());
env.unindent();
env.println(" };");
}
public void ASTNode.C_genFlatSignature(C_env env) {
throw new Error(this.getClass().getName() +
".C_genFlatSignature(C_env env)" +
" not declared");
}
public void TypeDecl.C_genFlatSignature(C_env env) {
getType().C_genFlatSignature(env);
}
public void SampleDecl.C_genFlatSignature(C_env env) {
getType().C_genFlatSignature(env);
}
public void PrimType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, getToken());
env.println("// " + getName());
}
public void UserType.C_genFlatSignature(C_env env) {
lookupType(getName()).C_genFlatSignature(env);
}
public void ArrayType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, LABCOMM_ARRAY);
env.println("// LABCOMM_ARRAY");
C_genFlatSignature(env, getNumExp());
env.println("// # of dimensions");
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_genFlatSignature(env);
env.println("");
}
getType().C_genFlatSignature(env);
}
public void StructType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, LABCOMM_STRUCT);
env.println("// LABCOMM_STRUCT");
C_genFlatSignature(env, getNumField());
env.println("// # of fields");
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_genFlatSignature(env);
}
}
public void Field.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, getName());
env.println("");
getType().C_genFlatSignature(env);
}
public void IntegerLiteral.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, Integer.parseInt(getValue()));
env.print("// " + getValue());
}
public void VariableSize.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, 0);
env.print("// _");
}
public void ASTNode.C_genFlatSignature(C_env env, int value) {
env.print(" ");
for (int i = 24 ; i >= 0 ; i -= 8) {
env.print("0x");
String hex = Integer.toHexString((value >> i) & 0xff);
if (hex.length() == 1) { env.print("0"); }
env.print(hex);
env.print(", ");
}
}
public void ASTNode.C_genFlatSignature(C_env env, String value) {
C_genFlatSignature(env, value.length());
env.println("");
env.print(" ");
for (int i = 0 ; i < value.length() ; i++) {
env.print("'" + value.charAt(i) +"', ");
}
}
}
aspect C_Sizeof {
public void Decl.C_emitSizeofDeclaration(C_env env) {
}
public void SampleDecl.C_emitSizeofDeclaration(C_env env) {
env.println("extern int labcomm_sizeof_" + env.prefix + getName() +
"(" + env.prefix + getName() + " *v);");
}
public int Decl.C_fixedSizeof() {
return getType().C_fixedSizeof();
}
public int Type.C_fixedSizeof() {
throw new Error(this.getClass().getName() +
".C_fixedSizeof()" +
" not declared");
}
public int VoidType.C_fixedSizeof() {
return 0;
}
public int PrimType.C_fixedSizeof() {
switch (getToken()) {
case LABCOMM_BOOLEAN: { return 1; }
case LABCOMM_BYTE: { return 1; }
case LABCOMM_SHORT: { return 2; }
case LABCOMM_INT: { return 4; }
case LABCOMM_LONG: { return 8; }
case LABCOMM_FLOAT: { return 4; }
case LABCOMM_DOUBLE: { return 8; }
default: {
throw new Error(this.getClass().getName() +
".C_fixedSizeof()" +
" unknown size (" + getName() + ")");
}
}
}
public int UserType.C_fixedSizeof() {
return lookupType(getName()).getType().C_fixedSizeof();
}
public int StructType.C_fixedSizeof() {
int result = 0;
for (int i = 0 ; i < getNumField() ; i++) {
result += getField(i).getType().C_fixedSizeof();
}
return result;
}
public int ArrayType.C_fixedSizeof() {
int elements = 1;
for (int i = 0 ; i < getNumExp() ; i++) {
int n = Integer.parseInt(((IntegerLiteral)getExp(i)).getValue());
elements = elements * n;
}
return getType().C_fixedSizeof() * elements;
}
public void Decl.C_emitSizeof(C_env env) {
}
public void SampleDecl.C_emitSizeof(C_env env) {
env = env.nestStruct("(*v)");
env.println("int labcomm_sizeof_" + env.prefix + getName() +
"(" + env.prefix + getName() + " *v)");
env.println("{");
env.indent();
if (C_isDynamic()) {
env.println("int result = 4;");
getType().C_emitSizeof(env);
env.println("return result;");
} else {
env.println("return " + (4 + C_fixedSizeof()) + ";");
}
env.unindent();
env.println("}");
}
public void Type.C_emitSizeof(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitSizeof(C_env env)" +
" not declared");
}
public void PrimType.C_emitSizeof(C_env env) {
switch (getToken()) {
case LABCOMM_STRING: {
env.println("result += 4 + strlen(" + env.qualid + ");");
} break;
default: {
throw new Error(this.getClass().getName() +
".C_emitSizeof(C_env env)" +
" known size (" + getName() + ")");
}
}
}
public void UserType.C_emitSizeof(C_env env) {
lookupType(getName()).getType().C_emitSizeof(env);
}
public void StructType.C_emitSizeof(C_env env) {
int fixed = 0;
for (int i = 0 ; i < getNumField() ; i++) {
if (getField(i).getType().C_isDynamic()) {
getField(i).getType().C_emitSizeof(
env.nestStruct("." + getField(i).getName()));
} else {
fixed += getField(i).getType().C_fixedSizeof();
}
}
if (fixed > 0) {
env.println("result += " + fixed + ";");
}
}
public void ArrayType.C_emitSizeof(C_env env) {
if (getType().C_isDynamic()) {
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitSizeof(C_Nest(env));
for (int i = 0 ; i < getNumExp() ; i++) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
} else {
env.print("result += " + getType().C_fixedSizeof());
for (int i = 0 ; i < getNumExp() ; i++) {
env.print(" * " + getExp(i).C_getLimit(env, i));
}
env.println(";");
}
}
}
aspect C_forAll {
public void Program.C_emitForAll(C_env env) {
env.print("#define LABCOMM_FORALL_SAMPLES_" + env.lcName +
"(func, sep)");
env.indent();
boolean needSeparator = false;
for (int i = 0; i < getNumDecl(); i++) {
String s = getDecl(i).C_forAll(env);
if (s != null) {
if (needSeparator) { env.print(" sep"); }
env.println(" \\");
env.print(s);
needSeparator = true;
}
}
env.println("");
env.unindent();
}
public String Decl.C_forAll(C_env env) {
return null;
}
public String SampleDecl.C_forAll(C_env env) {
return "func(" + getName() + ", " + env.prefix + getName() + ")";
}
}
aspect C_Info {
public void Program.C_info(PrintStream out, String prefix) {
C_env env = new C_env("", "", prefix, out);
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_info(env);
}
}
public void Decl.C_info(C_env env) {
throw new Error(this.getClass().getName() +
".C_info((C_env env)" +
" not declared");
}
public void TypeDecl.C_info(C_env env) {
env.println("C,typedef," + getName() + "," + getName());
}
public void SampleDecl.C_info(C_env env) {
env.println("C,sample," + getName() + "," + getName());
}
}