4 * Instruction re-writer
6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author Mykola Ostrovskyy <spambox03@mail.ru>
10 if (!class_exists('instruction_rewriter', false)) {
12 class instruction_rewriter
{
19 function instruction_rewriter() {
20 $this->correction
= array();
26 function addCorrections($correction) {
27 foreach ($correction as $c) {
28 $this->correction
[$c->getIndex()][] = $c;
35 function process(&$instruction) {
36 if (count($this->correction
) > 0) {
37 $index = $this->_getCorrectionIndex();
38 $corrections = count($index);
39 $instructions = count($instruction);
41 for ($c = 0, $i = 0; $c < $corrections; $c++
, $i++
) {
42 /* Copy all instructions that are before the next correction */
43 for ( ; $i < $index[$c]; $i++
) {
44 $output[] = $instruction[$i];
46 /* Apply the corrections */
47 $preventDefault = false;
48 foreach ($this->correction
[$i] as $correction) {
49 $preventDefault = ($preventDefault ||
$correction->apply($instruction, $output));
51 if (!$preventDefault) {
52 $output[] = $instruction[$i];
55 /* Copy the rest of instructions after the last correction */
56 for ( ; $i < $instructions; $i++
) {
57 $output[] = $instruction[$i];
60 if (array_key_exists(-1, $this->correction
)) {
61 $this->correction
[-1]->apply($instruction, $output);
63 $instruction = $output;
70 function _getCorrectionIndex() {
71 $result = array_keys($this->correction
);
74 if (reset($result) == -1) {
75 unset($result[key($result)]);
77 return array_values($result);
81 class instruction_rewriter_correction
{
88 function instruction_rewriter_correction($index) {
89 $this->index
= $index;
100 class instruction_rewriter_delete
extends instruction_rewriter_correction
{
105 function instruction_rewriter_delete($index) {
106 parent
::instruction_rewriter_correction($index);
112 function apply($input, &$output) {
117 class instruction_rewriter_call_list
extends instruction_rewriter_correction
{
124 function instruction_rewriter_call_list($index) {
125 parent
::instruction_rewriter_correction($index);
126 $this->call
= array();
132 function addCall($name, $data) {
133 $this->call
[] = array($name, $data);
139 function addPluginCall($name, $data, $state, $text = '') {
140 $this->call
[] = array('plugin', array($name, $data, $state, $text));
146 function appendCalls(&$output, $position) {
147 foreach ($this->call
as $call) {
148 $output[] = array($call[0], $call[1], $position);
153 class instruction_rewriter_insert
extends instruction_rewriter_call_list
{
158 function instruction_rewriter_insert($index) {
159 parent
::instruction_rewriter_call_list($index);
165 function apply($input, &$output) {
166 $this->appendCalls($output, $input[$this->index
][2]);
171 class instruction_rewriter_append
extends instruction_rewriter_call_list
{
176 function instruction_rewriter_append() {
177 parent
::instruction_rewriter_call_list(-1);
183 function apply($input, &$output) {
184 $lastCall = end($output);
185 $this->appendCalls($output, $lastCall[2]);