📄 smcobjcgenerator.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) 2006, 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: SmcObjCGenerator.java,v 1.4 2008/03/21 14:03:16 fperrad Exp $//// CHANGE LOG// (See the bottom of this file.)//package net.sf.smc;import java.io.PrintStream;import java.util.Iterator;import java.util.List;import java.util.StringTokenizer;/** * Visits the abstract syntax tree emitting Objective-C code. * @see SmcElement * @see SmcCodeGenerator * @see SmcVisitor * * @author <a href="mailto:rapp@acm.org">Charles Rapp</a> */public final class SmcObjCGenerator extends SmcCodeGenerator{//---------------------------------------------------------------// Member methods// public SmcObjCGenerator(String srcfileBase) { super (srcfileBase, "{0}{1}_sm.{2}", "m"); } // end of SmcObjCGenerator(String) // This method generates the following code: // // %{ %} raw source code - if any // // #import <%include header file> // #import "<context>_sm.h" public void visit(SmcFSM fsm) { String packageName = fsm.getPackage(); String rawSource = fsm.getSource(); String context = fsm.getContext(); String fqStateName = fsm.getStartState(); String mapName; List<SmcTransition> transList; String separator; List<SmcParameter> params; Iterator<SmcMap> mapIt; SmcMap map; Iterator<SmcState> stateIt; SmcState state; Iterator<SmcParameter> pit; String declaration; int packageDepth = 0; int index; // Dump out the raw source code, if any. if (rawSource != null && rawSource.length() > 0) { _source.println(rawSource); _source.println(); } // Generate #imports. for (String include: fsm.getIncludes()) { _source.print("#import "); _source.println(include); } // Include the context file last. _source.print("#import \""); _source.print(_srcfileBase); _source.println("_sm.h\""); // Statically declare all derive state classes. _source.print(_indent); _source.println("// Class declarations."); for (mapIt = fsm.getMaps().iterator(), index = 0; mapIt.hasNext() == true; ) { map = mapIt.next(); mapName = map.getName(); _source.print(_indent); _source.print("@implementation "); _source.println(mapName); for (stateIt = map.getStates().iterator(); stateIt.hasNext() == true; ++index) { state = stateIt.next(); _source.print(_indent); _source.print("+ ("); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.print("*)"); _source.print(state.getInstanceName()); _source.println(";"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" "); _source.print("static "); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.print(" *g"); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.println(" = nil;"); _source.print(_indent); _source.print(" if (!g"); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.println(")"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" g"); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.print(" = [["); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.print(" alloc] initWithName:@\""); _source.print(mapName); _source.print("::"); _source.print(state.getClassName()); _source.print("\" stateId:"); _source.print(index); _source.println("];"); _source.print(_indent); _source.println(" }"); _source.print(_indent); _source.print(" "); _source.print("return g"); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.println(";"); _source.print(_indent); _source.println("}"); } _source.println("@end"); } // Print out the default definitions for all the // transitions. First, get the transitions list. transList = fsm.getTransitions(); _source.println(); _source.print(_indent); _source.print("@implementation "); _source.print(context); _source.println("State"); // TODO: Need to fill in Entry/Exit code if they're // defined _source.print(_indent); _source.print("- (void)Entry:("); _source.print(context); _source.println("Context*)context"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.println("}"); _source.print(_indent); _source.print("- (void)Exit:("); _source.print(context); _source.println("Context*)context"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.println("}"); // Output the default transition definitions. for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.print(_indent); _source.print("- (void)"); _source.print(trans.getName()); _source.print(":("); _source.print(context); _source.print("Context*)context"); for (SmcParameter param: trans.getParameters()) { _source.print(" :"); param.accept(this); } _source.println(";"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.println(" [self Default:context];"); _source.print(_indent); _source.println("}"); } } // Output the Default transition method ... almost. // If -g is being used, then add the "s" argname. _source.println(); _source.print(_indent); _source.print("- (void)Default:("); _source.print(context); _source.println("Context*)context;"); _source.print(_indent); _source.println("{"); // Print the transition out to the verbose log. if (Smc.isDebug() == true) { _source.print(_indent); _source.println(" if ( [context debugFlag] )"); _source.print(_indent); _source.print("{"); // The TRACE macro. _source.print(_indent); _source.print(" TRACE(@"); _source.println( "\"TRANSITION : Default\\n\\r\");"); _source.print(_indent); _source.println(" }"); } // A transition has been issued which has no // definition in the current state and there // is no default to cover for it. Throw an // exception. // v. 1.3.1: But only if -noex was not specified. _source.print(_indent); _source.println( " NSAssert( NO, @\"Default transition\" );"); _source.print(_indent); _source.println("}"); // End the state class _source.println("@end"); _source.println(); // Have each map print out its source code now. for (mapIt = fsm.getMaps().iterator(); mapIt.hasNext() == true; ) { (mapIt.next()).accept(this); } // Dump the context class // @implementation FooContext // - (id)initWithOwner:(FOO*)owner; // ... // _source.print(_indent); _source.print("@implementation "); _source.print(context); _source.println("Context"); // Convert SMC scope syntax to Objective-C syntax. if (fqStateName.indexOf("::") >= 0) { fqStateName = convertScope(fqStateName); } // Dump the initWithOwner method // - (id)initWithOwner:(Foo*)owner; // { // [self setOwner:owner]; // [self setState:startState] // } _source.print(_indent); _source.print("- (id)initWithOwner:("); _source.print(context); _source.print("*)"); _source.println("owner;"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" "); _source.println("self = [super init];"); _source.print(_indent); _source.print(" "); _source.println("if (!self)"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" "); _source.println("return nil;"); _source.print(_indent); _source.println(" }"); _source.print(_indent); _source.print(" "); _source.println("_owner = owner;"); _source.print(_indent); _source.print(" "); _source.print("[self setState:"); _source.print(fqStateName); _source.println("];"); _source.print(_indent); _source.print(" ["); _source.print(fqStateName); _source.println(" Entry:self];"); _source.print(_indent); _source.print(" "); _source.println("return self;"); _source.print(_indent); _source.println("}"); _source.print(_indent); _source.print("- (" ); _source.print(context); _source.println("State*)state;"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" "); _source.print("return ("); _source.print(context); _source.println("State*)_state;"); _source.print(_indent); _source.println("}"); _source.print(_indent); _source.print("- ("); _source.print(context); _source.println("*)owner;"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.print(" "); _source.println("return _owner;"); _source.print(_indent); _source.println("}"); // Generate a method for every transition in every map // *except* the default transition. for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.println(); _source.print(_indent); _source.print("- (void)"); _source.print(trans.getName()); params = trans.getParameters(); for (pit = params.iterator(), separator = ":"; pit.hasNext() == true; separator = " :") { _source.print(separator); (pit.next()).accept(this); } _source.println(";"); _source.print(_indent); _source.println("{");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -