Simple Stack-based Interpreter

/*
 * Created by SharpDevelop.
 * User: YinYang
 * Date: 3/15/2011
 * Time: 9:28 PM
 * Lastest update: 3/16/2011
 * Simple Interpreter stack-based
 *  https://yinyangit.wordpress.com
 */
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;

namespace Y2MouseLanguage
{
	class Y2MouseInterpreter
	{
		Stack<IComparable> _stack;
		Dictionary<string,string> _dict;

		public Y2MouseInterpreter()
		{
			_stack=new Stack<IComparable>();
			_dict=new Dictionary<string, string>();
		}
		public void AddInstruction(string name, string expression)
		{
			_dict.Add(name,expression);
		}
		public void Execute(string input)
		{
			if(String.IsNullOrEmpty(input))
				return;
			if(Regex.Match(input,@"^\[.+\]$").Success)
				input=input.Trim('[',']');
			MatchCollection matchs = Regex.Matches(input,"\"[^\\[\\]]+\"|" + @"\[[^\[\]]+\]|\S+", RegexOptions.Multiline | RegexOptions.IgnoreCase);

			foreach(Match m in matchs)
			{
				string s=m.Value;

				int i;
				if(int.TryParse(s,out i))
					_stack.Push(i);
				else if(Regex.Match(s,@"^\[.+\]$").Success)
					_stack.Push(s);
				else if(Regex.Match(s,"^\".+\"$").Success)
					_stack.Push(s.Trim('"'));
				else
				{
					try{
						ExecuteInstruction(s);
					}catch(Exception ex)
					{
						Console.ForegroundColor=ConsoleColor.DarkCyan;
						Console.WriteLine("Error: "+ex.Message);
						Console.ResetColor();
					}

				}

			}
		}
		public void PrintStack()
		{
			Console.ForegroundColor=ConsoleColor.DarkCyan;
			Console.Write("Stack: ");
			if(_stack.Count==0)
				Console.WriteLine("_empty_");
			else
			{
				IEnumerable<IComparable> elems=_stack.Reverse();

				foreach(var item in elems)
					Console.Write(item +" ");
				Console.WriteLine();
			}
			Console.ResetColor();
		}
		private void ExecuteInstruction(string instruction)
		{
			if(_dict.ContainsKey(instruction))
			{
				Execute(_dict[instruction]);
				return;
			}
			switch (instruction.ToUpper())
			{
				case "+":
					_stack.Push((int)_stack.Pop()+(int)_stack.Pop());
					break;
				case "-":
					{
					int o1=(int)_stack.Pop();
					int o2=(int)_stack.Pop();
					_stack.Push(o2-o1);
					break;
					}
				case "*":
					_stack.Push((int)_stack.Pop()*(int)_stack.Pop());
					break;
				case "/":
					{
					int o1=(int)_stack.Pop();
					int o2=(int)_stack.Pop();
					_stack.Push(o2/o1);
					break;
					}
				case "TRUE":
					_stack.Push(true);
					break;
				case "FALSE":
					_stack.Push(false);
					break;
				case "POP":
					_stack.Pop();
					break;
				case "DUP":
					_stack.Push(_stack.Peek());
					break;
				case "SWAP":
					{
						IComparable o1=_stack.Pop();
						IComparable o2=_stack.Pop();
						_stack.Push(o1);
						_stack.Push(o2);
						break;
					}
				case "INC":
					{
						int o1=(int)_stack.Pop();
						_stack.Push(o1+1);
						break;
					}
				case "EQ":
					{
						object o1=_stack.Pop();
						object o2=_stack.Pop();
						_stack.Push(o1.Equals(o2));
						break;
					}
				case "LT":
					{
						IComparable o1=_stack.Pop();
						IComparable o2=_stack.Pop();
						_stack.Push(o2.CompareTo(o1)<0);
						break;
					}
				case "GT":
					{
						IComparable o1=_stack.Pop();
						IComparable o2=_stack.Pop();
						_stack.Push(o2.CompareTo(o1)>0);
						break;
					}
				case "WRITELN":
					Console.WriteLine(_stack.Pop());
					break;
				case "IF":
					{
						IComparable o1=_stack.Pop();
						IComparable o2=_stack.Pop();
						IComparable o3=_stack.Pop();

						if((bool)o3)
							Execute(o2.ToString());
						else
							Execute(o1.ToString());
						break;
					}
				case "WHILE":
					{
						IComparable o1=_stack.Pop();
						IComparable o2=_stack.Pop();

						Execute(o2.ToString());
						Execute(o1.ToString());

						IComparable o3=_stack.Pop();
						if((bool)o3)
							Execute(o2.ToString() + o1 + " while");
						break;
					}
				default:
					throw new Exception("Could not find instruction '"+instruction+"'");
			}
			if(_stack.Count==0)
				return;

			string s =_stack.Peek() as string;
			if(s!=null)
			{
				if(Regex.Match(s,@"^\[.+\]$").Success)
					Execute(s);
			}

		}

	}
	class Program
	{
	public static void Main(string[] args)
	{
		Console.WriteLine("Welcome to Mouse programming language");
		Console.WriteLine("version 1.0 beta 1");
		Console.WriteLine("by Yin Yang");
		Console.WriteLine("https://yinyangit.wordpress.com");

		Y2MouseInterpreter mInter=new Y2MouseInterpreter();
		mInter.AddInstruction("dec","1 -");

		while(true)
		{
			Console.Write(">>");
			string cmd=Console.ReadLine().Trim();
			if(cmd=="#x" || cmd=="#exit")
				break;
			else
				mInter.Execute(cmd);

			if(cmd!="")
				mInter.PrintStack();
		}
	}
	}

}

Example:

Mouse Interpreter Example

Mouse Interpreter Example

Article:

Tự viết trình thông dịch stack-based đơn giản bằng C#


https://yinyangit.wordpress.com

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s