📄 smctclgenerator.java
字号:
//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL///// Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.//// The Original Code is State Machine Compiler (SMC).//// The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2005 - 2007. Charles W. Rapp.// All Rights Reserved.//// Contributor(s):// Eitan Suez contributed examples/Ant.// (Name withheld) contributed the C# code generation and// examples/C#.// Francois Perrad contributed the Python code generation and// examples/Python.// Chris Liscio contributed the Objective-C code generation// and examples/ObjC.//// RCS ID// $Id: SmcTclGenerator.java,v 1.7 2008/03/21 14:03:17 fperrad Exp $//// CHANGE LOG// (See the bottom of this file.)//package net.sf.smc;import java.io.PrintStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * Visits the abstract syntax tree, emitting [incr Tcl] code. * @see SmcElement * @see SmcCodeGenerator * @see SmcVisitor * * @author <a href="mailto:rapp@acm.org">Charles Rapp</a> */public final class SmcTclGenerator extends SmcCodeGenerator{//---------------------------------------------------------------// Member methods// public SmcTclGenerator(String srcfileBase) { super (srcfileBase, "{0}{1}_sm.{2}", "tcl"); } // end of SmcTclGenerator(String) public void visit(SmcFSM fsm) { String context = fsm.getContext(); String rawSource = fsm.getSource(); String packageName = fsm.getPackage(); String startState = fsm.getStartState(); List<SmcMap> maps = fsm.getMaps(); List<SmcTransition> transitions; List<SmcParameter> params; String mapName; String transName; String separator; int index = 0; Iterator<SmcParameter> pit; // Now dump out the raw source code, if any. if (rawSource != null && rawSource.length() > 0) { _source.println(rawSource); _source.println(); } // Do user-specified imports now. for (String imp: fsm.getImports()) { _source.print("package require "); _source.print(imp); _source.println(";"); } _source.println(); // If a namespace was specified, then output that // namespace now. if (packageName != null && packageName.length() > 0) { _source.print("namespace eval "); _source.print(packageName); _source.println(" {"); _source.println(); _indent = " "; _pkgScope = "::" + packageName + "::"; } else { _indent = ""; _pkgScope = ""; } // Generate the context. _source.print(_indent); _source.print("class "); _source.print(context); _source.println("Context {"); _source.print(_indent); _source.println(" inherit ::statemap::FSMContext;"); _source.println(); _source.print(_indent); _source.println("# Member functions."); _source.println(); _source.print(_indent); _source.println(" constructor {owner} {"); _source.print(_indent); _source.println( " ::statemap::FSMContext::constructor;"); _source.print(_indent); _source.println(" } {"); _source.print(_indent); _source.println(" set _owner $owner;"); _source.print(_indent); _source.print(" setState ${"); _source.print(_pkgScope); _source.print(startState); _source.println("};"); _source.print(_indent); _source.print(" ${"); _source.print(_pkgScope); _source.print(startState); _source.println("} Entry $this;"); _source.print(_indent); _source.println(" }"); // For every possible transition in every state map, // create a method. // First, get the transitions list. transitions = fsm.getTransitions(); for (SmcTransition trans: transitions) { params = trans.getParameters(); // Don't do the Default transition. if (trans.getName().equals("Default") == false) { _source.println(); _source.print(_indent); _source.print(" public method "); _source.print(trans.getName()); _source.print(" {"); for (pit = params.iterator(), separator = ""; pit.hasNext() == true; separator = " ") { _source.print(separator); (pit.next()).accept(this); } _source.println("} {"); _source.print(_indent); _source.print(" [getState] "); _source.print(trans.getName()); _source.print(" $this"); for (SmcParameter param: params) { _source.print(" $"); _source.print(param.getName()); } _source.println(";"); _source.print(_indent); _source.println(" return -code ok;"); _source.print(_indent); _source.println(" }"); } } _source.println(); _source.print(_indent); _source.println(" public method getOwner {} {"); _source.print(_indent); _source.println(" return -code ok $_owner;"); _source.print(_indent); _source.println(" }"); // v. 2.2.0: If we are supporting serialization, then // declare the min and max indices. if (Smc.isSerial() == true) { _source.println(); _source.print(_indent); _source.println(" public method valueOf {id} {"); _source.print(_indent); _source.println( " if {$id < $MIN_ID || $id > $MAX_ID} {"); _source.print(_indent); _source.println(" set retcode error;"); _source.print(_indent); _source.print(" set retval "); _source.println("\"$id is out of bounds\";"); _source.print(_indent); _source.println(" } else {"); _source.print(_indent); _source.println(" set retcode ok;"); _source.print(_indent); _source.println( " set retval $_States($id);"); _source.print(_indent); _source.println(" }"); _source.println(); _source.print(_indent); _source.println( " return -code $retcode $retval;"); _source.print(_indent); _source.println(" }"); } _source.println(); _source.print(_indent); _source.println("# Member data."); _source.println(); _source.print(_indent); _source.println(" private variable _owner;"); // v. 2.2.0: If we are supporting serialization, then // declare the min and max indices. if (Smc.isSerial() == true) { _source.print(_indent); _source.println(" private common MIN_ID;"); _source.print(_indent); _source.println(" private common MAX_ID;"); _source.print(_indent); _source.println(" private common _States;"); } // Put the closing brace on the context class. _source.print(_indent); _source.println("}"); _source.println(); // Now output the application's state class. _source.print(_indent); _source.print("class "); _source.print(context); _source.println("State {"); _source.print(_indent); _source.println(" inherit ::statemap::State;"); _source.println(); _source.print(_indent); _source.println("# Member functions."); _source.println(); _source.print(_indent); _source.println(" constructor {name id} {"); _source.print(_indent); _source.println( " ::statemap::State::constructor $name $id;"); _source.print(_indent); _source.println(" } {}"); _source.println(); // Define the default Entry() and Exit() methods. _source.print(_indent); _source.println(" public method Entry {context} {};"); _source.print(_indent); _source.println(" public method Exit {context} {};"); // Declare the undefined default transitions. for (SmcTransition trans: transitions) { transName = trans.getName(); // The Default transition is handled separately. if (transName.equals("Default") == false) { _source.println(); _source.print(_indent); _source.print(" public method "); _source.print(transName); _source.print(" {context"); for (SmcParameter param: trans.getParameters()) { _source.print(" "); param.accept(this); } _source.println("} {"); _source.print(_indent); _source.println(" Default $context;"); _source.print(_indent); _source.println(" return -code ok;"); _source.print(_indent); _source.println(" }"); } } // Define the default Default transition. _source.println(); _source.print(_indent); _source.println(" public method Default {context} {"); _source.print(_indent); _source.println( " set transition [$context getTransition];"); _source.print(_indent); _source.print(" return -code error "); _source.print("\"Transition \\\"$transition\\\" "); _source.print("fell through to a "); _source.println( "non-existent default definition.\";"); _source.print(_indent); _source.println(" }"); // End of the application state class. _source.print(_indent); _source.println("}"); _source.println(); // Have each map print out its source code in turn. for (SmcMap map: maps) { map.accept(this); } // Output the static state initialization. _source.print(_indent); _source.println("# Static state declarations."); for (SmcMap map: maps) { mapName = map.getName(); for (SmcState state: map.getStates()) { _source.print(_indent); _source.print("set "); _source.print(mapName); _source.print("::"); _source.print(state.getInstanceName()); _source.print(" "); if (packageName != null && packageName.length() > 0) { _source.print(packageName); _source.print("::"); } _source.print("["); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.print(" #auto \""); _source.print(mapName); _source.print("::"); _source.print(state.getClassName()); _source.print("\" "); _source.print(index); _source.println("];"); ++index; } } // If -reflect specified, then generate the transitions // class-level data member for each state - but only if // the state has transitions. if (Smc.isReflection() == true) { SmcState defaultState; List<SmcTransition> defaultTransitions; List<SmcTransition> stateTransitions; _source.println(); _source.print(_indent); _source.println("# Static state transitions."); for (SmcMap map: maps)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -