-//\r
-// assembly: System\r
-// namespace: System.Text.RegularExpressions\r
-// file: compiler.cs\r
-//\r
-// author: Dan Lewis (dlewis@gmx.co.uk)\r
-// (c) 2002\r
-\r
-using System;\r
-using System.Collections;\r
-\r
-namespace System.Text.RegularExpressions {\r
- abstract class LinkRef {\r
- // empty\r
- }\r
- \r
- interface ICompiler {\r
- void Reset ();\r
- IMachineFactory GetMachineFactory ();\r
-\r
- // instruction emission\r
-\r
- void EmitFalse ();\r
- void EmitTrue ();\r
-\r
- // character matching\r
-\r
- void EmitCharacter (char c, bool negate, bool ignore, bool reverse);\r
- void EmitCategory (Category cat, bool negate, bool reverse);\r
- void EmitRange (char lo, char hi, bool negate, bool ignore, bool reverse);\r
- void EmitSet (char lo, BitArray set, bool negate, bool ignore, bool reverse);\r
-\r
- // other operators\r
-\r
- void EmitString (string str, bool ignore, bool reverse);\r
- void EmitPosition (Position pos);\r
- void EmitOpen (int gid);\r
- void EmitClose (int gid);\r
- void EmitBalance (int gid, int balance);\r
- void EmitReference (int gid, bool ignore, bool reverse);\r
-\r
- // constructs\r
-\r
- void EmitIfDefined (int gid, LinkRef tail);\r
- void EmitSub (LinkRef tail);\r
- void EmitTest (LinkRef yes, LinkRef tail);\r
- void EmitBranch (LinkRef next);\r
- void EmitJump (LinkRef target);\r
- void EmitRepeat (int min, int max, bool lazy, LinkRef until);\r
- void EmitUntil (LinkRef repeat);\r
- void EmitIn (LinkRef tail);\r
- void EmitInfo (int count, int min, int max);\r
- void EmitFastRepeat (int min, int max, bool lazy, LinkRef tail);\r
- void EmitAnchor (bool reverse, int offset, LinkRef tail);\r
-\r
- // event for the CILCompiler\r
- void EmitBranchEnd();\r
- void EmitAlternationEnd();\r
-\r
- LinkRef NewLink ();\r
- void ResolveLink (LinkRef link);\r
- }\r
-\r
- class InterpreterFactory : IMachineFactory {\r
- public InterpreterFactory (ushort[] pattern) {\r
- this.pattern = pattern;\r
- }\r
- \r
- public IMachine NewInstance () {\r
- return new Interpreter (pattern);\r
- }\r
-\r
- public int GroupCount {\r
- get { return pattern[0]; }\r
- }\r
-\r
- public IDictionary Mapping {\r
- get { return mapping; }\r
- set { mapping = value; }\r
- }\r
-\r
- private IDictionary mapping;\r
- private ushort[] pattern;\r
- }\r
-\r
- class PatternCompiler : ICompiler {\r
- public static ushort EncodeOp (OpCode op, OpFlags flags) {\r
- return (ushort)((int)op | ((int)flags & 0xff00));\r
- }\r
-\r
- public static void DecodeOp (ushort word, out OpCode op, out OpFlags flags) {\r
- op = (OpCode)(word & 0x00ff);\r
- flags = (OpFlags)(word & 0xff00);\r
- }\r
-\r
- public PatternCompiler () {\r
- pgm = new ArrayList ();\r
- }\r
-\r
- // ICompiler implementation\r
-\r
- public void Reset () {\r
- pgm.Clear ();\r
- }\r
-\r
- public IMachineFactory GetMachineFactory () {\r
- ushort[] image = new ushort[pgm.Count];\r
- pgm.CopyTo (image);\r
-\r
- return new InterpreterFactory (image);\r
- }\r
-\r
- public void EmitFalse () {\r
- Emit (OpCode.False);\r
- }\r
-\r
- public void EmitTrue () {\r
- Emit (OpCode.True);\r
- }\r
-\r
- public void EmitCharacter (char c, bool negate, bool ignore, bool reverse) {\r
- Emit (OpCode.Character, MakeFlags (negate, ignore, reverse, false));\r
-\r
- if (ignore)\r
- c = Char.ToLower (c);\r
-\r
- Emit ((ushort)c);\r
- }\r
-\r
- public void EmitCategory (Category cat, bool negate, bool reverse) {\r
- Emit (OpCode.Category, MakeFlags (negate, false, reverse, false));\r
- Emit ((ushort)cat);\r
- }\r
-\r
- public void EmitRange (char lo, char hi, bool negate, bool ignore, bool reverse) {\r
- Emit (OpCode.Range, MakeFlags (negate, ignore, reverse, false));\r
- Emit ((ushort)lo);\r
- Emit ((ushort)hi);\r
- }\r
-\r
- public void EmitSet (char lo, BitArray set, bool negate, bool ignore, bool reverse) {\r
- Emit (OpCode.Set, MakeFlags (negate, ignore, reverse, false));\r
- Emit ((ushort)lo);\r
-\r
- int len = (set.Length + 0xf) >> 4;\r
- Emit ((ushort)len);\r
-\r
- int b = 0;\r
- while (len -- != 0) {\r
- ushort word = 0;\r
- for (int i = 0; i < 16; ++ i) {\r
- if (b >= set.Length)\r
- break;\r
- \r
- if (set[b ++])\r
- word |= (ushort)(1 << i);\r
- }\r
-\r
- Emit (word);\r
- }\r
- }\r
-\r
- public void EmitString (string str, bool ignore, bool reverse) {\r
- Emit (OpCode.String, MakeFlags (false, ignore, reverse, false));\r
- int len = str.Length;\r
- Emit ((ushort)len);\r
-\r
- if (ignore)\r
- str = str.ToLower ();\r
- \r
- for (int i = 0; i < len; ++ i)\r
- Emit ((ushort)str[i]);\r
- }\r
-\r
- public void EmitPosition (Position pos) {\r
- Emit (OpCode.Position, 0);\r
- Emit ((ushort)pos);\r
- }\r
-\r
- public void EmitOpen (int gid) {\r
- Emit (OpCode.Open);\r
- Emit ((ushort)gid);\r
- }\r
-\r
- public void EmitClose (int gid) {\r
- Emit (OpCode.Close);\r
- Emit ((ushort)gid);\r
- }\r
-\r
- public void EmitBalance (int gid, int balance) {\r
- Emit (OpCode.Balance);\r
- Emit ((ushort)gid);\r
- Emit ((ushort)balance);\r
- }\r
-\r
- public void EmitReference (int gid, bool ignore, bool reverse) {\r
- Emit (OpCode.Reference, MakeFlags (false, ignore, reverse, false));\r
- Emit ((ushort)gid);\r
- }\r
-\r
- public void EmitIfDefined (int gid, LinkRef tail) {\r
- BeginLink (tail);\r
- Emit (OpCode.IfDefined);\r
- EmitLink (tail);\r
- Emit ((ushort)gid);\r
- }\r
-\r
- public void EmitSub (LinkRef tail) {\r
- BeginLink (tail);\r
- Emit (OpCode.Sub);\r
- EmitLink (tail);\r
- }\r
-\r
- public void EmitTest (LinkRef yes, LinkRef tail) {\r
- BeginLink (yes);\r
- BeginLink (tail);\r
- Emit (OpCode.Test);\r
- EmitLink (yes);\r
- EmitLink (tail);\r
- }\r
-\r
- public void EmitBranch (LinkRef next) {\r
- BeginLink (next);\r
- Emit (OpCode.Branch, 0);\r
- EmitLink (next);\r
- }\r
-\r
- public void EmitJump (LinkRef target) {\r
- BeginLink (target);\r
- Emit (OpCode.Jump, 0);\r
- EmitLink (target);\r
- }\r
-\r
- public void EmitRepeat (int min, int max, bool lazy, LinkRef until) {\r
- BeginLink (until);\r
- Emit (OpCode.Repeat, MakeFlags (false, false, false, lazy));\r
- EmitLink (until);\r
- Emit ((ushort)min);\r
- Emit ((ushort)max);\r
- }\r
-\r
- public void EmitUntil (LinkRef repeat) {\r
- ResolveLink (repeat);\r
- Emit (OpCode.Until);\r
- }\r
-\r
- public void EmitFastRepeat (int min, int max, bool lazy, LinkRef tail) {\r
- BeginLink (tail);\r
- Emit (OpCode.FastRepeat, MakeFlags (false, false, false, lazy));\r
- EmitLink (tail);\r
- Emit ((ushort)min);\r
- Emit ((ushort)max);\r
- }\r
-\r
- public void EmitIn (LinkRef tail) {\r
- BeginLink (tail);\r
- Emit (OpCode.In);\r
- EmitLink (tail);\r
- }\r
-\r
- public void EmitAnchor (bool reverse, int offset, LinkRef tail) {\r
- BeginLink (tail);\r
- Emit (OpCode.Anchor, MakeFlags(false, false, reverse, false));\r
- EmitLink (tail);\r
- Emit ((ushort)offset);\r
- }\r
-\r
- public void EmitInfo (int count, int min, int max) {\r
- Emit (OpCode.Info);\r
- Emit ((ushort)count);\r
- Emit ((ushort)min);\r
- Emit ((ushort)max);\r
- }\r
-\r
- public LinkRef NewLink () {\r
- return new PatternLinkStack ();\r
- }\r
- \r
- public void ResolveLink (LinkRef lref) {\r
- PatternLinkStack stack = (PatternLinkStack)lref;\r
- \r
- while (stack.Pop ())\r
- pgm[stack.OffsetAddress] = (ushort)stack.GetOffset (CurrentAddress);\r
- }\r
-\r
- public void EmitBranchEnd(){}\r
- public void EmitAlternationEnd(){}\r
-\r
- // private members\r
-\r
- private static OpFlags MakeFlags (bool negate, bool ignore, bool reverse, bool lazy) {\r
- OpFlags flags = 0;\r
- if (negate) flags |= OpFlags.Negate;\r
- if (ignore) flags |= OpFlags.IgnoreCase;\r
- if (reverse) flags |= OpFlags.RightToLeft;\r
- if (lazy) flags |= OpFlags.Lazy;\r
-\r
- return flags;\r
- }\r
- \r
- private void Emit (OpCode op) {\r
- Emit (op, (OpFlags)0);\r
- }\r
-\r
- private void Emit (OpCode op, OpFlags flags) {\r
- Emit (EncodeOp (op, flags));\r
- }\r
-\r
- private void Emit (ushort word) {\r
- pgm.Add (word);\r
- }\r
-\r
- private int CurrentAddress {\r
- get { return pgm.Count; }\r
- }\r
-\r
- private void BeginLink (LinkRef lref) {\r
- PatternLinkStack stack = (PatternLinkStack)lref;\r
- stack.BaseAddress = CurrentAddress;\r
- }\r
-\r
- private void EmitLink (LinkRef lref) {\r
- PatternLinkStack stack = (PatternLinkStack)lref;\r
- stack.OffsetAddress = CurrentAddress;\r
- Emit ((ushort)0); // placeholder\r
- stack.Push ();\r
- }\r
-\r
-\r
- private class PatternLinkStack : LinkStack {\r
- public PatternLinkStack () {\r
- }\r
- \r
- public int BaseAddress {\r
- set { link.base_addr = value; }\r
- }\r
-\r
- public int OffsetAddress {\r
- get { return link.offset_addr; }\r
- set { link.offset_addr = value; }\r
- }\r
-\r
- public int GetOffset (int target_addr) {\r
- return target_addr - link.base_addr;\r
- }\r
-\r
- // LinkStack implementation\r
-\r
- protected override object GetCurrent () { return link; }\r
- protected override void SetCurrent (object l) { link = (Link)l; }\r
-\r
- private struct Link {\r
- public int base_addr;\r
- public int offset_addr;\r
- }\r
-\r
- Link link;\r
- }\r
-\r
- private ArrayList pgm;\r
- }\r
-\r
- abstract class LinkStack : LinkRef {\r
- public LinkStack () {\r
- stack = new Stack ();\r
- }\r
-\r
- public void Push () {\r
- stack.Push (GetCurrent ());\r
- }\r
-\r
- public bool Pop () {\r
- if (stack.Count > 0) {\r
- SetCurrent (stack.Pop ());\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
- protected abstract object GetCurrent ();\r
- protected abstract void SetCurrent (object l);\r
-\r
- private Stack stack;\r
- }\r
-\r
- //Used by CILCompiler and Interpreter\r
- internal struct Mark {\r
- public int Start, End;\r
- public int Previous;\r
- \r
- public bool IsDefined {\r
- get { return Start >= 0 && End >= 0; }\r
- }\r
- \r
- public int Index {\r
- get { return Start < End ? Start : End; }\r
- }\r
- \r
- public int Length {\r
- get { return Start < End ? End - Start : Start - End; }\r
- }\r
- }\r
-\r
-}\r
+//
+// assembly: System
+// namespace: System.Text.RegularExpressions
+// file: compiler.cs
+//
+// author: Dan Lewis (dlewis@gmx.co.uk)
+// (c) 2002
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace System.Text.RegularExpressions {
+ abstract class LinkRef {
+ // empty
+ }
+
+ interface ICompiler {
+ void Reset ();
+ IMachineFactory GetMachineFactory ();
+
+ // instruction emission
+
+ void EmitFalse ();
+ void EmitTrue ();
+
+ // character matching
+
+ void EmitCharacter (char c, bool negate, bool ignore, bool reverse);
+ void EmitCategory (Category cat, bool negate, bool reverse);
+ void EmitNotCategory (Category cat, bool negate, bool reverse);
+ void EmitRange (char lo, char hi, bool negate, bool ignore, bool reverse);
+ void EmitSet (char lo, BitArray set, bool negate, bool ignore, bool reverse);
+
+ // other operators
+
+ void EmitString (string str, bool ignore, bool reverse);
+ void EmitPosition (Position pos);
+ void EmitOpen (int gid);
+ void EmitClose (int gid);
+ void EmitBalanceStart(int gid, int balance, bool capture, LinkRef tail);
+ void EmitBalance ();
+ void EmitReference (int gid, bool ignore, bool reverse);
+
+ // constructs
+
+ void EmitIfDefined (int gid, LinkRef tail);
+ void EmitSub (LinkRef tail);
+ void EmitTest (LinkRef yes, LinkRef tail);
+ void EmitBranch (LinkRef next);
+ void EmitJump (LinkRef target);
+ void EmitRepeat (int min, int max, bool lazy, LinkRef until);
+ void EmitUntil (LinkRef repeat);
+ void EmitIn (LinkRef tail);
+ void EmitInfo (int count, int min, int max);
+ void EmitFastRepeat (int min, int max, bool lazy, LinkRef tail);
+ void EmitAnchor (bool reverse, int offset, LinkRef tail);
+
+ // event for the CILCompiler
+ void EmitBranchEnd();
+ void EmitAlternationEnd();
+
+ LinkRef NewLink ();
+ void ResolveLink (LinkRef link);
+ }
+
+ class InterpreterFactory : IMachineFactory {
+ public InterpreterFactory (ushort[] pattern) {
+ this.pattern = pattern;
+ }
+
+ public IMachine NewInstance () {
+ return new Interpreter (pattern);
+ }
+
+ public int GroupCount {
+ get { return pattern[1]; }
+ }
+
+ public IDictionary Mapping {
+ get { return mapping; }
+ set { mapping = value; }
+ }
+
+ private IDictionary mapping;
+ private ushort[] pattern;
+ }
+
+ class PatternCompiler : ICompiler {
+ public static ushort EncodeOp (OpCode op, OpFlags flags) {
+ return (ushort)((int)op | ((int)flags & 0xff00));
+ }
+
+ public static void DecodeOp (ushort word, out OpCode op, out OpFlags flags) {
+ op = (OpCode)(word & 0x00ff);
+ flags = (OpFlags)(word & 0xff00);
+ }
+
+ public PatternCompiler () {
+ pgm = new ArrayList ();
+ }
+
+ // ICompiler implementation
+
+ public void Reset () {
+ pgm.Clear ();
+ }
+
+ public IMachineFactory GetMachineFactory () {
+ ushort[] image = new ushort[pgm.Count];
+ pgm.CopyTo (image);
+
+ return new InterpreterFactory (image);
+ }
+
+ public void EmitFalse () {
+ Emit (OpCode.False);
+ }
+
+ public void EmitTrue () {
+ Emit (OpCode.True);
+ }
+
+ void EmitCount (int count)
+ {
+ uint ucount = (uint) count;
+ Emit ((ushort) (ucount & 0xFFFF)); // lo 16bits
+ Emit ((ushort) (ucount >> 16)); // hi
+ }
+
+ public void EmitCharacter (char c, bool negate, bool ignore, bool reverse) {
+ Emit (OpCode.Character, MakeFlags (negate, ignore, reverse, false));
+
+ if (ignore)
+ c = Char.ToLower (c);
+
+ Emit ((ushort)c);
+ }
+
+ public void EmitCategory (Category cat, bool negate, bool reverse) {
+ Emit (OpCode.Category, MakeFlags (negate, false, reverse, false));
+ Emit ((ushort)cat);
+ }
+
+ public void EmitNotCategory (Category cat, bool negate, bool reverse) {
+ Emit (OpCode.NotCategory, MakeFlags (negate, false, reverse, false));
+ Emit ((ushort)cat);
+ }
+
+ public void EmitRange (char lo, char hi, bool negate, bool ignore, bool reverse) {
+ Emit (OpCode.Range, MakeFlags (negate, ignore, reverse, false));
+ Emit ((ushort)lo);
+ Emit ((ushort)hi);
+ }
+
+ public void EmitSet (char lo, BitArray set, bool negate, bool ignore, bool reverse) {
+ Emit (OpCode.Set, MakeFlags (negate, ignore, reverse, false));
+ Emit ((ushort)lo);
+
+ int len = (set.Length + 0xf) >> 4;
+ Emit ((ushort)len);
+
+ int b = 0;
+ while (len -- != 0) {
+ ushort word = 0;
+ for (int i = 0; i < 16; ++ i) {
+ if (b >= set.Length)
+ break;
+
+ if (set[b ++])
+ word |= (ushort)(1 << i);
+ }
+
+ Emit (word);
+ }
+ }
+
+ public void EmitString (string str, bool ignore, bool reverse) {
+ Emit (OpCode.String, MakeFlags (false, ignore, reverse, false));
+ int len = str.Length;
+ Emit ((ushort)len);
+
+ if (ignore)
+ str = str.ToLower ();
+
+ for (int i = 0; i < len; ++ i)
+ Emit ((ushort)str[i]);
+ }
+
+ public void EmitPosition (Position pos) {
+ Emit (OpCode.Position, 0);
+ Emit ((ushort)pos);
+ }
+
+ public void EmitOpen (int gid) {
+ Emit (OpCode.Open);
+ Emit ((ushort)gid);
+ }
+
+ public void EmitClose (int gid) {
+ Emit (OpCode.Close);
+ Emit ((ushort)gid);
+ }
+
+
+
+ public void EmitBalanceStart (int gid, int balance, bool capture, LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.BalanceStart);
+ Emit ((ushort)gid);
+ Emit ((ushort)balance);
+ Emit ((ushort)(capture ? 1 : 0));
+ EmitLink (tail);
+ }
+
+ public void EmitBalance () {
+ Emit (OpCode.Balance);
+ }
+
+ public void EmitReference (int gid, bool ignore, bool reverse) {
+ Emit (OpCode.Reference, MakeFlags (false, ignore, reverse, false));
+ Emit ((ushort)gid);
+ }
+
+ public void EmitIfDefined (int gid, LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.IfDefined);
+ EmitLink (tail);
+ Emit ((ushort)gid);
+ }
+
+ public void EmitSub (LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.Sub);
+ EmitLink (tail);
+ }
+
+ public void EmitTest (LinkRef yes, LinkRef tail) {
+ BeginLink (yes);
+ BeginLink (tail);
+ Emit (OpCode.Test);
+ EmitLink (yes);
+ EmitLink (tail);
+ }
+
+ public void EmitBranch (LinkRef next) {
+ BeginLink (next);
+ Emit (OpCode.Branch, 0);
+ EmitLink (next);
+ }
+
+ public void EmitJump (LinkRef target) {
+ BeginLink (target);
+ Emit (OpCode.Jump, 0);
+ EmitLink (target);
+ }
+
+ public void EmitRepeat (int min, int max, bool lazy, LinkRef until) {
+ BeginLink (until);
+ Emit (OpCode.Repeat, MakeFlags (false, false, false, lazy));
+ EmitLink (until);
+ EmitCount (min);
+ EmitCount (max);
+ }
+
+ public void EmitUntil (LinkRef repeat) {
+ ResolveLink (repeat);
+ Emit (OpCode.Until);
+ }
+
+ public void EmitFastRepeat (int min, int max, bool lazy, LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.FastRepeat, MakeFlags (false, false, false, lazy));
+ EmitLink (tail);
+ EmitCount (min);
+ EmitCount (max);
+ }
+
+ public void EmitIn (LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.In);
+ EmitLink (tail);
+ }
+
+ public void EmitAnchor (bool reverse, int offset, LinkRef tail) {
+ BeginLink (tail);
+ Emit (OpCode.Anchor, MakeFlags(false, false, reverse, false));
+ EmitLink (tail);
+ Emit ((ushort)offset);
+ }
+
+ public void EmitInfo (int count, int min, int max) {
+ Emit (OpCode.Info);
+ EmitCount (count);
+ EmitCount (min);
+ EmitCount (max);
+ }
+
+ public LinkRef NewLink () {
+ return new PatternLinkStack ();
+ }
+
+ public void ResolveLink (LinkRef lref) {
+ PatternLinkStack stack = (PatternLinkStack)lref;
+
+ while (stack.Pop ())
+ pgm[stack.OffsetAddress] = (ushort)stack.GetOffset (CurrentAddress);
+ }
+
+ public void EmitBranchEnd(){}
+ public void EmitAlternationEnd(){}
+
+ // private members
+
+ private static OpFlags MakeFlags (bool negate, bool ignore, bool reverse, bool lazy) {
+ OpFlags flags = 0;
+ if (negate) flags |= OpFlags.Negate;
+ if (ignore) flags |= OpFlags.IgnoreCase;
+ if (reverse) flags |= OpFlags.RightToLeft;
+ if (lazy) flags |= OpFlags.Lazy;
+
+ return flags;
+ }
+
+ private void Emit (OpCode op) {
+ Emit (op, (OpFlags)0);
+ }
+
+ private void Emit (OpCode op, OpFlags flags) {
+ Emit (EncodeOp (op, flags));
+ }
+
+ private void Emit (ushort word) {
+ pgm.Add (word);
+ }
+
+ private int CurrentAddress {
+ get { return pgm.Count; }
+ }
+
+ private void BeginLink (LinkRef lref) {
+ PatternLinkStack stack = (PatternLinkStack)lref;
+ stack.BaseAddress = CurrentAddress;
+ }
+
+ private void EmitLink (LinkRef lref) {
+ PatternLinkStack stack = (PatternLinkStack)lref;
+ stack.OffsetAddress = CurrentAddress;
+ Emit ((ushort)0); // placeholder
+ stack.Push ();
+ }
+
+
+ private class PatternLinkStack : LinkStack {
+ public PatternLinkStack () {
+ }
+
+ public int BaseAddress {
+ set { link.base_addr = value; }
+ }
+
+ public int OffsetAddress {
+ get { return link.offset_addr; }
+ set { link.offset_addr = value; }
+ }
+
+ public int GetOffset (int target_addr) {
+ return target_addr - link.base_addr;
+ }
+
+ // LinkStack implementation
+
+ protected override object GetCurrent () { return link; }
+ protected override void SetCurrent (object l) { link = (Link)l; }
+
+ private struct Link {
+ public int base_addr;
+ public int offset_addr;
+ }
+
+ Link link;
+ }
+
+ private ArrayList pgm;
+ }
+
+ abstract class LinkStack : LinkRef {
+ public LinkStack () {
+ stack = new Stack ();
+ }
+
+ public void Push () {
+ stack.Push (GetCurrent ());
+ }
+
+ public bool Pop () {
+ if (stack.Count > 0) {
+ SetCurrent (stack.Pop ());
+ return true;
+ }
+
+ return false;
+ }
+
+ protected abstract object GetCurrent ();
+ protected abstract void SetCurrent (object l);
+
+ private Stack stack;
+ }
+
+ //Used by CILCompiler and Interpreter
+ internal struct Mark {
+ public int Start, End;
+ public int Previous;
+
+ public bool IsDefined {
+ get { return Start >= 0 && End >= 0; }
+ }
+
+ public int Index {
+ get { return Start < End ? Start : End; }
+ }
+
+ public int Length {
+ get { return Start < End ? End - Start : Start - End; }
+ }
+ }
+
+}