From 1bdf058cf07cfd53885c81af4c0c943d3baac4c6 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 29 Feb 2016 23:32:08 +0100 Subject: More work on VHDL --- src/uscxml/transform/ChartToC.cpp | 28 +- src/uscxml/transform/ChartToVHDL.cpp | 490 +++++++++++++++++++++-------------- src/uscxml/transform/ChartToVHDL.h | 7 +- test/src/test-c-inline.c | 25 +- test/src/test-c-inline.c.scxml.c | 94 +++++-- test/src/test-c-machine.cpp | 7 - test/src/test-c-machine.scxml.c | 209 ++++++--------- 7 files changed, 495 insertions(+), 365 deletions(-) diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index ee0b431..159b4c5 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -785,6 +785,7 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << " const char target[USCXML_MAX_NR_STATES_BYTES];" << std::endl; stream << " const char* event;" << std::endl; stream << " const char* condition;" << std::endl; + stream << " const is_enabled_t is_enabled;" << std::endl; stream << " const exec_content_t on_transition;" << std::endl; stream << " const unsigned char type;" << std::endl; stream << " const char conflicts[USCXML_MAX_NR_TRANS_BYTES];" << std::endl; @@ -884,7 +885,6 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << std::endl; stream << " dequeue_internal_t dequeue_internal;" << std::endl; stream << " dequeue_external_t dequeue_external;" << std::endl; - stream << " is_enabled_t is_enabled;" << std::endl; stream << " is_matched_t is_matched;" << std::endl; stream << " is_true_t is_true;" << std::endl; stream << " raise_done_event_t raise_done_event;" << std::endl; @@ -1147,6 +1147,19 @@ void ChartToC::writeExecContent(std::ostream& stream) { Element transition(_transitions[i]); NodeSet execContent = DOMUtils::filterChildType(Node_base::ELEMENT_NODE, transition); + if (HAS_ATTR(transition, "cond")) { + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(transition) << "_is_enabled(const uscxml_ctx* ctx, const uscxml_transition* transition) {" << std::endl; + if (HAS_ATTR(_scxml, "datamodel") && ATTR(_scxml, "datamodel") == "native") { + stream << " return (" << ATTR(transition, "cond") << ");" << std::endl; + } else { + stream << " if likely(ctx->is_true != NULL) {" << std::endl; + stream << " return (ctx->is_true(ctx, \"" << escape(ATTR(transition, "cond")) << "\"));" << std::endl; + stream << " }" << std::endl; + stream << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; + } + stream << "}" << std::endl; + } + if (execContent.size() > 0) { stream << "static int " << _prefix << "_" << DOMUtils::idForNode(transition) << "_on_trans(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; stream << " int err = USCXML_ERR_OK;" << std::endl; @@ -1971,6 +1984,16 @@ void ChartToC::writeTransitions(std::ostream& stream) { stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL"); stream << "," << std::endl; + + // is enabled + stream << " /* is_enabled */ "; + if (HAS_ATTR(transition, "cond")) { + stream << _prefix << "_" << DOMUtils::idForNode(transition) << "_is_enabled"; + } else { + stream << "NULL"; + } + stream << "," << std::endl; + // on transition handlers stream << " /* ontrans */ "; if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) { @@ -2209,7 +2232,8 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) {" << std::endl; stream << " /* is it enabled? */" << std::endl; stream << " if ((ctx->event == NULL || ctx->is_matched(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) &&" << std::endl; - stream << " (USCXML_GET_TRANS(i).condition == NULL || ctx->is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) {" << std::endl; + stream << " (USCXML_GET_TRANS(i).condition == NULL || " << std::endl; + stream << " USCXML_GET_TRANS(i).is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) {" << std::endl; stream << " /* remember that we found a transition */" << std::endl; stream << " ctx->flags |= USCXML_CTX_TRANSITION_FOUND;" << std::endl; stream << std::endl; diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 6f104ac..d3abcf1 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -120,14 +120,77 @@ void ChartToVHDL::writeTo(std::ostream& stream) { // same preparations as the C transformation prepare(); -// checkDocument(); + // checkDocument(); findEvents(); + stream << "-- generated from " << _sourceURL.asString() << std::endl; + stream << "-- run as " << std::endl; + stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=foo.vcd" << std::endl; + stream << std::endl; + writeTypes(stream); writeFiFo(stream); writeFSM(stream); + writeTestbench(stream); } +void ChartToVHDL::writeTestbench(std::ostream& stream) { + + stream << "-- TESTBENCH" << std::endl; + writeIncludes(stream); + stream << " " << std::endl; + stream << "-- empty entity" << std::endl; + stream << "entity tb is" << std::endl; + stream << "end entity tb;" << std::endl; + stream << " " << std::endl; + stream << "architecture bhv of tb is" << std::endl; + stream << " " << std::endl; + stream << " -- Module declaration" << std::endl; + stream << " component fsm_scxml is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in event_type;" << std::endl; + stream << " next_event_en_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " completed_o :out std_logic;" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + stream << " current_state_o :out state_type" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << " " << std::endl; + stream << " -- input" << std::endl; + stream << " signal clk : std_logic := '0';" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal next_event_i : event_type;" << std::endl; + stream << " " << std::endl; + stream << " -- output" << std::endl; + stream << " signal error_o, next_event_en_i, completed_o : std_logic;" << std::endl; + stream << " " << std::endl; + stream << "begin" << std::endl; + stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; + stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; + stream << " " << std::endl; + stream << " -- Module instantiation" << std::endl; + stream << " dut : fsm_scxml" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst => reset," << std::endl; + stream << " en => '1'," << std::endl; + stream << " " << std::endl; + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_en_i => next_event_en_i," << std::endl; + stream << " completed_o => completed_o," << std::endl; + stream << " error_o => error_o," << std::endl; + stream << " current_state_o => open" << std::endl; + stream << " );" << std::endl; + stream << " " << std::endl; + stream << "end architecture;" << std::endl; + stream << "-- END TESTBENCH" << std::endl; + +} void ChartToVHDL::writeFSM(std::ostream & stream) { @@ -164,11 +227,14 @@ void ChartToVHDL::writeFSM(std::ostream & stream) { writeModuleInstantiation(stream); // write fsm architecture -// writeNextStateLogic(stream); + writeNextStateLogic(stream); writeOptimalTransitionSetSelection(stream); writeExitSet(stream); writeEntrySet(stream); + writeDefaultCompletions(stream); + writeCompleteEntrySet(stream); + writeActiveStateNplusOne(stream); // writeOutputLogic(stream); writeErrorHandler(stream); @@ -180,6 +246,7 @@ void ChartToVHDL::writeFSM(std::ostream & stream) { } #if 0 + void ChartToVHDL::writeTopDown(std::ostream & stream) { // create hardware top level stream << "-- top level" << std::endl; @@ -235,11 +302,11 @@ void ChartToVHDL::writeTypes(std::ostream & stream) { // create event type stream << " type event_type is ("; seperator = ""; -// for (size_t i = 0; i < _events.size(); i++) { -// stream << seperator; -// stream << _events[i]; -// seperator = ", "; -// } + // for (size_t i = 0; i < _events.size(); i++) { + // stream << seperator; + // stream << _events[i]; + // seperator = ", "; + // } if (seperator.size() == 0) { stream << "NO_EVENTS"; } @@ -359,16 +426,14 @@ void ChartToVHDL::writeSignals(std::ostream & stream) { stream << "-- system signals" << std::endl; stream << "signal stall : std_logic;" << std::endl; stream << "-- state signals" << std::endl; -// stream << "signal next_state : state_type;" << std::endl; -// stream << "signal current_state : state_type;" << std::endl; + // stream << "signal next_state : state_type;" << std::endl; + // stream << "signal current_state : state_type;" << std::endl; for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); - stream << "signal " << DOMUtils::idForNode(state) << "_curr : std_logic;" << std::endl; - stream << "signal " << DOMUtils::idForNode(state) << "_next : std_logic;" << std::endl; - } - for (size_t i = 0; i < _states.size(); i++) { - Element state(_states[i]); + stream << "signal is_active_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal is_active_np1_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal in_entry_set_" << toStr(i) << "_sig : std_logic;" << std::endl; stream << "signal in_exit_set_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl; stream << "signal in_complete_entry_set_up_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl; stream << "signal in_complete_entry_set_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl; @@ -476,6 +541,23 @@ std::string ChartToVHDL::eventNameEscape(const std::string& eventName) { return escaped; } +void ChartToVHDL::writeActiveStateNplusOne(std::ostream & stream) { + stream << "-- active configuration" << std::endl; + + for (size_t i = 0; i < _states.size(); i++) { + + VBranch* tree = (VASSIGN , + VLINE("is_active_np1_" + toStr(i) + "_sig"), + (VAND , + VLINE("in_complete_entry_set_"+toStr(i)+"_sig"), + (VOR , VLINE("in_exit_set_"+toStr(i)+"_sig"), (VNOT, VLINE("is_active_"+toStr(i)+"_sig"))))); + + tree->print(stream); + stream << ";" << std::endl; + + } +} + void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) { stream << "-- optimal transition set selection" << std::endl; for (size_t i = 0; i < _transitions.size(); i++) { @@ -503,46 +585,18 @@ void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) { } } - VBranch* tree = (VASSIGN , - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig") , - (VAND , + VBranch* tree = (VASSIGN, + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), + (VAND, (HAS_ATTR(transition, "event") - ? ( VNOT , VLINE("spontaneous_en") ) - : ( VNOP , VLINE("spontaneous_en") ) ) , + ? (VNOT, VLINE("spontaneous_en")) + : (VNOP, VLINE("spontaneous_en"))), VLINE("state_active_" + ATTR(transition, "source") + "_sig"), nameMatchers, - (VNOT , conflicters) ) ); + (VNOT, conflicters))); tree->print(stream); stream << ";" << std::endl; - - -#if 0 - stream << "in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig " - << "<= " << (HAS_ATTR(transition, "event") ? "(not spontaneous_en)" : "spontaneous_en") << " and " << std::endl - << " state_active_" << ATTR(transition, "source") << "_sig and not ( '0' " << std::endl; - for (size_t j = 0; j < i; j++) { - if (conflicts[j] == '1') { - stream << " or in_optimal_transition_set_" << toStr(j) << "_sig" << std::endl; - } - } - stream << " )"; - if (HAS_ATTR(transition, "event")) { - stream << " and ( '0' " << std::endl;; - - // find all matching event literals - std::list eventDescs = tokenize(ATTR(transition, "event")); - for (std::list::iterator descIter = eventDescs.begin(); descIter != eventDescs.end(); descIter++) { - std::list eventNames = _eventTrie.getWordsWithPrefix((*descIter) == "*" ? "" : *descIter); - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << " or event_" << eventNameEscape((*eventIter)->value) << "_sig" << std::endl; - } - } - stream << " )"; - - } - stream << ";" << std::endl; -#endif } } @@ -565,34 +619,75 @@ void ChartToVHDL::writeExitSet(std::ostream & stream) { } } - VBranch* tree = (VASSIGN , + VBranch* tree = (VASSIGN, VLINE("in_exit_set_" + toStr(i) + "_sig"), (VAND, VLINE("state_active_" + toStr(i) + "_sig"), - exitsetters )); + exitsetters)); tree->print(stream); stream << ";" << std::endl; + } +} -#if 0 - stream << "in_exit_set_" << toStr(i) << "_sig " - << "<= state_active_" << toStr(i) << "_sig and ('0'" << std::endl; - for (size_t j = 0; j < _transitions.size(); j++) { - Element transition(_transitions[j]); - std::string exitSet = ATTR(transition, "exitSetBools"); - if (exitSet[i] == '1') { - stream << " or in_optimal_transition_set_" << toStr(j) << "_sig " << std::endl; +void ChartToVHDL::writeEntrySet(std::ostream & stream) { + stream << "-- entry set selection" << std::endl; + + for (size_t i = 0; i < _states.size(); i++) { + + VBranch* tree = (VASSIGN , + VLINE("in_entry_set_" + toStr(i) + "_sig"), + (VAND , + VLINE("in_complete_entry_set_"+toStr(i)+"_sig"), + (VOR , VLINE("is_active_"+toStr(i)+"_sig"), (VNOT, VLINE("in_exit_set_"+toStr(i)+"_sig"))))); + + tree->print(stream); + stream << ";" << std::endl; + } +} + +void ChartToVHDL::writeDefaultCompletions(std::ostream & stream) { + stream << "-- default completion assignments" << std::endl; + + std::map, NodeSet > completions; + for (size_t i = 0; i < _states.size(); i++) { + Element state(_states[i]); + completions[state]; // initialize other completions to 0 + + std::string completion = ATTR(state, "completionBools"); + for (size_t j = 0; j < _states.size(); j++) { + if (completion[j] == '1') { + completions[Element(_states[j])].push_back(state); } } + } + + std::map, NodeSet >::const_iterator complIter = completions.begin(); + while(complIter != completions.end()) { + const Element& state(complIter->first); + const NodeSet& refs(complIter->second); + + std::string index = ATTR(state, "documentOrder"); + VContainer defaultCompleters = VOR; + + for (size_t i =0 ; i< refs.size(); i++) { + *defaultCompleters += VLINE("in_complete_entry_set_" + toStr(i) + "_sig "); + } + + VBranch* tree = (VASSIGN , + VLINE("default_completion_" + index + "_sig"), defaultCompleters); - stream << ")"; + tree->print(stream); stream << ";" << std::endl; -#endif + + complIter++; } + + } -void ChartToVHDL::writeEntrySet(std::ostream & stream) { - stream << "-- entry set selection" << std::endl; +void ChartToVHDL::writeCompleteEntrySet(std::ostream & stream) { + stream << "-- complete entry set selection" << std::endl; for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); @@ -619,7 +714,7 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) { } } - VBranch* tree = (VASSIGN , + VBranch* tree = (VASSIGN, VLINE("in_complete_entry_set_up_" + toStr(i) + "_sig"), optimalEntrysetters, completeEntrysetters); @@ -632,7 +727,7 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) { for (size_t j = 0; j < _transitions.size(); j++) { Element transition(_transitions[j]); -// std::cout << transition; + // std::cout << transition; std::string targetSet = ATTR(transition, "targetBools"); if (targetSet[i] == '1') { stream << " or in_optimal_transition_set_" << toStr(j) << std::endl; @@ -669,12 +764,12 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) { for (size_t j = 0; j < _states.size(); j++) { if (children[j] != '1') continue; - *tmp1 += ( VAND, - ( VNOT, - ( VAND, - VLINE("is_active" + toStr(j) + "_sig"), - ( VNOT, - VLINE("in_exit_set_" + toStr(j) + "_sig") ) ) ) ); + *tmp1 += (VAND, + (VNOT, + (VAND, + VLINE("is_active" + toStr(j) + "_sig"), + (VNOT, + VLINE("in_exit_set_" + toStr(j) + "_sig"))))); } @@ -684,7 +779,7 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) { *tmp1 += VLINE("in_complete_entry_set_" + toStr(parent) + "_sig"); } - VBranch* tree = (VASSIGN , + VBranch* tree = (VASSIGN, VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), tmp1); tree->print(stream); @@ -716,135 +811,146 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) { // process bauen der bei fail 0 ausgibt und bei accept 1 void ChartToVHDL::writeNextStateLogic(std::ostream & stream) { - stream << "-- state logic" << std::endl; - stream << "-- only gets active when state changes (microstep?) " << std::endl; - stream << "state_decode_proc: process(current_state)" << std::endl; + // stream << "-- state logic" << std::endl; + // stream << "-- only gets active when state changes (microstep?) " << std::endl; + // stream << "state_decode_proc: process(current_state)" << std::endl; + // stream << "begin" << std::endl; + // + // std::stringstream nextStateBuffer; + // for (size_t i = 0; i < _states.size(); i++) { + // Element state(_states[i]); + // + // // calculate event choices + // // _transitions is sorted in Postfix order + // // by stating with smalest index the most important + // // will be written first + // std::vector< Element > choices; + // std::string spntaneous_trans_sig = ""; + // for (size_t j = 0; j < _transitions.size(); j++) { + // Element transition(_transitions[j]); + // if (ATTR_CAST(transition.getParentNode(), "id") == ATTR(state, "id")) { + // choices.push_back(transition); + // if (ATTR(transition, "event") == CONST_TRANS_SPONTANIOUS) { + // spntaneous_trans_sig = ATTR(transition, "id"); + // // FIXME hofully there are just single spntaneous transitions allowed + // // else we have to handle this + // } + // } + // } + // + // // calculate incomming transitions (for later use) + // std::vector< Element > incommingTransitions; + // for (size_t j = 0; j < _transitions.size(); j++) { + // Element transition(_transitions[j]); + // if (ATTR_CAST(transition, "target") == ATTR(state, "id")) { + // incommingTransitions.push_back(transition); + // } + // } + // + // if (choices.size() > 0) {// if no outgoing transitions (maybe final state :D) we don't write anything + // + // stream << " if ( " << ATTR(state, "id") << " = '1' ) then" << std::endl; + // stream << " if ( transition_spntaneous_en = '1' ) then" << std::endl; + // // enable spntaneous transition (if any) and disable all other + // for (size_t j = 0; j < choices.size(); j++) { + // Element transition(choices[j]); + // if (ATTR(transition, "id") == spntaneous_trans_sig) { + // stream << " " << ATTR(transition, "id") << "_sig <= '1';" << std::endl; + // } else { + // stream << " " << ATTR(transition, "id") << "_sig <= '0';" << std::endl; + // } + // } + // + // stream << " elsif ( next_event_re = '1' ) then" << std::endl; + // // if no spntaneous transition enables, look at events + // // since there is just one event at a time, we use case statement + // // to check transitions matching in postfix order + // // FIXME hopefully there is just one transition per state and event at a time + // stream << " case next_event is" << std::endl; + // bool hasWildcardTransition = false; + // for (size_t j = 0; j < choices.size(); j++) { + // Element transition(choices[j]); + // std::string eventName = ATTR(transition, "event"); + // if (eventName == CONST_EVENT_ANY) { + // eventName = "others"; + // hasWildcardTransition = true; + // } + // stream << " when " << eventName << " =>" << std::endl; + // // activate transition and deactivete others + // for (size_t k = 0; k < choices.size(); k++) { + // Element tmp_t(choices[k]); + // if (ATTR(tmp_t, "event") == ATTR(transition, "event")) { + // stream << " " << ATTR(tmp_t, "id") << "_sig <= '1';" << std::endl; + // } else { + // stream << " " << ATTR(tmp_t, "id") << "_sig <= '0';" << std::endl; + // } + // } + // } + // if (!hasWildcardTransition) { + // // if there is no others we create one for deactivating everything + // stream << " when others =>" << std::endl; + // for (size_t j = 0; j < choices.size(); j++) { + // Element tmp_t(choices[j]); + // stream << " " << ATTR(tmp_t, "id") << "_sig <= '0';" << std::endl; + // } + // } + // stream << " end case;" << std::endl; + // //TODO umkehren oder other abfangen + // //stream << " when others =>" << std::endl; + // //stream << " next_state <= current_state;" << std::endl; + // + // stream << " else" << std::endl; + // // no enabled event ? disable all transitions (looks like we have to wait) + // for (size_t j = 0; j < choices.size(); j++) { + // Element transition(choices[j]); + // stream << " " << ATTR(transition, "id") << "_sig <= '0';" << std::endl; + // } + // stream << " end if;" << std::endl; + // stream << " end if;" << std::endl; + // stream << std::endl; + // } + // // write next state calculation in buffer for later use + // nextStateBuffer << ATTR(state, "id") << "_next <= ( ( '0'"; + // std::string seperator = " or "; + // for (size_t j = 0; j < incommingTransitions.size(); j++) { + // nextStateBuffer << seperator + // << ATTR(incommingTransitions[j], "id") << "_sig"; + // } + // nextStateBuffer << " ) or "; + // nextStateBuffer << "( ( not ( '0'"; + // seperator = " or "; + // for (size_t j = 0; j < choices.size(); j++) { + // nextStateBuffer << seperator + // << ATTR(choices[j], "id") << "_sig"; + // } + // nextStateBuffer << " ) ) and " << ATTR(state, "id") + // << "_curr ));" << std::endl; + // } + // stream << "end process;" << std::endl; + // stream << std::endl; + // // write outgoing transition buffer + // stream << nextStateBuffer.str() << std::endl; + + // updater for current state + stream << "-- update current state" << std::endl; + stream << "state_proc: process(clk, rst, stall)" << std::endl; stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; - std::stringstream nextStateBuffer; for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); + stream << " is_active_" << toStr(i) << "_sig <= " << "'0';" << std::endl; + } - // calculate event choices - // _transitions is sorted in Postfix order - // by stating with smalest index the most important - // will be written first - std::vector< Element > choices; - std::string spntaneous_trans_sig = ""; - for (size_t j = 0; j < _transitions.size(); j++) { - Element transition(_transitions[j]); - if (ATTR_CAST(transition.getParentNode(), "id") == ATTR(state, "id")) { - choices.push_back(transition); - if (ATTR(transition, "event") == CONST_TRANS_SPONTANIOUS) { - spntaneous_trans_sig = ATTR(transition, "id"); - // FIXME hofully there are just single spntaneous transitions allowed - // else we have to handle this - } - } - } - - // calculate incomming transitions (for later use) - std::vector< Element > incommingTransitions; - for (size_t j = 0; j < _transitions.size(); j++) { - Element transition(_transitions[j]); - if (ATTR_CAST(transition, "target") == ATTR(state, "id")) { - incommingTransitions.push_back(transition); - } - } - - if (choices.size() > 0) {// if no outgoing transitions (maybe final state :D) we don't write anything - - stream << " if ( " << ATTR(state, "id") << " = '1' ) then" << std::endl; - stream << " if ( transition_spntaneous_en = '1' ) then" << std::endl; - // enable spntaneous transition (if any) and disable all other - for (size_t j = 0; j < choices.size(); j++) { - Element transition(choices[j]); - if (ATTR(transition, "id") == spntaneous_trans_sig) { - stream << " " << ATTR(transition, "id") << "_sig <= '1';" << std::endl; - } else { - stream << " " << ATTR(transition, "id") << "_sig <= '0';" << std::endl; - } - } + stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; + stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; + stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - stream << " elsif ( next_event_re = '1' ) then" << std::endl; - // if no spntaneous transition enables, look at events - // since there is just one event at a time, we use case statement - // to check transitions matching in postfix order - // FIXME hopefully there is just one transition per state and event at a time - stream << " case next_event is" << std::endl; - bool hasWildcardTransition = false; - for (size_t j = 0; j < choices.size(); j++) { - Element transition(choices[j]); - std::string eventName = ATTR(transition, "event"); - if (eventName == CONST_EVENT_ANY) { - eventName = "others"; - hasWildcardTransition = true; - } - stream << " when " << eventName << " =>" << std::endl; - // activate transition and deactivete others - for (size_t k = 0; k < choices.size(); k++) { - Element tmp_t(choices[k]); - if (ATTR(tmp_t, "event") == ATTR(transition, "event")) { - stream << " " << ATTR(tmp_t, "id") << "_sig <= '1';" << std::endl; - } else { - stream << " " << ATTR(tmp_t, "id") << "_sig <= '0';" << std::endl; - } - } - } - if (!hasWildcardTransition) { - // if there is no others we create one for deactivating everything - stream << " when others =>" << std::endl; - for (size_t j = 0; j < choices.size(); j++) { - Element tmp_t(choices[j]); - stream << " " << ATTR(tmp_t, "id") << "_sig <= '0';" << std::endl; - } - } - stream << " end case;" << std::endl; - //TODO umkehren oder other abfangen - //stream << " when others =>" << std::endl; - //stream << " next_state <= current_state;" << std::endl; - - stream << " else" << std::endl; - // no enabled event ? disable all transitions (looks like we have to wait) - for (size_t j = 0; j < choices.size(); j++) { - Element transition(choices[j]); - stream << " " << ATTR(transition, "id") << "_sig <= '0';" << std::endl; - } - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << std::endl; - } - // write next state calculation in buffer for later use - nextStateBuffer << ATTR(state, "id") << "_next <= ( ( '0'"; - std::string seperator = " or "; - for (size_t j = 0; j < incommingTransitions.size(); j++) { - nextStateBuffer << seperator - << ATTR(incommingTransitions[j], "id") << "_sig"; - } - nextStateBuffer << " ) or "; - nextStateBuffer << "( ( not ( '0'"; - seperator = " or "; - for (size_t j = 0; j < choices.size(); j++) { - nextStateBuffer << seperator - << ATTR(choices[j], "id") << "_sig"; - } - nextStateBuffer << " ) ) and " << ATTR(state, "id") - << "_curr ));" << std::endl; + for (size_t i = 0; i < _states.size(); i++) { + Element state(_states[i]); + stream << " is_active_" << toStr(i) << "_sig <= " << "is_active_np1_" << toStr(i) << "_sig;" << std::endl; } - stream << "end process;" << std::endl; - stream << std::endl; - // write outgoing transition buffer - stream << nextStateBuffer.str() << std::endl; - // updater for current state - stream << "-- update current state" << std::endl; - stream << "state_proc: process(clk, rst, stall)" << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " current_state <= (others => '0');" << std::endl; -// stream << " " << _initState << "_curr <= '1';" << std::endl; - stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; - stream << " current_state <= next_state;" << std::endl; stream << " end if;" << std::endl; stream << "end process;" << std::endl; stream << std::endl; diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index 84d8f7f..a63cba2 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -180,6 +180,11 @@ protected: void writeFSM(std::ostream& stream); void writeTransitionSet(std::ostream & stream); + void writeActiveStateNplusOne(std::ostream & stream); + void writeDefaultCompletions(std::ostream & stream); + void writeCompleteEntrySet(std::ostream & stream); + + void writeTestbench(std::ostream & stream); Trie _eventTrie; @@ -191,4 +196,4 @@ private: } -#endif /* end of include guard: FSMTOCPP_H_201672B0 */ +#endif /* end of include guard: FSMTOCPP_H_201672B0 */ \ No newline at end of file diff --git a/test/src/test-c-inline.c b/test/src/test-c-inline.c index a4b237c..659fcdf 100644 --- a/test/src/test-c-inline.c +++ b/test/src/test-c-inline.c @@ -10,10 +10,16 @@ /** INLINE SCXML BEGIN + enteredFoo(); + + + enteredDone(); + + INLINE SCXML END */ @@ -24,15 +30,28 @@ void enteredFoo() { printf("Entered Foo!\n"); } +void enteredDone() { + printf("Entered Done!\n"); +} + +struct userData { + int foo; +}; + +#define UD ((struct userData*)ctx->user_data) #include "test-c-inline.c.scxml.c" + int main(int argc, char** argv) { - uscxml_ctx ctx; + struct userData ud; + uscxml_ctx ctx; int err = USCXML_ERR_OK; - + memset(&ctx, 0, sizeof(uscxml_ctx)); ctx.machine = &USCXML_MACHINE_TEST_INLINE; - + ctx.user_data = &ud; + ud.foo = 3; + while(err != USCXML_ERR_DONE) { err = uscxml_step(&ctx); } diff --git a/test/src/test-c-inline.c.scxml.c b/test/src/test-c-inline.c.scxml.c index 740d030..9bd1464 100644 --- a/test/src/test-c-inline.c.scxml.c +++ b/test/src/test-c-inline.c.scxml.c @@ -252,6 +252,7 @@ struct uscxml_transition { const char target[USCXML_MAX_NR_STATES_BYTES]; const char* event; const char* condition; + const is_enabled_t is_enabled; const exec_content_t on_transition; const unsigned char type; const char conflicts[USCXML_MAX_NR_TRANS_BYTES]; @@ -345,7 +346,6 @@ struct uscxml_ctx { dequeue_internal_t dequeue_internal; dequeue_external_t dequeue_external; - is_enabled_t is_enabled; is_matched_t is_matched; is_true_t is_true; raise_done_event_t raise_done_event; @@ -368,11 +368,11 @@ struct uscxml_ctx { #endif /* forward declare machines to allow references */ -extern const uscxml_machine _uscxml_9FAC9BE9_machine; +extern const uscxml_machine _uscxml_04E4C4CE_machine; #ifndef USCXML_NO_ELEM_INFO -static const uscxml_elem_donedata _uscxml_9FAC9BE9_elem_donedatas[1] = { +static const uscxml_elem_donedata _uscxml_04E4C4CE_elem_donedatas[1] = { /* source, content, contentexpr, params */ { 0, NULL, NULL, NULL } }; @@ -385,46 +385,73 @@ static const uscxml_elem_donedata _uscxml_9FAC9BE9_elem_donedatas[1] = { #ifndef USCXML_NO_EXEC_CONTENT -static int _uscxml_9FAC9BE9_foo_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { +static int _uscxml_04E4C4CE_foo_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { int err = USCXML_ERR_OK; enteredFoo(); return USCXML_ERR_OK; } -static int _uscxml_9FAC9BE9_foo_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - _uscxml_9FAC9BE9_foo_on_entry_0(ctx, state, event); +static int _uscxml_04E4C4CE_foo_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_04E4C4CE_foo_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } +static int _uscxml_04E4C4CE_done_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + + enteredDone(); + return USCXML_ERR_OK; +} + +static int _uscxml_04E4C4CE_done_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_04E4C4CE_done_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; +} + +static int _uscxml_04E4C4CE_foo_transition0_is_enabled(const uscxml_ctx* ctx, const uscxml_transition* transition) { + return (UD->foo == 3); +} #endif #ifndef USCXML_NO_ELEM_INFO -static const uscxml_state _uscxml_9FAC9BE9_states[2] = { +static const uscxml_state _uscxml_04E4C4CE_states[3] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x02 /* 01 */ }, - /* completion */ { 0x02 /* 01 */ }, - /* ancestors */ { 0x00 /* 00 */ }, + /* children */ { 0x06 /* 011 */ }, + /* completion */ { 0x02 /* 010 */ }, + /* ancestors */ { 0x00 /* 000 */ }, /* data */ NULL, /* type */ USCXML_STATE_COMPOUND, }, { /* state number 1 */ /* name */ "foo", /* parent */ 0, - /* onentry */ _uscxml_9FAC9BE9_foo_on_entry, + /* onentry */ _uscxml_04E4C4CE_foo_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00 */ }, - /* completion */ { 0x00 /* 00 */ }, - /* ancestors */ { 0x01 /* 10 */ }, + /* children */ { 0x00 /* 000 */ }, + /* completion */ { 0x00 /* 000 */ }, + /* ancestors */ { 0x01 /* 100 */ }, /* data */ NULL, /* type */ USCXML_STATE_ATOMIC, + }, + { /* state number 2 */ + /* name */ "done", + /* parent */ 0, + /* onentry */ _uscxml_04E4C4CE_done_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 000 */ }, + /* completion */ { 0x00 /* 000 */ }, + /* ancestors */ { 0x01 /* 100 */ }, + /* data */ NULL, + /* type */ USCXML_STATE_FINAL, } }; @@ -432,27 +459,43 @@ static const uscxml_state _uscxml_9FAC9BE9_states[2] = { #ifndef USCXML_NO_ELEM_INFO +static const uscxml_transition _uscxml_04E4C4CE_transitions[1] = { + { /* transition number 0 with priority 0 + target: done + */ + /* source */ 1, + /* target */ { 0x04 /* 001 */ }, + /* event */ NULL, + /* condition */ "UD->foo == 3", + /* is_enabled */ _uscxml_04E4C4CE_foo_transition0_is_enabled, + /* ontrans */ NULL, + /* type */ USCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0x01 /* 1 */ }, + /* exit set */ { 0x06 /* 011 */ } + } +}; + #endif #ifndef USCXML_NO_ELEM_INFO #ifndef USCXML_MACHINE -# define USCXML_MACHINE _uscxml_9FAC9BE9_machine +# define USCXML_MACHINE _uscxml_04E4C4CE_machine #endif -#define USCXML_MACHINE_0 _uscxml_9FAC9BE9_machine -#define USCXML_MACHINE_TEST_INLINE _uscxml_9FAC9BE9_machine +#define USCXML_MACHINE_0 _uscxml_04E4C4CE_machine +#define USCXML_MACHINE_TEST_INLINE _uscxml_04E4C4CE_machine -const uscxml_machine _uscxml_9FAC9BE9_machine = { +const uscxml_machine _uscxml_04E4C4CE_machine = { /* flags */ 0, - /* nr_states */ 2, - /* nr_transitions */ 0, + /* nr_states */ 3, + /* nr_transitions */ 1, /* name */ "test-inline", /* datamodel */ "native", - /* uuid */ "9FAC9BE9A82F66AFD36A205557064B27", - /* states */ &_uscxml_9FAC9BE9_states[0], - /* transitions */ NULL, + /* uuid */ "04E4C4CEB25F6A7D5638FCE2C3213285", + /* states */ &_uscxml_04E4C4CE_states[0], + /* transitions */ &_uscxml_04E4C4CE_transitions[0], /* parent */ NULL, - /* donedata */ &_uscxml_9FAC9BE9_elem_donedatas[0], + /* donedata */ &_uscxml_04E4C4CE_elem_donedatas[0], /* script */ NULL }; @@ -666,7 +709,8 @@ SELECT_TRANSITIONS: (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) { /* is it enabled? */ if ((ctx->event == NULL || ctx->is_matched(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) && - (USCXML_GET_TRANS(i).condition == NULL || ctx->is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) { + (USCXML_GET_TRANS(i).condition == NULL || + USCXML_GET_TRANS(i).is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) { /* remember that we found a transition */ ctx->flags |= USCXML_CTX_TRANSITION_FOUND; diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index f78e970..d069cfe 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -65,7 +65,6 @@ public: ctx.user_data = (void*)this; // register callbacks with scxml context - ctx.is_enabled = &isEnabled; ctx.is_matched = &isMatched; ctx.is_true = &isTrue; ctx.raise_done_event = &raiseDoneEvent; @@ -256,12 +255,6 @@ public: return (nameMatch(t->event, event->name.c_str())); } - static int isEnabled(const uscxml_ctx* ctx, const uscxml_transition* t) { - if (t->condition != NULL) - return isTrue(ctx, t->condition); - return 1; - } - static int isTrue(const uscxml_ctx* ctx, const char* expr) { try { return USER_DATA(ctx)->dataModel.evalAsBool(expr); diff --git a/test/src/test-c-machine.scxml.c b/test/src/test-c-machine.scxml.c index 6378096..b75c6a5 100644 --- a/test/src/test-c-machine.scxml.c +++ b/test/src/test-c-machine.scxml.c @@ -1,6 +1,6 @@ /** Generated from source: - file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test326.scxml + file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test144.scxml */ #ifndef USCXML_NO_STDTYPES_H @@ -252,6 +252,7 @@ struct uscxml_transition { const char target[USCXML_MAX_NR_STATES_BYTES]; const char* event; const char* condition; + const is_enabled_t is_enabled; const exec_content_t on_transition; const unsigned char type; const char conflicts[USCXML_MAX_NR_TRANS_BYTES]; @@ -345,7 +346,6 @@ struct uscxml_ctx { dequeue_internal_t dequeue_internal; dequeue_external_t dequeue_external; - is_enabled_t is_enabled; is_matched_t is_matched; is_true_t is_true; raise_done_event_t raise_done_event; @@ -368,24 +368,11 @@ struct uscxml_ctx { #endif /* forward declare machines to allow references */ -extern const uscxml_machine _uscxml_EC83C2A5_machine; +extern const uscxml_machine _uscxml_7B67993D_machine; #ifndef USCXML_NO_ELEM_INFO -static const uscxml_elem_assign _uscxml_EC83C2A5_elem_assigns[2] = { - /* location, expr, content */ - { "_ioprocessors", "'otherName'", NULL }, - { "Var2", "_ioprocessors", NULL }, -}; - -static const uscxml_elem_data _uscxml_EC83C2A5_elem_datas[3] = { - /* id, src, expr, content */ - { "Var1", NULL, "_ioprocessors", NULL }, - { "Var2", NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL } -}; - -static const uscxml_elem_donedata _uscxml_EC83C2A5_elem_donedatas[1] = { +static const uscxml_elem_donedata _uscxml_7B67993D_elem_donedatas[1] = { /* source, content, contentexpr, params */ { 0, NULL, NULL, NULL } }; @@ -398,42 +385,27 @@ static const uscxml_elem_donedata _uscxml_EC83C2A5_elem_donedatas[1] = { #ifndef USCXML_NO_EXEC_CONTENT -static int _uscxml_EC83C2A5_s1_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { +static int _uscxml_7B67993D_s0_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { int err = USCXML_ERR_OK; - if likely(ctx->exec_content_assign != NULL) { - if ((ctx->exec_content_assign(ctx, &_uscxml_EC83C2A5_elem_assigns[0])) != USCXML_ERR_OK) return err; - } else { - return USCXML_ERR_MISSING_CALLBACK; - } if likely(ctx->exec_content_raise != NULL) { if unlikely((ctx->exec_content_raise(ctx, "foo")) != USCXML_ERR_OK) return err; } else { return USCXML_ERR_MISSING_CALLBACK; } - return USCXML_ERR_OK; -} - -static int _uscxml_EC83C2A5_s1_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - _uscxml_EC83C2A5_s1_on_entry_0(ctx, state, event); - return USCXML_ERR_OK; -} - -static int _uscxml_EC83C2A5_s2_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - int err = USCXML_ERR_OK; - if likely(ctx->exec_content_assign != NULL) { - if ((ctx->exec_content_assign(ctx, &_uscxml_EC83C2A5_elem_assigns[1])) != USCXML_ERR_OK) return err; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "bar")) != USCXML_ERR_OK) return err; } else { return USCXML_ERR_MISSING_CALLBACK; } return USCXML_ERR_OK; } -static int _uscxml_EC83C2A5_s2_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - _uscxml_EC83C2A5_s2_on_entry_0(ctx, state, event); +static int _uscxml_7B67993D_s0_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_7B67993D_s0_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } -static int _uscxml_EC83C2A5_pass_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { +static int _uscxml_7B67993D_pass_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { int err = USCXML_ERR_OK; if likely(ctx->exec_content_log != NULL) { if unlikely((ctx->exec_content_log(ctx, "Outcome", "'pass'")) != USCXML_ERR_OK) return err; @@ -443,12 +415,12 @@ static int _uscxml_EC83C2A5_pass_on_entry_0(const uscxml_ctx* ctx, const uscxml_ return USCXML_ERR_OK; } -static int _uscxml_EC83C2A5_pass_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - _uscxml_EC83C2A5_pass_on_entry_0(ctx, state, event); +static int _uscxml_7B67993D_pass_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_7B67993D_pass_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } -static int _uscxml_EC83C2A5_fail_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { +static int _uscxml_7B67993D_fail_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { int err = USCXML_ERR_OK; if likely(ctx->exec_content_log != NULL) { if unlikely((ctx->exec_content_log(ctx, "Outcome", "'fail'")) != USCXML_ERR_OK) return err; @@ -458,8 +430,8 @@ static int _uscxml_EC83C2A5_fail_on_entry_0(const uscxml_ctx* ctx, const uscxml_ return USCXML_ERR_OK; } -static int _uscxml_EC83C2A5_fail_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { - _uscxml_EC83C2A5_fail_on_entry_0(ctx, state, event); +static int _uscxml_7B67993D_fail_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_7B67993D_fail_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } @@ -467,76 +439,64 @@ static int _uscxml_EC83C2A5_fail_on_entry(const uscxml_ctx* ctx, const uscxml_st #ifndef USCXML_NO_ELEM_INFO -static const uscxml_state _uscxml_EC83C2A5_states[6] = { +static const uscxml_state _uscxml_7B67993D_states[5] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x3e /* 011111 */ }, - /* completion */ { 0x02 /* 010000 */ }, - /* ancestors */ { 0x00 /* 000000 */ }, - /* data */ &_uscxml_EC83C2A5_elem_datas[0], + /* children */ { 0x1e /* 01111 */ }, + /* completion */ { 0x02 /* 01000 */ }, + /* ancestors */ { 0x00 /* 00000 */ }, + /* data */ NULL, /* type */ USCXML_STATE_COMPOUND, }, { /* state number 1 */ /* name */ "s0", /* parent */ 0, - /* onentry */ NULL, + /* onentry */ _uscxml_7B67993D_s0_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 000000 */ }, - /* completion */ { 0x00 /* 000000 */ }, - /* ancestors */ { 0x01 /* 100000 */ }, + /* children */ { 0x00 /* 00000 */ }, + /* completion */ { 0x00 /* 00000 */ }, + /* ancestors */ { 0x01 /* 10000 */ }, /* data */ NULL, /* type */ USCXML_STATE_ATOMIC, }, { /* state number 2 */ /* name */ "s1", /* parent */ 0, - /* onentry */ _uscxml_EC83C2A5_s1_on_entry, + /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 000000 */ }, - /* completion */ { 0x00 /* 000000 */ }, - /* ancestors */ { 0x01 /* 100000 */ }, + /* children */ { 0x00 /* 00000 */ }, + /* completion */ { 0x00 /* 00000 */ }, + /* ancestors */ { 0x01 /* 10000 */ }, /* data */ NULL, /* type */ USCXML_STATE_ATOMIC, }, { /* state number 3 */ - /* name */ "s2", - /* parent */ 0, - /* onentry */ _uscxml_EC83C2A5_s2_on_entry, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x00 /* 000000 */ }, - /* completion */ { 0x00 /* 000000 */ }, - /* ancestors */ { 0x01 /* 100000 */ }, - /* data */ NULL, - /* type */ USCXML_STATE_ATOMIC, - }, - { /* state number 4 */ /* name */ "pass", /* parent */ 0, - /* onentry */ _uscxml_EC83C2A5_pass_on_entry, + /* onentry */ _uscxml_7B67993D_pass_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 000000 */ }, - /* completion */ { 0x00 /* 000000 */ }, - /* ancestors */ { 0x01 /* 100000 */ }, + /* children */ { 0x00 /* 00000 */ }, + /* completion */ { 0x00 /* 00000 */ }, + /* ancestors */ { 0x01 /* 10000 */ }, /* data */ NULL, /* type */ USCXML_STATE_FINAL, }, - { /* state number 5 */ + { /* state number 4 */ /* name */ "fail", /* parent */ 0, - /* onentry */ _uscxml_EC83C2A5_fail_on_entry, + /* onentry */ _uscxml_7B67993D_fail_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 000000 */ }, - /* completion */ { 0x00 /* 000000 */ }, - /* ancestors */ { 0x01 /* 100000 */ }, + /* children */ { 0x00 /* 00000 */ }, + /* completion */ { 0x00 /* 00000 */ }, + /* ancestors */ { 0x01 /* 10000 */ }, /* data */ NULL, /* type */ USCXML_STATE_FINAL, } @@ -546,78 +506,58 @@ static const uscxml_state _uscxml_EC83C2A5_states[6] = { #ifndef USCXML_NO_ELEM_INFO -static const uscxml_transition _uscxml_EC83C2A5_transitions[6] = { +static const uscxml_transition _uscxml_7B67993D_transitions[4] = { { /* transition number 0 with priority 0 target: s1 */ /* source */ 1, - /* target */ { 0x04 /* 001000 */ }, - /* event */ NULL, - /* condition */ "Var1", + /* target */ { 0x04 /* 00100 */ }, + /* event */ "foo", + /* condition */ NULL, + /* is_enabled */ NULL, /* ontrans */ NULL, - /* type */ USCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } + /* type */ 0, + /* conflicts */ { 0x0f /* 1111 */ }, + /* exit set */ { 0x1e /* 01111 */ } }, { /* transition number 1 with priority 1 target: fail */ /* source */ 1, - /* target */ { 0x20 /* 000001 */ }, - /* event */ NULL, - /* condition */ "true", + /* target */ { 0x10 /* 00001 */ }, + /* event */ "*", + /* condition */ NULL, + /* is_enabled */ NULL, /* ontrans */ NULL, - /* type */ USCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } + /* type */ 0, + /* conflicts */ { 0x0f /* 1111 */ }, + /* exit set */ { 0x1e /* 01111 */ } }, { /* transition number 2 with priority 2 - target: s2 + target: pass */ /* source */ 2, - /* target */ { 0x08 /* 000100 */ }, - /* event */ "error.execution", + /* target */ { 0x08 /* 00010 */ }, + /* event */ "bar", /* condition */ NULL, + /* is_enabled */ NULL, /* ontrans */ NULL, /* type */ 0, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } + /* conflicts */ { 0x0f /* 1111 */ }, + /* exit set */ { 0x1e /* 01111 */ } }, { /* transition number 3 with priority 3 target: fail */ /* source */ 2, - /* target */ { 0x20 /* 000001 */ }, + /* target */ { 0x10 /* 00001 */ }, /* event */ "*", /* condition */ NULL, + /* is_enabled */ NULL, /* ontrans */ NULL, /* type */ 0, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } - }, - { /* transition number 4 with priority 4 - target: pass - */ - /* source */ 3, - /* target */ { 0x10 /* 000010 */ }, - /* event */ NULL, - /* condition */ "Var1==Var2", - /* ontrans */ NULL, - /* type */ USCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } - }, - { /* transition number 5 with priority 5 - target: fail - */ - /* source */ 3, - /* target */ { 0x20 /* 000001 */ }, - /* event */ NULL, - /* condition */ NULL, - /* ontrans */ NULL, - /* type */ USCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 111111 */ }, - /* exit set */ { 0x3e /* 011111 */ } + /* conflicts */ { 0x0f /* 1111 */ }, + /* exit set */ { 0x1e /* 01111 */ } } }; @@ -626,22 +566,21 @@ static const uscxml_transition _uscxml_EC83C2A5_transitions[6] = { #ifndef USCXML_NO_ELEM_INFO #ifndef USCXML_MACHINE -# define USCXML_MACHINE _uscxml_EC83C2A5_machine +# define USCXML_MACHINE _uscxml_7B67993D_machine #endif -#define USCXML_MACHINE_0 _uscxml_EC83C2A5_machine -#define USCXML_MACHINE_MACHINENAME _uscxml_EC83C2A5_machine +#define USCXML_MACHINE_0 _uscxml_7B67993D_machine -const uscxml_machine _uscxml_EC83C2A5_machine = { +const uscxml_machine _uscxml_7B67993D_machine = { /* flags */ 0, - /* nr_states */ 6, - /* nr_transitions */ 6, - /* name */ "machineName", + /* nr_states */ 5, + /* nr_transitions */ 4, + /* name */ "", /* datamodel */ "ecmascript", - /* uuid */ "EC83C2A5BDF05B11A1F7E2C35039F65D", - /* states */ &_uscxml_EC83C2A5_states[0], - /* transitions */ &_uscxml_EC83C2A5_transitions[0], + /* uuid */ "7B67993D8309FD356AECB23C2C98EE79", + /* states */ &_uscxml_7B67993D_states[0], + /* transitions */ &_uscxml_7B67993D_transitions[0], /* parent */ NULL, - /* donedata */ &_uscxml_EC83C2A5_elem_donedatas[0], + /* donedata */ &_uscxml_7B67993D_elem_donedatas[0], /* script */ NULL }; @@ -755,7 +694,7 @@ static void bit_and(char* dest, const char* mask, size_t i) { #ifndef USCXML_NO_STEP_FUNCTION int uscxml_step(uscxml_ctx* ctx) { - USCXML_NR_TRANS_TYPE i, j, k; + USCXML_NR_STATES_TYPE i, j, k; USCXML_NR_STATES_TYPE nr_states_bytes = ((USCXML_NUMBER_STATES + 7) & ~7) >> 3; USCXML_NR_TRANS_TYPE nr_trans_bytes = ((USCXML_NUMBER_TRANS + 7) & ~7) >> 3; int err = USCXML_ERR_OK; @@ -855,7 +794,7 @@ SELECT_TRANSITIONS: (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) { /* is it enabled? */ if ((ctx->event == NULL || ctx->is_matched(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) && - (USCXML_GET_TRANS(i).condition == NULL || ctx->is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) { + (USCXML_GET_TRANS(i).condition == NULL || USCXML_GET_TRANS(i).is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) { /* remember that we found a transition */ ctx->flags |= USCXML_CTX_TRANSITION_FOUND; -- cgit v0.12