import java.util.Hashtable; import java.util.Vector; import Jakarta.util.FixDosOutputStream; import java.io.*; public class sm4data { static final String serExtension = ".ser"; sdInfo Sm; // parse info repository String ser_directory = ""; // output directory Hashtable serCache = new Hashtable(); // cache of .ser files int uniqueCounter = 0; // unique integer // convert AST into a string, where null ASTs are "" strings // these are not really standard functions -- if they were, // they would be removed to the StringAST layer. static String ToString( AstNode x ) { return ( x == null ) ? "" : x.toString(); } // methods to convert strings into different ASTs, where // vacuous strings are mapped to null ASTs static AST_FieldDecl ToFieldDecl( String x ) { return ( x.equals( "" ) || x.equals( "\n" ) ) ? null : AST_FieldDecl.MakeAST( x ); } static AST_Stmt ToStmt( String x ) { return ( x.equals( "" ) || x.equals( "\n" ) ) ? null : AST_Stmt.MakeAST( x ); } // refineMethod( o, u, m, v, h, t ) is used for refining Prepare, Exit, // Enter, Otherwise, Otherwise_default, Test, and Action methods. // upon return of refineMethod, set o = u. // t is a token whose line number is extracted for error reporting static AstNode refineMethod( AstNode orig, AstNode upd, String specName, String methodName, boolean isVoid, AstTokenInterface t ) { boolean proceedFound; String extraMeth; // Step 0: make sure that upd is not null. if so, provide // dummy statement if (upd == null) upd = AST_Stmt.MakeAST( ";" ); // Step 1: see if this is the first specification in this file // note: when states and edges are first declared, // bodies are present for each method spec (e.g., Enter, Exit, // etc. So orig == null only if we are dealing with // a spec method refinement in a subclass (or subSm). if ( orig == null ) { // Step 2: it is the first specification in this file. Search upd // for Proceeds declaration. Replace "Proceed" with // " super.<methodName>". <specName> example is // "Prepare", <methodName> example is "Prepare_myState". proceedFound = replaceProceed( upd, " super." + methodName ); if ( !proceedFound && isVoid ) { // make upd an implicit before method, which is by default // what it should be upd = ToStmt( upd + " super." + methodName + "( " + kernelConstants.globals().sm4vars.Sm.argdecl + "); " ); } else if ( !proceedFound && !isVoid ) AstNode.error( t, Utility.SourceName() + "Proceed() not found in " + specName + " method." ); } else { // Step 3: it isn't the first specification in this file. // Create a mangled name to house the original // specification code String mname = methodName + "$$" + kernelConstants.globals().sm4vars.Sm.name + + kernelConstants.globals().sm4vars.uniqueCounter++; // Step 4: now replace each "Proceed" with "<mname>" and // add the generated method to extra_methods for output proceedFound = replaceProceed( upd, " " + mname ); if ( isVoid ) extraMeth = "\n final void "; else extraMeth = "\n final boolean "; extraMeth = extraMeth + mname + "( " + kernelConstants.globals().sm4vars.Sm.pardecl + " ) {"; if ( isVoid ) extraMeth = extraMeth + orig + " }"; else extraMeth = extraMeth + " return " + orig + "; }"; // we're done if upd was updated. If not, assume upd is // an before method if ( !proceedFound && isVoid ) upd = ToStmt( upd + mname + "( " + kernelConstants.globals().sm4vars.Sm.argdecl + "); " ); else if ( !proceedFound && !isVoid ) AstNode.error( t, Utility.SourceName() + "Proceed() not found in " + specName + " method." ); kernelConstants.globals().sm4vars.Sm.extra_methods = kernelConstants.globals().sm4vars.Sm.extra_methods + extraMeth; } return upd; } private static boolean replaceProceed( AstNode tree, String code ) { AstCursor c = new AstCursor(); boolean proceedFound = false; if ( tree == null ) return false; for ( c.First( tree ); c.More(); c.PlusPlus() ) { if ( c.node instanceof ProceedDecl ) { ProceedDecl n = ( ProceedDecl ) c.node; // this kinda cheats -- should replace it with the actual // parse tree, but this should be OK. n.tok[0].setTokenName( code ); proceedFound = true; } } return proceedFound; } }