private string getSyncChannel(Template t, StateTransition st, SyncRule.Direction dir) { SyncRule r = (SyncRule)st.Rules.SingleOrDefault(x => x is SyncRule); if (r == null) { return(NULL); } if (r.Dir != dir) { return(NULL); } VarDecl vd; switch (r.Expr.Type) { case Expression.ExpType.Func: // might be array/range if (r.Expr.Func != Expression.Funcs.ArrayIndex) { throw new Exception("Only array dereferencing allowed on channels!"); } if (r.Expr.First.Type != Expression.ExpType.Var) { throw new Exception("Synchronization rule must be a channel!"); } int idx; if (!t.Declarations.getExprValue(r.Expr.Second, out idx)) { throw new Exception("Channel array index must be a constant!"); } vd = t.Declarations.getVar(r.Expr.First.Var); if (vd == null || vd.Type.Type != VarType.Channel) { throw new Exception(String.Format("Could not find '{0}' in declarations for template '{1}' or globally!", r.Expr.First.Var, t.Name)); } return(String.Format("{0}_ARRAY[{1}]", getUniqueName(vd), idx - vd.ArrLow)); case Expression.ExpType.Var: vd = t.Declarations.getVar(r.Expr.Var); if (vd == null || vd.Type.Type != VarType.Channel) { throw new Exception(String.Format("Could not find '{0}' in declarations for template '{1}' or globally!", r.Expr.Var, t.Name)); } return(String.Format("&{0}", getUniqueName(vd))); default: throw new Exception("Synchronization rule must be a channel"); } }
private Template parseTemplate(XmlElement node, Declarations globaldecls) { try { Console.WriteLine(" Parsing template ..."); TemplateState state = new TemplateState(); XmlNodeList subnodes; XmlNode namenode = node.SelectSingleNode("./name"); if (namenode == null || string.IsNullOrEmpty(getElementText(namenode))) { throw new ParseException("No name node!"); } state._name = getElementText(namenode); if (_templates.Count > 0 && !_templates.Contains(state._name)) { return(null); } XmlNode decnode = node.SelectSingleNode("./declaration"); if (decnode != null) { state._declarations = parseDeclarations(getElementText(decnode), globaldecls); } else { state._declarations = new Declarations() { Parent = globaldecls } }; Console.WriteLine(" Name: " + state._name); subnodes = node.SelectNodes("./location"); if (subnodes != null) { foreach (XmlNode subnode in subnodes) { StateNode sn = parseNode((XmlElement)subnode, state._declarations); state._nodes.Add(sn); } } subnodes = node.SelectNodes("./transition"); if (subnodes != null) { foreach (XmlNode subnode in subnodes) { StateTransition st = parseTransition((XmlElement)subnode, state); state._transitions.Add(st); } } XmlNode initnode = node.SelectSingleNode("./init"); if (initnode == null || string.IsNullOrEmpty(((XmlElement)initnode).GetAttribute("ref"))) { throw new ParseException("No init node!"); } state._init = findNode(((XmlElement)initnode).GetAttribute("ref"), state); if (state._init == null) { throw new ParseException("Init node not found"); } XmlNode parameter = node.SelectSingleNode("./parameter"); if (parameter != null) { throw new ParseException("template parameters not yet supported, easy to add if needed!"); } return(new Template(state._name, state._declarations, state._init, state._nodes.ToArray(), state._transitions.ToArray())); } catch (SelectNotSupportException) { return(null); // for now } }
private StateTransition parseTransition(XmlElement node, TemplateState state) { Console.WriteLine(" Parsing transition ..."); string id = node.GetAttribute("id"); if (id == null) { throw new ParseException("Expected id in <location>"); } XmlNode source = node.SelectSingleNode("./source"); if (source == null) { throw new ParseException("Expected source in <location>"); } XmlNode target = node.SelectSingleNode("./target"); if (target == null) { throw new ParseException("Expected source in <location>"); } string srcid = ((XmlElement)source).GetAttribute("ref"); if (string.IsNullOrEmpty(srcid)) { throw new ParseException("No source id for transition"); } string tgtid = ((XmlElement)target).GetAttribute("ref"); if (string.IsNullOrEmpty(tgtid)) { throw new ParseException("No target id for transition"); } StateNode tgtnode = findNode(tgtid, state); if (tgtnode == null) { throw new ParseException("Target node not found for transition"); } StateNode srcnode = findNode(srcid, state); if (srcnode == null) { throw new ParseException("Source node not found for transition"); } string name = null; XmlNodeList namenodes = node.SelectNodes("./label[@kind='comments']"); if (namenodes != null) { XmlNode namenode = (from XmlNode n in namenodes select n).SingleOrDefault(n => getElementText(n).Contains("{name=")); if (namenode != null) { string txt = getElementText(namenode); int pos = txt.IndexOf("{name="); txt = txt.Substring(pos + 6); pos = txt.IndexOf("}"); if (pos > 0) { name = txt.Substring(0, pos); } } } StateTransition st = new StateTransition(state._name, srcnode, tgtnode, name); st.Rules = parseRules(node, st.Name, state._declarations); return(st); }