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;
}
}