package javal; import java.io.File; import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.*; public class LimboGen { public LimboGen( Class cl, Field[] fields, Method[] methods, boolean verbose ) { theClass = cl; this.fields = fields; this.methods = methods; opt_verbose = verbose; // create names String full_name = cl.getName(); base_name = ClassBaseName( full_name ); mod_name = base_name +"_L"; limbo_dotm = mod_name +".m"; limbo_dotb = mod_name +".b"; // some class are "special" to javal // if it is a special class we don't // want to generate adt's for it and // will use a special ADT name special = true; //assume special obj_adt = SpecialClass( full_name ); if ( obj_adt == null ) { special = false; obj_adt = base_name +"_obj"; } // will only generate skeleton for native methods natives = GetNatives( methods ); has_natives = natives.length > 0; // need to distinguish between instance and static fields iFields = GetInstanceFields( fields ); sFields = GetStaticFields( fields ); } /** * Generate a Limbo Module Declaration * file (.m) for a java class containing * native methods. */ public void DotM() throws IOException { // open a file out = MkFile( limbo_dotm ); // emit the Limbo Module File Emit( "# generated file edit with care\n\n" ); Emit( mod_name +" : module\n" ); Emit( "{\n" ); GenADT(); Emit( "\n" ); GenFct(false); Emit( "\n};\n" ); out.close(); if ( merge ) { // save off existing .m and rename // tmp to .m File f = new File( limbo_dotm ); File o = new File("old_"+limbo_dotm); File t = new File( tmpname ); if ( o.exists() ) o.delete(); f.renameTo( o ); t.renameTo( f ); } } /** * Generate a Limbo Module Implementation * Skeleton containing native methods for * a java class. */ public void DotB() throws IOException { // don't generate a .b if no natives if ( ! has_natives ) return; // open a file out = MkFile( limbo_dotb ); // generate file prolog Emit("implement "+ mod_name +";\n\n" ); Emit("include \"jni.m\";\n" ); Emit(T1+"jni : JNI;\n" ); Emit(T2+"ClassModule,\n"); Emit(T2+ T_JString +",\n"); Emit(T2+ T_JArray +",\n"); Emit(T2+ T_JArrayI +",\n"); Emit(T2+ T_JArrayC +",\n"); Emit(T2+ T_JArrayB +",\n"); Emit(T2+ T_JArrayS +",\n"); Emit(T2+ T_JArrayJ +",\n"); Emit(T2+ T_JArrayF +",\n"); Emit(T2+ T_JArrayD +",\n"); Emit(T2+ T_JArrayZ +",\n"); Emit(T2+ T_JArrayJObject +",\n"); Emit(T2+ T_JArrayJClass +",\n"); Emit(T2+ T_JArrayJString +",\n"); Emit(T2+ T_JClass +",\n"); Emit(T2+T_JObject +" : import jni;\n\n"); Emit("#>> extra pre includes here\n\n#<<\n\n"); Emit("include \""+ limbo_dotm +"\";\n\n" ); Emit("#>> extra post includes here\n\n#<<\n\n"); // generate a skeleton for init() and each native method GenFct( true ); out.close(); if ( merge ) FileMerge.Merge( limbo_dotb, tmpname ); } /** * Generate an ADT declaration for the class * instance fields. */ private void GenADT() throws IOException { // don't generate an ADT decl for "special" clases if ( special ) return; Emit( T1+ obj_adt +" : adt\n"+ T1+ "{\n" ); // emit the std object header Emit( T2+ "cl_mod : ClassModule;\n" ); // walk through instance data emitting Limbo decl for( int x=0; x>\n}#<<\n\n" ); } else { Emit( T1+ fct_name +" : fn( "+ fct_params.toString() +")"+ fct_t +";\n" ); } } } /** * every Limbo Native module has a init() * function which the loader will call * when the native mod is loaded. This * method generates that fct. * * @param skel If true gen a fct skel; else fct decl * */ private void GenInit( boolean skel ) throws IOException { if ( skel ) { Emit( "init( jni_p : JNI )\n{\n" ); Emit( T1+"# save java native inteface mod instance\n" ); Emit( T1+"jni = jni_p;\n" ); Emit( T1+"#>>extra initialization here\n"+T1+"#<<\n" ); Emit( "}\n\n" ); } else { Emit( T1+"init : fn( jni_p : JNI );\n" ); } } /** * Given an array of types return a string with * a comma seperated sequence of java method * parameter declarations * * @param ptypes An array of types * * @return A string representing method param decls */ private String GenFctParams( Class[] ptypes ) { String fct_params = ""; for( int x=0; x