diff --git a/CS-MIC/csmic/CSMICTests/AuthoringTests.txt b/CS-MIC/csmic/CSMICTests/AuthoringTests.txt
new file mode 100644
index 0000000..64bab94
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/AuthoringTests.txt
@@ -0,0 +1,136 @@
+==========================================================================
+ Visual Studio Team System: Overview of Authoring and Running Tests
+==========================================================================
+
+This overview describes the features for authoring and running tests in
+Visual Studio Team System and Visual Studio Team Edition for Software Testers.
+
+Opening Tests
+-------------
+To open a test, open a test project or a test metadata file (a file with
+extension .vsmdi) that contains the definition of the test. You can find
+test projects and metadata files in Solution Explorer.
+
+Viewing Tests
+-------------
+To see which tests are available to you, open the Test View window. Or,
+if you have installed Team Edition for Software Testers, you can also open
+the Test List Editor window to view tests.
+
+To open the Test View window, click the Test menu, point to Windows, and
+then click Test View. To open the Test List Editor window (if you have
+installed Team Edition for Software Testers), click Test, point to Windows,
+and then click Test List Editor.
+
+Running Tests
+-------------
+You can run tests from the Test View window and the Test List Editor window.
+See Viewing Tests to learn how to open these windows. To run one or more
+tests displayed in the Test View window, first select the tests in that
+window; to select multiple tests, hold either the Shift or CTRL key while
+clicking tests. Then click the Run Tests button in the Test View window
+toolbar.
+
+If you have installed Visual Studio Team Edition for Software Testers, you can
+also use the Test List Editor window to run tests. To run tests in Test List Editor,
+select the check box next to each test that you want to run. Then click the
+Run Tests button in the Test List Editor window toolbar.
+
+Viewing Test Results
+--------------------
+When you run a test or a series of tests, the results of the test run will be
+shown in the Test Results window. Each individual test in the run is shown on
+a separate line so that you can see its status. The window contains an
+embedded status bar in the top half of the window that provides you with
+summary details of the complete test run.
+
+To see more detailed results for a particular test result, double-click it in
+the Test Results window. This opens a window that provides more information
+about the particular test result, such as any specific error messages returned
+by the test.
+
+Changing the way that tests are run
+-----------------------------------
+Each time you run one or more tests, a collection of settings is used to
+determine how those tests are run. These settings are contained in a “test
+run configuration” file.
+
+Here is a partial list of the changes you can make with a test run
+configuration file:
+
+ - Change the naming scheme for each test run.
+ - Change the test controller that the tests are run on so that you can run
+ tests remotely.
+ - Gather code coverage data for the code being tested so that you can see
+ which lines of code are covered by your tests.
+ - Enable and disable test deployment.
+ - Specify additional files to deploy before tests are run.
+ - Select a different host, ASP.NET, for running ASP.NET unit tests.
+ - Select a different host, the smart device test host, for running smart device unit tests.
+ - Set various properties for the test agents that run your tests.
+ - Run custom scripts at the start and end of each test run so that you can
+ set up the test environment exactly as required each time tests are run.
+ - Set time limits for tests and test runs.
+ - Set the browser mix and the number of times to repeat Web tests in the
+ test run.
+
+By default, a test run configuration file is created whenever you create a
+new test project. You make changes to this file by double-clicking it in
+Solution Explorer and then changing its settings. (Test run configuration
+files have the extension .testrunconfig.)
+
+A solution can contain multiple test run configuration files. Only one of
+those files, known as the “Active” test run configuration file, is used to
+determine the settings that are currently used for test runs. You select
+the active test run configuration by clicking Select Active Test Run
+Configuration on the Test menu.
+
+-------------------------------------------------------------------------------
+
+Test Types
+----------
+Using Visual Studio Team Edition for Software Testers, you can create a number
+of different test types:
+
+Unit test: Use a unit test to create a programmatic test in C++, Visual C# or
+Visual Basic that exercises source code. A unit test calls the methods of a
+class, passing suitable parameters, and verifies that the returned value is
+what you expect.
+There are three specialized variants of unit tests:
+ - Data-driven unit tests are created when you configure a unit test to be
+ called repeatedly for each row of a data source. The data from each row
+ is used by the unit test as input data.
+ - ASP.NET unit tests are unit tests that exercise code in an ASP.NET Web
+ application.
+ - Smart device unit tests are unit tests that are deployed to a smart device
+ or emulator and then executed by the smart device test host.
+
+Web Test: Web tests consist of an ordered series of HTTP requests that you
+record in a browser session using Microsoft Internet Explorer. You can have
+the test report specific details about the pages or sites it requests, such
+as whether a particular page contains a specified string.
+
+Load Test: You use a load test to encapsulate non-manual tests, such as
+unit, Web, and generic tests, and then run them simultaneously by using
+virtual users. Running these tests under load generates test results,
+including performance and other counters, in tables and in graphs.
+
+Generic test: A generic test is an existing program wrapped to function as a
+test in Visual Studio. The following are examples of tests or programs that
+you can turn into generic tests:
+ - An existing test that uses process exit codes to communicate whether the
+ test passed or failed. 0 indicates passing and any other value indicates
+ a failure.
+ - A general program to obtain specific functionality during a test scenario.
+ - A test or program that uses a special XML file (called a “summary results
+ file”), to communicate detailed results.
+
+Manual test: The manual test type is used when the test tasks are to be
+completed by a test engineer as opposed to an automated script.
+
+Ordered test: Use an ordered test to execute a set of tests in an order you
+specify.
+
+-------------------------------------------------------------------------------
+
+
diff --git a/CS-MIC/csmic/CSMICTests/CSMICTests.csproj b/CS-MIC/csmic/CSMICTests/CSMICTests.csproj
new file mode 100644
index 0000000..000d928
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/CSMICTests.csproj
@@ -0,0 +1,120 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.21022
+ 2.0
+ {C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}
+ Library
+ Properties
+ CSMICTests
+ CSMICTests
+ v4.0
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}
+ csmic
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/CS-MIC/csmic/CSMICTests/CSMICTests.csproj.vspscc b/CS-MIC/csmic/CSMICTests/CSMICTests.csproj.vspscc
new file mode 100644
index 0000000..feffdec
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/CSMICTests.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/CS-MIC/csmic/CSMICTests/InputInterpreterTest.cs b/CS-MIC/csmic/CSMICTests/InputInterpreterTest.cs
new file mode 100644
index 0000000..78aeca9
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/InputInterpreterTest.cs
@@ -0,0 +1,216 @@
+using csmic;
+using csmic.Extensions;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace CSMICTests
+{
+
+
+ ///
+ ///This is a test class for InputInterpreterTest and is intended
+ ///to contain all InputInterpreterTest Unit Tests
+ ///
+ [TestClass()]
+ public class InputInterpreterTest
+ {
+
+
+ private TestContext testContextInstance;
+
+ ///
+ ///Gets or sets the test context which provides
+ ///information about and functionality for the current test run.
+ ///
+ public TestContext TestContext
+ {
+ get
+ {
+ return testContextInstance;
+ }
+ set
+ {
+ testContextInstance = value;
+ }
+ }
+
+ #region Additional test attributes
+ //
+ //You can use the following additional attributes as you write your tests:
+ //
+ //Use ClassInitialize to run code before running the first test in the class
+ //[ClassInitialize()]
+ //public static void MyClassInitialize(TestContext testContext)
+ //{
+ //}
+ //
+ //Use ClassCleanup to run code after all tests in a class have run
+ //[ClassCleanup()]
+ //public static void MyClassCleanup()
+ //{
+ //}
+ //
+ //Use TestInitialize to run code before running each test
+ //[TestInitialize()]
+ //public void MyTestInitialize()
+ //{
+ //}
+ //
+ //Use TestCleanup to run code after each test has run
+ //[TestCleanup()]
+ //public void MyTestCleanup()
+ //{
+ //}
+ //
+ #endregion
+
+
+ ///
+ ///A test for Interpret
+ ///
+ [TestMethod()]
+ public void InterpretTest()
+ {
+ InputInterpreter target = new InputInterpreter();
+ target.CodedFunctions.Add(CodedFunctionFactory.Create("addfive", 1, rf => rf[0] + 5));
+
+ //HighLoadTest(target, "+1");
+ //HighLoadTest(target, "+sin(1)");
+ //HighLoadTest(target, "+precision(0.123456789, 7)");
+ //HighLoadTest(target, "+2*(2 + 5)/tan(sin(4))");
+ //HighLoadTest(target, "+2*2/3-1.23456");
+
+ ExpressionDecimalTest(target, "2+2", 4);
+ ExpressionDecimalTest(target, "1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10", 55);
+ ExpressionDecimalTest(target, "4 + 2 / 1 - 3 * 2", 0);
+ ExpressionDecimalTest(target, "16*2 - 2*3", 26);
+ ExpressionDecimalTest(target, "7-6+3*2", 7);
+ ExpressionDecimalTest(target, "1/-2*-1", 0.5M);
+ ExpressionDecimalTest(target, "12 + 26 / -2 + 3", 2);
+ ExpressionDecimalTest(target, "0.02395/1000", 0.00002395M);
+ ExpressionDecimalTest(target, "0100010101b", 277);
+ ExpressionDecimalTest(target, "0xabcdef", 11259375);
+ ExpressionDecimalTest(target, "11111111b + 0xFF", 510);
+ ExpressionDecimalTest(target, "10011001b * 0x01bAc", 1083852);
+
+ ExpressionDecimalTest(target, "log(sin(((25*200) - 5000)^1943),2)", decimal.MinValue);
+ ExpressionDecimalTest(target, "log(cos(((25*200) - 5000)^1943),2)", 0);
+ ExpressionDecimalTest(target, "cos(2^3)", -0.145500033808614M);
+ ExpressionDecimalTest(target, "addfive(30)", 35);
+ ExpressionDecimalTest(target, "precision(1.23456789, 4)", 1.2346M);
+ ExpressionDecimalTest(target, "3000 * (log(1 + 3162, 2))", 34881.2335215522M);
+ ExpressionDecimalTest(target, "(((12)))", 12);
+
+ ExpressionOutputTest(target, "z := (3*x) - (2*y)", "(3*x)-(2*y)");
+ ExpressionOutputTest(target, "x :: 3", "3");
+ ExpressionOutputTest(target, "y :: 2", "2");
+ ExpressionOutputTest(target, "x", "3");
+ ExpressionOutputTest(target, "y", "2");
+ ExpressionOutputTest(target, "z", "5");
+ ExpressionOutputTest(target, "z + 2", "7");
+ ExpressionOutputTest(target, "y :: 3", "3");
+ ExpressionOutputTest(target, "z", "3");
+ ExpressionOutputTest(target, "arr -> [3,6,9,12]", "3,6,9,12");
+ ExpressionOutputTest(target, "arr[1]", "6");
+ ExpressionOutputTest(target, "arr[1+1]", "9");
+ ExpressionOutputTest(target, "arr[2+44]", "0");
+
+ ExpressionOutputTest(target, "log(sin(((25*200) - 5000)^1943),2)", "log(sin(((25*200) - 5000)^1943),2)".Interpret());
+ ExpressionOutputTest(target, "log(cos(((25*200) - 5000)^1943),2)", "log(cos(((25*200) - 5000)^1943),2)".Interpret());
+
+ }
+
+ [TestMethod]
+ public void AsyncTest()
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+ interpreter.InterpretAsync("2 + 2", i =>
+ {
+ Assert.IsTrue(i.Output == "4");
+ });
+ }
+
+ [TestMethod]
+ public void ComputableTest()
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+
+ interpreter.Interpret("1");
+ Assert.IsTrue(interpreter.AsComputable(c => c.Add(5)).Resolve().Decimal == 6);
+ Assert.IsTrue(interpreter.AsComputable(c => c.Subtract(5)).Resolve().Decimal == 1);
+ Assert.IsTrue(interpreter.AsComputable(c => c.Multiply(5)).Resolve().Decimal == 5);
+ Assert.IsTrue(interpreter.AsComputable(c => c.Divide(1)).Resolve().Decimal == 5);
+ Assert.IsTrue(interpreter.AsComputable(c => c.Mod(1)).Resolve().Decimal == 0);
+ Assert.IsTrue(interpreter.AsComputable(c => c.RaiseToPower(5)).Resolve().Decimal == 0);
+
+ interpreter.Interpret("1");
+ Assert.IsTrue(interpreter.ToComputable().Add(5).Resolve().Decimal == 6);
+ Assert.IsTrue(interpreter.ToComputable().Subtract(5).Resolve().Decimal == 1);
+ Assert.IsTrue(interpreter.ToComputable().Multiply(5).Resolve().Decimal == 5);
+ Assert.IsTrue(interpreter.ToComputable().Divide(1).Resolve().Decimal == 5);
+ Assert.IsTrue(interpreter.ToComputable().Mod(1).Resolve().Decimal == 0);
+ Assert.IsTrue(interpreter.ToComputable().RaiseToPower(5).Resolve().Decimal == 0);
+
+ interpreter.Interpret("1");
+ Assert.IsTrue(interpreter.AsComputable(c => c.Add(5)).ResolveTo(i => i.Decimal) == 6);
+ Assert.IsTrue(interpreter.AsComputable(c => c.Subtract(5)).ResolveTo(i => i.Int) == 1);
+
+ interpreter.Interpret("5");
+ int[] ia = new int[] { 1,2,3 };
+ var test = interpreter.AsComputable(computable => computable.ForAll(ia, sub => sub.RaiseToPower)).Resolve();
+ Assert.IsTrue(test.Output == "15625");
+ }
+
+ ///
+ /// Tests a value repeated 10,000 times and checks for an execution time less than 200 milliseconds.
+ ///
+ /// The input interpreter.
+ /// The value to repeat and test.
+ public void HighLoadTest(InputInterpreter target, string value)
+ {
+ StringBuilder builder = new StringBuilder();
+ string input = string.Empty;
+ System.TimeSpan baseTime = new System.TimeSpan();
+ for (int i = 0; i < 1000; i++)
+ {
+ builder.Append(value);
+ }
+ input = builder.ToString();
+ target.Interpret(input);
+ baseTime = target.LastExecutionTime;
+
+ builder = new StringBuilder();
+ for (int i = 0; i < 100000; i++)
+ {
+ builder.Append(value);
+ }
+ input = builder.ToString();
+ target.Interpret(input);
+
+ Assert.IsTrue(target.LastExecutionTime <= System.TimeSpan.FromTicks((baseTime.Ticks + 1 * 100) + 100), string.Format("{0} failed the high load test.", value));
+ }
+
+ ///
+ /// Tests a given expression for a decimal result.
+ ///
+ /// The input interpreter.
+ /// The input to execute.
+ /// The expected value.
+ public void ExpressionDecimalTest(InputInterpreter target, string input, decimal expected)
+ {
+ target.Interpret(input);
+ Assert.AreEqual(expected, target.Decimal, string.Format("{0} returned {1} but {2} was expected.", input, target.Decimal, expected));
+ }
+
+ ///
+ /// Tests a given expression for a string result.
+ ///
+ /// The input interpreter.
+ /// The input to execute.
+ /// The expected value.
+ public void ExpressionOutputTest(InputInterpreter target, string input, string expected)
+ {
+ target.Interpret(input);
+ Assert.AreEqual(expected, target.Output, string.Format("{0} returned {1} but {2} was expected.", input, target.Decimal, expected));
+ }
+ }
+}
diff --git a/CS-MIC/csmic/CSMICTests/Properties/AssemblyInfo.cs b/CS-MIC/csmic/CSMICTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4c637fa
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CSMICTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CSMICTests")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM componenets. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8e6bded0-27ba-4d6b-a785-988958ca4b10")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CS-MIC/csmic/CSMICTests/Test References/csmic.accessor b/CS-MIC/csmic/CSMICTests/Test References/csmic.accessor
new file mode 100644
index 0000000..67034e0
--- /dev/null
+++ b/CS-MIC/csmic/CSMICTests/Test References/csmic.accessor
@@ -0,0 +1,2 @@
+csmic.dll
+Desktop
diff --git a/CS-MIC/csmic/HelpFile/HelpFile.shfbproj b/CS-MIC/csmic/HelpFile/HelpFile.shfbproj
new file mode 100644
index 0000000..5390394
--- /dev/null
+++ b/CS-MIC/csmic/HelpFile/HelpFile.shfbproj
@@ -0,0 +1,87 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ {b60970b9-771a-4ebb-9978-89f55163888f}
+ 1.9.5.0
+
+ HelpFile
+ HelpFile
+ HelpFile
+
+ .\Help\
+ csmic_help
+ en-US
+ HtmlHelp1, Website
+ False
+ .NET Framework 4.0
+ True
+ False
+ False
+ True
+ Standard
+ Blank
+ csmic
+ True
+ VS2010
+ False
+ Guid
+ CS-MIC - C Sharp Math Input Control
+ Please visit the <%3ba href="%3bhttp://cs-mic.com"%3b>%3bofficial site<%3b/a>%3b for more information.
+ Please feel free to provide feedback!
+ jordan%40jordanwages.com
+ Copyright 2012
+ AboveNamespaces
+ Msdn
+ Msdn
+ True
+ True
+ CS-MIC is a .NET library written in C# designed to give developers easy access to expression parsing. For many developers, there is no need to involve complicated settings and formats. With few exposed methods and objects, CS-MIC makes basic expression solving as simple as possible with as little logic required from developers as possible. In fact, one can pull a value with only one line of code.
+ Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Internals, Protected, SealedProtected
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CS-MIC/csmic/HelpFile/HelpFile.shfbproj.vspscc b/CS-MIC/csmic/HelpFile/HelpFile.shfbproj.vspscc
new file mode 100644
index 0000000..feffdec
--- /dev/null
+++ b/CS-MIC/csmic/HelpFile/HelpFile.shfbproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/CS-MIC/csmic/csmic.sln b/CS-MIC/csmic/csmic.sln
new file mode 100644
index 0000000..09de5d8
--- /dev/null
+++ b/CS-MIC/csmic/csmic.sln
@@ -0,0 +1,54 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csmic", "csmic\csmic.csproj", "{7BBA4BA2-E885-4D89-8710-F1A609616B7D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSMICTests", "CSMICTests\CSMICTests.csproj", "{C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}"
+EndProject
+Project("{7CF6DF6D-3B04-46F8-A40B-537D21BCA0B4}") = "HelpFile", "HelpFile\HelpFile.shfbproj", "{B60970B9-771A-4EBB-9978-89F55163888F}"
+EndProject
+Global
+ GlobalSection(TeamFoundationVersionControl) = preSolution
+ SccNumberOfProjects = 4
+ SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+ SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs35
+ SccLocalPath0 = .
+ SccProjectUniqueName1 = csmic\\csmic.csproj
+ SccProjectName1 = csmic
+ SccLocalPath1 = csmic
+ SccProjectUniqueName2 = CSMICTests\\CSMICTests.csproj
+ SccProjectName2 = CSMICTests
+ SccLocalPath2 = CSMICTests
+ SccProjectUniqueName3 = HelpFile\\HelpFile.shfbproj
+ SccProjectName3 = HelpFile
+ SccLocalPath3 = HelpFile
+ EndGlobalSection
+ GlobalSection(TestCaseManagementSettings) = postSolution
+ CategoryFile = csmic8.vsmdi
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B60970B9-771A-4EBB-9978-89F55163888F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B60970B9-771A-4EBB-9978-89F55163888F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B60970B9-771A-4EBB-9978-89F55163888F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B60970B9-771A-4EBB-9978-89F55163888F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(SubversionScc) = preSolution
+ Svn-Managed = True
+ Manager = AnkhSVN - Subversion Support for Visual Studio
+ EndGlobalSection
+EndGlobal
diff --git a/CS-MIC/csmic/csmic.vssscc b/CS-MIC/csmic/csmic.vssscc
new file mode 100644
index 0000000..794f014
--- /dev/null
+++ b/CS-MIC/csmic/csmic.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctionFactory.cs b/CS-MIC/csmic/csmic/CodedFunctionFactory.cs
new file mode 100644
index 0000000..e72ce84
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctionFactory.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ /// Coded function factory.
+ ///
+ /// This class generates new coded functions dynamically.
+ ///
+ public static class CodedFunctionFactory
+ {
+ /// Creates a new ICodedFunction interface object that implements the dynamic method described.
+ /// Name of the function.
+ /// Number of expected arguments.
+ /// The method body.
+ /// An ICodedFunction interface object.
+ public static ICodedFunction Create(string functionName, int numExpectedArguments, Func methodBody)
+ {
+ return new GenericCodedFunction(functionName, numExpectedArguments, methodBody);
+ }
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Abs.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Abs.cs
new file mode 100644
index 0000000..d459f55
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Abs.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the absolute value function.
+ ///
+ class CF_Abs : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "abs"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The absolute value of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = Math.Abs(input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Cos.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Cos.cs
new file mode 100644
index 0000000..be0df91
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Cos.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the cosine function.
+ ///
+ class CF_Cos : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "cos"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The cosine of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = (decimal)Math.Cos((double)input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Exp.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Exp.cs
new file mode 100644
index 0000000..e4cad95
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Exp.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the exponential function based on the constant e.
+ ///
+ class CF_Exp : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "exp"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The constant e raised to the power of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = (decimal)Math.Exp((double)input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Log.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Log.cs
new file mode 100644
index 0000000..c938834
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Log.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the log function.
+ ///
+ class CF_Log : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 2 arguments.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 2; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "log"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The log of the first argument to the base of the second argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ decimal logBase = args[1];
+ try
+ {
+ output = (decimal)Math.Log((double)input, (double)logBase);
+ }
+ catch
+ {
+ output = decimal.MinValue;
+ }
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Precision.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Precision.cs
new file mode 100644
index 0000000..b718082
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Precision.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of a precision function.
+ ///
+ class CF_Precision : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 2 arguments.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 2; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "precision"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The first argument to the precision of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ decimal precision = args[1];
+ output = (decimal)Math.Round(input, (int)precision);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Round.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Round.cs
new file mode 100644
index 0000000..9d88fe5
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Round.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of a rounded function.
+ ///
+ class CF_Round : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "round"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The rounded argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = Math.Round(input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Sin.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Sin.cs
new file mode 100644
index 0000000..8b05729
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Sin.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the sine function.
+ ///
+ class CF_Sin : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "sin"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The sine of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = (decimal)Math.Sin((double)input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Sqrt.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Sqrt.cs
new file mode 100644
index 0000000..5de4871
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Sqrt.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the squre root function.
+ ///
+ class CF_Sqrt : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "sqrt"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The square root of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = (decimal)Math.Sqrt((double)input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/CodedFunctions/CF_Tan.cs b/CS-MIC/csmic/csmic/CodedFunctions/CF_Tan.cs
new file mode 100644
index 0000000..6527cbe
--- /dev/null
+++ b/CS-MIC/csmic/csmic/CodedFunctions/CF_Tan.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.CodedFunctions
+{
+ ///
+ /// A coded implementation of the tangent function.
+ ///
+ class CF_Tan : ICodedFunction
+ {
+ #region ICodedFunction Members
+
+ ///
+ /// Expects 1 argument.
+ ///
+ public int NumExpectedArguments
+ {
+ get { return 1; }
+ }
+
+ ///
+ /// The name of the function.
+ ///
+ public string FunctionName
+ {
+ get { return "tan"; }
+ }
+
+ ///
+ /// Executes a code block.
+ ///
+ /// The arguments used in the code block.
+ /// The tangent of the argument.
+ public decimal Execute(params decimal[] args)
+ {
+ decimal output = 0;
+ if (args.Length == this.NumExpectedArguments)
+ {
+ decimal input = args[0];
+ output = (decimal)Math.Tan((double)input);
+ }
+ return output;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/Computable/Computable.cs b/CS-MIC/csmic/csmic/Computable/Computable.cs
new file mode 100644
index 0000000..323b9f7
--- /dev/null
+++ b/CS-MIC/csmic/csmic/Computable/Computable.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic.ComputableEngine
+{
+ /// Computable class.
+ public sealed class Computable
+ {
+ #region Members
+
+ /// The expression to be built.
+ private string expression;
+ /// The interpreter to act as a base.
+ private InputInterpreter interpreter;
+
+ #region Constants
+
+ /// The add symbol.
+ private const string ADD = "+";
+ /// The substract symbol.
+ private const string SUBSTRACT = "-";
+ /// The divide symbol.
+ private const string DIVIDE = "/";
+ /// The multiply symbol.
+ private const string MULTIPLY = "*";
+ /// The modifier symbol.
+ private const string MOD = "%";
+ /// The power symbol.
+ private const string POWER = "^";
+
+ #endregion
+
+ #endregion
+
+ #region Properties
+
+ /// Gets the expression.
+ /// The expression.
+ internal string Expression
+ {
+ get
+ {
+ return this.expression;
+ }
+ }
+
+ #endregion
+
+ #region Constructor
+
+ /// Creates a Computable instance.
+ /// The expression.
+ /// The interpreter.
+ internal Computable(string expression, InputInterpreter interpreter)
+ {
+ this.expression = expression;
+ this.interpreter = interpreter;
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// Resolves the computable as an input interpreter having calculated the input.
+ /// The computable as an input interpreter.
+ public InputInterpreter Resolve()
+ {
+ this.interpreter.Interpret(this.Expression);
+ return this.interpreter;
+ }
+
+ /// Resolve the computer to a type .
+ /// Generic type parameter.
+ /// The selector function.
+ /// .
+ public T ResolveTo(Func selector)
+ {
+ return selector(this.Resolve());
+ }
+
+ /// Form the operation given the operation constant and an argument.
+ /// The operation constant.
+ /// The argument.
+ /// A string with the given operation appended.
+ private string FormOperation(string operation, object argument)
+ {
+ return string.Format("({0} {1} {2})", this.Expression, operation, argument);
+ }
+
+ /// Form the function with the current expression as the first argument, followed by .
+ /// The name of the function.
+ /// The arguments.
+ /// .
+ private string FormFunction(string name, object[] arguments)
+ {
+ return string.Format("{0}({1})", name, string.Join(",", this.Expression, arguments));
+ }
+
+ /// Adds addend.
+ /// The decimal to add.
+ /// A computable class after the addition.
+ public Computable Add(decimal addend)
+ {
+ this.expression = FormOperation(ADD, addend);
+ return this;
+ }
+
+ /// Subtracts the subtrahend.
+ /// The subtrahend.
+ /// A computable class after the subtraction.
+ public Computable Subtract(decimal subtrahend)
+ {
+ this.expression = FormOperation(SUBSTRACT, subtrahend);
+ return this;
+ }
+
+ /// Multiplies the multiplicand.
+ /// The multiplicand.
+ /// A computable class after the mulitplication.
+ public Computable Multiply(decimal multiplicand)
+ {
+ this.expression = FormOperation(MULTIPLY, multiplicand);
+ return this;
+ }
+
+ /// Divides the divisor.
+ /// The divisor.
+ /// A computable class after the divison.
+ public Computable Divide(decimal divisor)
+ {
+ this.expression = FormOperation(DIVIDE, divisor);
+ return this;
+ }
+
+ /// Mods using a given divisor.
+ /// The divisor.
+ /// A computable class after the mod.
+ public Computable Mod(decimal divisor)
+ {
+ this.expression = FormOperation(MOD, divisor);
+ return this;
+ }
+
+ /// Raises to power of the given integer value.
+ /// The power.
+ /// A computable class after the power operation.
+ public Computable RaiseToPower(int power)
+ {
+ this.expression = FormOperation(POWER, power);
+ return this;
+ }
+
+ /// Applies the function with the current expression as the first argument, followed by .
+ /// The name of the function.
+ /// The arguments.
+ /// A computable class after the function is applied.
+ public Computable ApplyFunction(string name, object[] arguments)
+ {
+ this.expression = FormFunction(name, arguments);
+ return this;
+ }
+
+ /// Executes a command for all items in a collection.
+ /// Generic type parameter.
+ /// The items of type .
+ /// The action belonging to type .
+ /// .
+ public Computable ForAll(ICollection items, Func> action)
+ {
+ foreach (T item in items)
+ {
+ action(this)(item);
+ }
+
+ return this;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/Extensions/CSMICExtension.cs b/CS-MIC/csmic/csmic/Extensions/CSMICExtension.cs
new file mode 100644
index 0000000..c999aa3
--- /dev/null
+++ b/CS-MIC/csmic/csmic/Extensions/CSMICExtension.cs
@@ -0,0 +1,178 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Linq;
+using System.Text;
+
+namespace csmic.Extensions
+{
+ /// CS-MIC extension methods.
+ public static class CSMICExtension
+ {
+ #region String
+
+ /// A string extension method that interprets as input the string that calls it.
+ /// The input to act on.
+ /// The output from the interpretation of the string.
+ public static string Interpret(this string input)
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+ interpreter.Interpret(input);
+ return interpreter.Output;
+ }
+
+ /// A string extension method that executes as macro operation.
+ /// The script to act on.
+ /// The final output of the script.
+ public static string RunAsMacro(this string script)
+ {
+ MacroBuilder macro = new MacroBuilder(script, new InputInterpreter());
+ return macro.FinalOutput;
+ }
+
+ #endregion
+
+ #region IEnumerable
+
+ ///
+ /// A string extension method that interprets as input the string that calls it.
+ ///
+ /// The collection to act on.
+ /// The output from the interpretation of the string.
+ public static IEnumerable Interpret(this IEnumerable collection)
+ {
+ List computed = new List();
+ InputInterpreter interpreter = new InputInterpreter();
+
+ foreach (string input in collection)
+ {
+ interpreter.Interpret(input);
+ computed.Add(interpreter.Output);
+ }
+
+ return computed;
+ }
+
+ ///
+ /// A string extension method that interprets as input the string that calls it.
+ ///
+ /// The collection to act on.
+ /// The action.
+ /// The output from the interpretation of the string.
+ public static IEnumerable Interpret(this IEnumerable collection, Action action)
+ {
+ List computed = new List();
+ InputInterpreter interpreter = new InputInterpreter();
+
+ foreach (string input in collection)
+ {
+ interpreter.Interpret(input);
+ computed.Add(interpreter.Output);
+ action(interpreter);
+ }
+
+ return computed;
+ }
+
+ /// Enumerates input in this collection, returning a selection on the interpreter.
+ /// Generic type parameter.
+ /// The collection to act on.
+ /// The selection.
+ ///
+ /// An enumerator that allows foreach to be used to process interpret< t> in this
+ /// collection.
+ ///
+ public static IEnumerable Interpret(this IEnumerable collection, Func selection)
+ {
+ List computed = new List();
+ InputInterpreter interpreter = new InputInterpreter();
+
+ foreach (string input in collection)
+ {
+ interpreter.Interpret(input);
+ computed.Add(selection(interpreter));
+ }
+
+ return computed;
+ }
+
+ /// A string extension method that executes as macro operation.
+ /// The collection to act on.
+ /// The final output of the script.
+ public static MacroBuilder RunAsMacro(this IEnumerable collection)
+ {
+ return new MacroBuilder(string.Join(Environment.NewLine, collection.ToArray()), new InputInterpreter());
+ }
+
+ #endregion
+
+ #region IEnumerable In Parallel
+
+ /// Enumerates input in parallel in this collection.
+ /// The collection to act on.
+ ///
+ /// An enumerator that allows foreach to be used to process interpret in parallel in this
+ /// collection.
+ ///
+ public static IEnumerable InterpretInParallel(this IEnumerable collection)
+ {
+ ConcurrentBag bag = new ConcurrentBag();
+
+ collection.AsParallel().ForAll(input =>
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+ interpreter.Interpret(input);
+ bag.Add(interpreter);
+ });
+
+ return bag;
+ }
+
+ /// Enumerates input in parallel this collection, returning a selection on the interpreter.
+ /// Generic type parameter.
+ /// The collection to act on.
+ /// The selection.
+ ///
+ /// An enumerator that allows foreach to be used to process interpret in parallel< t> in
+ /// this collection.
+ ///
+ public static IEnumerable InterpretInParallel(this IEnumerable collection, Func selection)
+ {
+ ConcurrentBag bag = new ConcurrentBag();
+
+ collection.AsParallel().ForAll(input =>
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+ interpreter.Interpret(input);
+ bag.Add(selection(interpreter));
+ });
+
+ return bag;
+ }
+
+ #endregion
+
+ #region ParallelQuery
+
+ ///
+ /// A string extension method that interprets as input the strings that calls it in parallel.
+ ///
+ /// The collection to act on.
+ /// The output from the interpretation of the string.
+ public static IEnumerable Interpret(this ParallelQuery collection)
+ {
+ ConcurrentBag bag = new ConcurrentBag();
+
+ collection.ForAll(input =>
+ {
+ InputInterpreter interpreter = new InputInterpreter();
+ interpreter.Interpret(input);
+ bag.Add(interpreter);
+ });
+
+ return bag;
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/GenericCodedFunction.cs b/CS-MIC/csmic/csmic/GenericCodedFunction.cs
new file mode 100644
index 0000000..6e1f12a
--- /dev/null
+++ b/CS-MIC/csmic/csmic/GenericCodedFunction.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// A generically coded implementation of the ICodedFunction interface.
+ ///
+ internal class GenericCodedFunction : ICodedFunction
+ {
+ #region Members
+
+ /// Number of expected arguments.
+ private int numExpectedArguments;
+ /// Name of the function.
+ private string functionName;
+ /// The method body.
+ private Func methodBody;
+
+ #endregion
+
+ #region Constructor
+
+ /// Constructor.
+ /// Name of the function.
+ /// Number of expected arguments.
+ /// The method body.
+ internal GenericCodedFunction(string functionName, int numExpectedArguments, Func methodBody)
+ {
+ this.functionName = functionName;
+ this.numExpectedArguments = numExpectedArguments;
+ this.methodBody = methodBody;
+ }
+
+ #endregion
+
+ #region ICodedFunction Members
+
+ /// Gets the number of expected arguments.
+ /// The total number of expected arguments.
+ public int NumExpectedArguments
+ {
+ get
+ {
+ return this.numExpectedArguments;
+ }
+ }
+
+ /// Gets the name of the function.
+ /// The name of the function.
+ public string FunctionName
+ {
+ get
+ {
+ return this.functionName;
+ }
+ }
+
+ /// Executes a code block that computes the value of the function.
+ /// A variable-length parameters list containing arguments.
+ /// The decimal value computed by the function.
+ public decimal Execute(params decimal[] args)
+ {
+ if (this.methodBody != null)
+ {
+ return this.methodBody(args);
+ }
+
+ throw new MissingMethodException(this.GetType().Name, this.functionName);
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/ICodedFunction.cs b/CS-MIC/csmic/csmic/ICodedFunction.cs
new file mode 100644
index 0000000..4b827a4
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ICodedFunction.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// Implements a function that is coded in the .Net environment.
+ ///
+ /// This interface is required to implement a method or function
+ /// that can be used by the CS-MIC inputInterpreter. It is worth noting that the
+ /// function's name will be the text that is used in the inputInterpreter as the
+ /// executable text.
+ public interface ICodedFunction
+ {
+ #region Properties
+
+ ///
+ /// Gets the number of expected arguments.
+ ///
+ int NumExpectedArguments { get; }
+ ///
+ /// Gets the name of the function.
+ ///
+ /// The input inputInterpreter will use this function name as
+ /// executable text, expecting an opening and closing parenthesis following
+ /// it.
+ string FunctionName { get; }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Executes a code block that computes the value of the function.
+ ///
+ /// An array of arguments passed to the function.
+ /// The decimal value computed by the function.
+ /// Any code block is valid. Error handling must be done by the
+ /// developer, as the inputInterpreter cannot determine if there is an error.
+ ///
+ /// This example shows how to implement the sine function through the interface's
+ /// Execute() function.
+ ///
+ /// public decimal Execute(params decimal[] args)
+ ///{
+ /// //Set up an output variable.
+ /// decimal output = 0;
+ ///
+ /// //Check to see if the number or arguments recieved
+ /// //is equal to the number of arguments expected.
+ /// if (args.Length == this.NumExpectedArguments)
+ /// {
+ /// //Grab the argument and set a local variable for clarity.
+ /// decimal input = args[0];
+ ///
+ /// //Set the output as a sine of the input.
+ /// output = (decimal)Math.Sin((double)input);
+ /// }
+ ///
+ /// //Return the output. The function will return the sine if the arguments
+ /// //matched what was expected, and will return 0 otherwise. Returning 0 on
+ /// //errors is the standard in CS-MIC.
+ /// return output;
+ ///}
+ ///
+ ///
+ decimal Execute(params decimal[] args);
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/InputInterpreter.cs b/CS-MIC/csmic/csmic/InputInterpreter.cs
new file mode 100644
index 0000000..c13d8f1
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InputInterpreter.cs
@@ -0,0 +1,502 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.IO;
+using System.Threading;
+using csmic.CodedFunctions;
+using csmic.Interpreter;
+using csmic.ComputableEngine;
+using System.Runtime.Remoting.Messaging;
+
+// namespace: csmic
+//
+// summary: .
+namespace csmic
+{
+ ///
+ /// An interpreter object that reads user input and evaluates the code.
+ ///
+ /// The interpreter does not support exceptions by design. Instead, invalid
+ /// calculations, parameters, etc. will result in a result of zero.
+ ///
+ /// InputInterpreter interpreter = new InputInterpreter();
+ /// interpreter.Interpret("1/0"); // The result will be 0, not an exception.
+ ///
+ ///
+ public class InputInterpreter
+ {
+ #region Members
+
+ ///
+ /// The output generated.
+ ///
+ private string output;
+ ///
+ /// The variables assigned.
+ ///
+ internal Dictionary variables;
+ ///
+ /// The time for execution.
+ ///
+ private TimeSpan executionTime;
+ ///
+ /// The verbose message of the calculation.
+ ///
+ private string message;
+ ///
+ /// The list of coded functions that can be executed.
+ ///
+ private List codedFunctions;
+ ///
+ /// The list of user defined functions that can be executed.
+ ///
+ private List interpretedFunctions;
+ ///
+ /// The private calculated value.
+ ///
+ private decimal calculatedValue;
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Creates a new InputInterpreter.
+ ///
+ public InputInterpreter()
+ {
+ this.output = string.Empty;
+ this.variables = new Dictionary();
+ this.executionTime = new TimeSpan();
+ this.codedFunctions = new List();
+ this.interpretedFunctions = new List();
+ LoadDefaultCodedFunctions();
+ }
+
+ ///
+ /// Creates a new InputInterpreter from an original.
+ ///
+ /// The orginal input interpreter to copy.
+ public InputInterpreter(InputInterpreter original)
+ {
+ this.output = original.output;
+ this.variables = original.variables;
+ this.executionTime = original.executionTime;
+ this.codedFunctions = original.codedFunctions;
+ this.interpretedFunctions = original.interpretedFunctions;
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the message that represents the InputInterpreters output.
+ ///
+ public string Output
+ {
+ get
+ {
+ return this.output;
+ }
+ }
+
+ ///
+ /// Gets the verbose message that is generated with a calculation.
+ ///
+ public string Message
+ {
+ get
+ {
+ return this.message;
+ }
+ }
+
+ ///
+ /// Gets the value of the output as a decimal.
+ ///
+ public decimal Decimal
+ {
+ get
+ {
+ return this.calculatedValue;
+ }
+ }
+
+ ///
+ /// Gets the value of the output cast as an int.
+ ///
+ public int Int
+ {
+ get
+ {
+ return (int)decimal.Round(this.calculatedValue);
+ }
+ }
+
+ ///
+ /// Gets the value of the output cast as a float.
+ ///
+ public float Float
+ {
+ get
+ {
+ return (float)this.calculatedValue;
+ }
+ }
+
+ ///
+ /// Gets the value of the output cast as a double.
+ ///
+ public double Double
+ {
+ get
+ {
+ return (double)this.calculatedValue;
+ }
+ }
+
+ ///
+ /// Gets the value (cast as a long) converted to its binary equivalent.
+ ///
+ public string Binary
+ {
+ get
+ {
+ return Convert.ToString((long)this.calculatedValue, 2).PadLeft(64, '0');
+ }
+ }
+
+ ///
+ /// Gets the execution time of the last calculation.
+ ///
+ public TimeSpan LastExecutionTime
+ {
+ get
+ {
+ return this.executionTime;
+ }
+ }
+
+ ///
+ /// Gets or sets a list of coded functions that the interpreter supports.
+ ///
+ public List CodedFunctions
+ {
+ get
+ {
+ return this.codedFunctions;
+ }
+ set
+ {
+ this.codedFunctions = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a list of user generated interpreted functions that the interpreter supports.
+ ///
+ /// The interpreted functions.
+ public List InterpretedFunctions
+ {
+ get
+ {
+ return this.interpretedFunctions;
+ }
+ set
+ {
+ this.interpretedFunctions = value;
+ }
+ }
+
+ /// Gets the variables.
+ /// The variables.
+ public Dictionary Variables
+ {
+ get
+ {
+ return this.variables;
+ }
+ set
+ {
+ this.variables = value;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Interprets and executes given input.
+ ///
+ /// The input to interpret and execute.
+ public void Interpret(string input)
+ {
+ if (string.IsNullOrEmpty(input))
+ {
+ return;
+ }
+
+ DateTime timeStart = DateTime.Now;
+ this.message = string.Empty;
+
+ UTF8Encoding encoder = new UTF8Encoding();
+ Parser p = new Parser(new Scanner(new MemoryStream(encoder.GetBytes(input))));
+ p.Interpreter = this;
+ try
+ {
+ p.Parse();
+ this.calculatedValue = p.CalculatedValue;
+ if (p.errors.count > 0)
+ {
+ ProduceOutput(this.calculatedValue, p.errors.builder.ToString());
+ }
+ }
+ catch (Exception e)
+ {
+ this.calculatedValue = 0;
+ ProduceOutput(this.calculatedValue, e.Message);
+ }
+
+ DateTime timeEnd = DateTime.Now;
+ this.executionTime = timeEnd - timeStart;
+ }
+
+ ///
+ /// Computes an expression and returns the result as a decimal.
+ ///
+ /// The expression to be calculated.
+ /// The value that was computed.
+ public decimal ComputeExpression(string expression)
+ {
+ this.Interpret(expression);
+ return this.calculatedValue;
+ }
+
+ ///
+ /// Assigns a decimal value to a variable.
+ ///
+ /// The name of the variable.
+ /// The value of the variable.
+ /// True if the variable was set, false otherwise.
+ internal bool Assign(string name, decimal value)
+ {
+ Variable v = new Variable();
+ v.Type = VariableType.Decimal;
+ v.Value = value;
+
+ if (!this.variables.ContainsKey(name))
+ {
+ this.variables.Add(name, v);
+ }
+ else
+ {
+ this.variables[name] = v;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Assigns a decimal value to a variable.
+ ///
+ /// The name of the variable.
+ /// The expression of the variable.
+ /// True if the variable was set, false otherwise.
+ internal bool Assign(string name, string expression)
+ {
+ Variable v = new Variable();
+ v.Type = VariableType.Equation;
+ v.Value = expression;
+
+ if (!this.variables.ContainsKey(name))
+ {
+ this.variables.Add(name, v);
+ }
+ else
+ {
+ this.variables[name] = v;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Assigns a decimal value to a variable.
+ ///
+ /// The name of the variable.
+ /// The values of the variable.
+ /// True if the variable was set, false otherwise.
+ internal bool Assign(string name, decimal[] values)
+ {
+ Variable v = new Variable();
+ v.Type = VariableType.Array;
+ v.Value = values;
+
+ if (!this.variables.ContainsKey(name))
+ {
+ this.variables.Add(name, v);
+ }
+ else
+ {
+ this.variables[name] = v;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Executes a function stored in the interpreter.
+ ///
+ /// The name of the function to execute.
+ /// The arguments to pass to the function.
+ /// The value computed from the function execution.
+ internal decimal ExecuteFunction(string name, decimal[] args)
+ {
+ foreach (ICodedFunction codedFunction in this.codedFunctions)
+ {
+ if (codedFunction.FunctionName == name)
+ {
+ return codedFunction.Execute(args);
+ }
+ }
+
+ foreach (InterpretedFunction interpretedFunction in this.interpretedFunctions)
+ {
+ if (interpretedFunction.Name == name)
+ {
+ string answer = interpretedFunction.Compute(args);
+ decimal parsed = 0;
+ if (decimal.TryParse(answer, out parsed))
+ {
+ return parsed;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Loads the default coded functions supported by the interpreter.
+ ///
+ private void LoadDefaultCodedFunctions()
+ {
+ this.codedFunctions.Add(new CF_Sin());
+ this.codedFunctions.Add(new CF_Cos());
+ this.codedFunctions.Add(new CF_Tan());
+ this.codedFunctions.Add(new CF_Round());
+ this.codedFunctions.Add(new CF_Sqrt());
+ this.codedFunctions.Add(new CF_Abs());
+ this.codedFunctions.Add(new CF_Exp());
+ this.codedFunctions.Add(new CF_Log());
+ this.codedFunctions.Add(new CF_Precision());
+ }
+
+ ///
+ /// Produces output given a single object.
+ ///
+ /// The object representing the output.
+ internal void ProduceOutput(object output)
+ {
+ if (output is bool)
+ {
+ bool o = (bool)output;
+ if (o)
+ {
+ this.calculatedValue = 1;
+ }
+ else
+ {
+ this.calculatedValue = 0;
+ }
+ }
+ this.output = string.Format("{0}", output);
+ }
+
+ ///
+ /// Produces output given an object and a message.
+ ///
+ /// The object representing the output.
+ /// The message to be displayed with the output.
+ private void ProduceOutput(object output, string message)
+ {
+ if (!string.IsNullOrEmpty(message))
+ {
+ this.output = string.Format("{0}", output);
+ this.message = message;
+ }
+ else
+ {
+ ProduceOutput(output);
+ this.message = string.Empty;
+ }
+ }
+
+ #endregion
+
+ #region Asynchronous
+
+ /// Interpret an input asynchronously.
+ /// The input to interpret and execute.
+ /// The callback.
+ public void InterpretAsync(string input, Action callback)
+ {
+ InterpretAsyncDelegate del = new InterpretAsyncDelegate(InterpretAsyncThreadingWork);
+ del.BeginInvoke(input, (result) =>
+ {
+ AsyncResult returned = result as AsyncResult;
+ if (returned != null)
+ {
+ InterpretAsyncDelegate end = returned.AsyncDelegate as InterpretAsyncDelegate;
+ if (end != null)
+ {
+ InputInterpreter returnValue = end.EndInvoke(result);
+ callback(returnValue);
+ }
+ }
+ }, null);
+ }
+
+ /// Interpret asynchronous threading work.
+ /// The input to interpret and execute.
+ private InputInterpreter InterpretAsyncThreadingWork(string input)
+ {
+ Interpret(input);
+ return this;
+ }
+
+ /// Interpret asynchronous delegate.
+ /// The input.
+ /// .
+ private delegate InputInterpreter InterpretAsyncDelegate(string input);
+
+ #endregion
+
+ #region Computable
+
+ /// Converts this object to a computable.
+ /// This object as a Computable.
+ public Computable ToComputable()
+ {
+ return new Computable(this.Decimal.ToString(), this);
+ }
+
+ /// Treats the current object as a computable and performs an action in that context.
+ /// The action to execute as a computable object.
+ /// This object as a Computable, after the given action.
+ public Computable AsComputable(Func action)
+ {
+ return action(this.ToComputable());
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/InterpretedFunction.cs b/CS-MIC/csmic/csmic/InterpretedFunction.cs
new file mode 100644
index 0000000..70c29d6
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpretedFunction.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// Represents a user defined function that can be executed by the interpreter.
+ ///
+ public class InterpretedFunction
+ {
+ #region Members
+
+ ///
+ /// The name of the function.
+ ///
+ private string name;
+ ///
+ /// The number of expected arguments.
+ ///
+ private int numExpectedArguments;
+ ///
+ /// The set of instructions to be passed to the internal inputInterpreter.
+ ///
+ private MacroOperation script;
+ ///
+ /// A set of arguments used in computation of the function.
+ ///
+ private InterpretedFunctionArgument[] arguments;
+ ///
+ /// The internal macro builder used for computation.
+ ///
+ private MacroBuilder macroFunction;
+ ///
+ /// The internal input inputInterpreter that macro builder will use for computation.
+ ///
+ private InputInterpreter interpreter;
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Creates a new interpreted function.
+ ///
+ /// The name of the fuction.
+ /// The node to be used in computation.
+ /// A set of argument names to be used in computation.
+ internal InterpretedFunction(string name, MacroOperation script, params string[] args)
+ {
+ this.name = name;
+ this.script = script;
+ this.macroFunction = null;
+ this.arguments = new InterpretedFunctionArgument[args.Length];
+ this.interpreter = new InputInterpreter();
+ this.numExpectedArguments = args.Length;
+
+ for (int i = 0; i < args.Length; i++)
+ {
+ this.arguments[i] = new InterpretedFunctionArgument(args[i], 0);
+ }
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the name of the function.
+ ///
+ public string Name
+ {
+ get
+ {
+ return this.name;
+ }
+ }
+
+ ///
+ /// Gets the number of expected arguments for the function.
+ ///
+ public int NumExpectedArguments
+ {
+ get
+ {
+ return this.numExpectedArguments;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Computes the value of the function.
+ ///
+ /// The arguments used for computation.
+ /// The decimal value computed by the function.
+ public string Compute(params decimal[] args)
+ {
+ if (args.Length != this.numExpectedArguments)
+ {
+ return "0";
+ }
+
+ if (args.Length == this.arguments.Length)
+ {
+ for (int i = 0; i < args.Length; i++)
+ {
+ this.arguments[i].Value = args[i];
+ }
+ }
+
+ foreach (InterpretedFunctionArgument argument in this.arguments)
+ {
+ this.interpreter.Interpret(string.Format("{0} :: {1}", argument.Name, argument.Value));
+ }
+
+ this.macroFunction = new MacroBuilder(this.script, this.interpreter);
+
+ return this.macroFunction.FinalOutput;
+ }
+
+ #endregion
+
+ ///
+ /// Because a function's internal pattern may be different, we must manually check to see if the function
+ /// names are the same.
+ ///
+ /// The object to test.
+ /// True if the functions are the same.
+ public override bool Equals(object obj)
+ {
+ InterpretedFunction fun = obj as InterpretedFunction;
+ if(fun != null)
+ {
+ return fun.name == this.name;
+ }
+
+ return false;
+ }
+
+ /// Serves as a hash function for a particular type.
+ /// A hash code for the current .
+ public override int GetHashCode()
+ {
+ return this.script.GetHashCode() & this.name.GetHashCode();
+ }
+ }
+}
diff --git a/CS-MIC/csmic/csmic/InterpretedFunctionArgument.cs b/CS-MIC/csmic/csmic/InterpretedFunctionArgument.cs
new file mode 100644
index 0000000..2338b6e
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpretedFunctionArgument.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// Represents an argument made in an interpreted function.
+ ///
+ public class InterpretedFunctionArgument
+ {
+ #region Members
+
+ ///
+ /// The name of the argument.
+ ///
+ private string name;
+ ///
+ /// The value of the argument.
+ ///
+ private decimal value;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Creates a new interpreted function argument.
+ ///
+ public InterpretedFunctionArgument()
+ {
+ this.name = string.Empty;
+ this.value = 0;
+ }
+
+ ///
+ /// Creates a new interpreted function argument.
+ ///
+ /// The name of the argument in the interpreted function.
+ /// The value of the argument to use in the interpreted function.
+ public InterpretedFunctionArgument(string name, decimal value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the name of the argument.
+ ///
+ public string Name
+ {
+ get
+ {
+ return this.name;
+ }
+ set
+ {
+ this.name = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the value of the argument.
+ ///
+ public decimal Value
+ {
+ get
+ {
+ return this.value;
+ }
+ set
+ {
+ this.value = value;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/InterpreterParser/CSMIC.atg b/CS-MIC/csmic/csmic/InterpreterParser/CSMIC.atg
new file mode 100644
index 0000000..eb741c0
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpreterParser/CSMIC.atg
@@ -0,0 +1,369 @@
+using csmic;
+using System.Text;
+using System.Collections.Generic;
+
+COMPILER CSMIC
+
+/*
+*
+* Class Structures
+*
+*/
+
+private decimal calcValue = 0;
+private string stringValue = string.Empty;
+
+public decimal CalculatedValue
+{
+ get
+ {
+ return this.calcValue;
+ }
+ set
+ {
+ this.calcValue = value;
+ }
+}
+
+private InputInterpreter interpreter = null;
+
+public InputInterpreter Interpreter
+{
+ get
+ {
+ return this.interpreter;
+ }
+ set
+ {
+ this.interpreter = value;
+ }
+}
+
+bool IsFunctionCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _LPAREN && la.kind == _identifier)
+ return true;
+ return false;
+}
+
+bool IsCompare()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _COMPARER)
+ return true;
+ return false;
+}
+
+bool IsAssignment()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.val == "::" || next.val == ":=" || next.val == "->")
+ return true;
+ return false;
+}
+
+bool IsArrayCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if(next.val == "[")
+ return true;
+ return false;
+}
+
+CHARACTERS
+
+ UpperLetter = 'A'..'Z'.
+ LowerLetter = 'a'..'z'.
+ letter = UpperLetter + LowerLetter.
+ digit = "0123456789" .
+ cr = '\r' .
+ lf = '\n' .
+ tab = '\t' .
+ PM = "+-" .
+ NoQuote = ANY - '\"' .
+
+TOKENS
+
+ identifier = letter { letter | digit}.
+ sign = PM .
+ binary = ( '0' | '1' ) { '0' | '1' } ('B' | 'b') .
+ hex = "0x" ( digit | ('A' | 'B' | 'C' | 'D' | 'E' |'F') | ('a' | 'b' | 'c' | 'd' | 'e' |'f') ) { digit | ('A' | 'B' | 'C' | 'D' | 'E' |'F') | ('a' | 'b' | 'c' | 'd' | 'e' |'f') } .
+ number = digit { digit }['.' {digit}] [('E'|'e')['+'|'-'] digit {digit}] .
+ string = "\"" { NoQuote } "\"" .
+ LPAREN = '(' .
+ RPAREN = ')' .
+ COMPARER = "==" | "<" | ">" | "<=" | ">=" .
+
+IGNORE cr + tab
+
+/*
+ * Parser specification
+ *
+ */
+
+PRODUCTIONS
+
+CSMIC (. decimal r = 0;
+ string s = string.Empty;
+ decimal[] a = new decimal[0];
+ bool success = true;
+ if(this.interpreter == null)
+ {
+ return;
+ }
+ .)
+=
+ IF(IsCompare())
+ Comparison (. this.calcValue = (success == true) ? 1 : 0; this.interpreter.ProduceOutput(success); .)
+ |
+ IF(IsAssignment())
+ Assignment (. this.calcValue = r; .)
+ |
+ Expression (. this.calcValue = r; this.interpreter.ProduceOutput(r); .)
+ |
+ String (. this.stringValue = s; this.interpreter.ProduceOutput(s); .)
+.
+
+String
+=
+ string (. s = t.val; .)
+
+.
+
+Expression
+=
+ (. decimal r1; .)
+Term
+{
+ '+' Term (. r += r1; .)
+|
+ '-' Term (. r -= r1; .)
+}
+.
+
+Term (. decimal r1; .)
+=
+ Factor
+ {
+ '*'
+ Factor (. r *= r1; .)
+|
+ '/'
+ Factor (. r /= r1; .)
+|
+ '%' Term (. r %= r1; .)
+}
+.
+
+Factor (. decimal r1; .)
+=
+ Value
+ {
+ '^'
+ Expression (. r = Convert.ToDecimal(Math.Pow(Convert.ToDouble(r), Convert.ToDouble(r1))); .)
+ }
+.
+
+Value (. r = 0;
+ decimal r1 = 0;
+ string fn;
+ int sign = 1;.)
+=
+
+ [
+ "+"
+ |
+ "-" (. sign = -1; .)
+ ]
+(
+ IF(IsFunctionCall())
+ Function (. r = sign * r; .)
+|
+ IF(IsArrayCall())
+ ArrayCall (. r = sign * r; .)
+|
+ identifier (. if(this.interpreter.variables.ContainsKey(t.val))
+ {
+ Variable v = this.interpreter.variables[t.val];
+ if(v.Type == VariableType.Equation)
+ {
+ InputInterpreter i = new InputInterpreter(this.interpreter);
+ i.Interpret(v.Value.ToString());
+ r = i.Decimal;
+ }
+ else if(v.Type == VariableType.Decimal)
+ {
+ r = Convert.ToDecimal(v.Value);
+ }
+ else
+ {
+ r = 0;
+ }
+ }
+ .)
+|
+ number (. r = sign * Convert.ToDecimal (t.val); .)
+|
+ hex (. string expression = t.val.Remove(0,2);
+ try
+ {
+ decimal value = Convert.ToDecimal(Convert.ToInt64(expression, 16));
+ r = sign * value;
+ }
+ catch
+ {
+ r = 0;
+ }
+ .)
+|
+ binary (. string expression = t.val.Remove(t.val.Length - 1);
+ try
+ {
+ decimal value = Convert.ToDecimal(Convert.ToInt64(expression, 2));
+ r = sign * value;
+ }
+ catch
+ {
+ r = 0;
+ }
+ .)
+|
+ '('
+ Expression
+ ')' (. r = sign * r; .)
+)
+.
+
+ArrayL
+=
+'['
+CommaList
+']'
+.
+
+ArrayCall (. string ident = string.Empty; r = 0; decimal pos = 0; .)
+=
+identifier (. ident = t.val; .)
+'['
+ Expression (. int i = 0;
+ try
+ {
+ i = Convert.ToInt32(pos);
+ if(this.interpreter.variables.ContainsKey(ident))
+ {
+ decimal[] values = this.interpreter.variables[ident].Value as decimal[];
+ if(values != null)
+ {
+ r = values[i];
+ }
+ }
+ }
+ catch
+ {
+ }
+ .)
+']'
+.
+
+CommaList (. List list = new List(); decimal r = 0; .)
+=
+Expression (. list.Add(r); d = list.ToArray(); .)
+{
+ ','
+ Expression (. list.Add(r); d = list.ToArray(); .)
+}
+.
+
+Assignment (.
+ string identifier = string.Empty;
+ string expression = string.Empty;
+ decimal[] d = new decimal[0];
+ r = 0;
+ .)
+=
+identifier (. identifier = t.val; .)
+(
+ (
+ "::"
+ Expression (. this.interpreter.Assign(identifier, r); .)
+ (. this.interpreter.ProduceOutput(r); .)
+ )
+ |
+ (
+ ":="
+ AnyExpression (. this.interpreter.Assign(identifier, expression); .)
+ (. this.interpreter.ProduceOutput(expression); .)
+ )
+ |
+ (
+ "->"
+ ArrayL (. this.interpreter.Assign(identifier, d); r = 0; .)
+ (.
+ StringBuilder builder = new StringBuilder();
+ foreach(decimal dec in d)
+ {
+ builder.Append("," + dec.ToString());
+ }
+ builder.Remove(0,1);
+ this.interpreter.ProduceOutput(builder.ToString());
+ .)
+ )
+)
+.
+
+Function (.
+ string functionName = string.Empty;
+ decimal[] d = new decimal[0];
+ .)
+=
+identifier (. functionName = t.val; .)
+'('
+CommaList
+')' (. r = this.interpreter.ExecuteFunction(functionName, d); .)
+.
+
+Comparison (.
+ decimal firstValue = 0;
+ decimal secondValue = 0;
+ string compareType = string.Empty;
+ .)
+=
+Expression
+COMPARER (. compareType = t.val; .)
+Expression (.
+ switch(compareType)
+ {
+ case "==":
+ result = (firstValue == secondValue);
+ break;
+ case ">":
+ result = (firstValue > secondValue);
+ break;
+ case "<":
+ result = (firstValue < secondValue);
+ break;
+ case ">=":
+ result = (firstValue >= secondValue);
+ break;
+ case "<=":
+ result = (firstValue <= secondValue);
+ break;
+ default:
+ result = false;
+ break;
+ }
+ .)
+.
+
+AnyExpression (. value = string.Empty; StringBuilder builder = new StringBuilder(); .)
+=
+ANY (. builder.Append(t.val); .) { ANY (. builder.Append(t.val); .) } (. value = builder.ToString(); .)
+.
+
+
+END CSMIC.
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/InterpreterParser/Parser.cs b/CS-MIC/csmic/csmic/InterpreterParser/Parser.cs
new file mode 100644
index 0000000..218958a
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpreterParser/Parser.cs
@@ -0,0 +1,534 @@
+using csmic;
+using System.Text;
+using System.Collections.Generic;
+
+
+
+using System;
+using System.CodeDom.Compiler;
+
+namespace csmic.Interpreter {
+
+
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Parser {
+ public const int _EOF = 0;
+ public const int _identifier = 1;
+ public const int _sign = 2;
+ public const int _binary = 3;
+ public const int _hex = 4;
+ public const int _number = 5;
+ public const int _string = 6;
+ public const int _LPAREN = 7;
+ public const int _RPAREN = 8;
+ public const int _COMPARER = 9;
+ public const int maxT = 22;
+
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+private decimal calcValue = 0;
+private string stringValue = string.Empty;
+
+public decimal CalculatedValue
+{
+ get
+ {
+ return this.calcValue;
+ }
+ set
+ {
+ this.calcValue = value;
+ }
+}
+
+private InputInterpreter interpreter = null;
+
+public InputInterpreter Interpreter
+{
+ get
+ {
+ return this.interpreter;
+ }
+ set
+ {
+ this.interpreter = value;
+ }
+}
+
+bool IsFunctionCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _LPAREN && la.kind == _identifier)
+ return true;
+ return false;
+}
+
+bool IsCompare()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _COMPARER)
+ return true;
+ return false;
+}
+
+bool IsAssignment()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.val == "::" || next.val == ":=" || next.val == "->")
+ return true;
+ return false;
+}
+
+bool IsArrayCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if(next.val == "[")
+ return true;
+ return false;
+}
+
+
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (string msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ bool StartOf (int s) {
+ return set[s, la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+
+ bool WeakSeparator(int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) {Get(); return true;}
+ else if (StartOf(repFol)) {return false;}
+ else {
+ SynErr(n);
+ while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+
+ void CSMIC() {
+ decimal r = 0;
+ string s = string.Empty;
+ decimal[] a = new decimal[0];
+ bool success = true;
+ if(this.interpreter == null)
+ {
+ return;
+ }
+
+ if (IsCompare()) {
+ Comparison(out success);
+ this.calcValue = (success == true) ? 1 : 0; this.interpreter.ProduceOutput(success);
+ } else if (IsAssignment()) {
+ Assignment(out r);
+ this.calcValue = r;
+ } else if (StartOf(1)) {
+ Expression(out r);
+ this.calcValue = r; this.interpreter.ProduceOutput(r);
+ } else if (la.kind == 6) {
+ String(out s);
+ this.stringValue = s; this.interpreter.ProduceOutput(s);
+ } else SynErr(23);
+ }
+
+ void Comparison(out bool result) {
+ decimal firstValue = 0;
+ decimal secondValue = 0;
+ string compareType = string.Empty;
+
+ Expression(out firstValue);
+ Expect(9);
+ compareType = t.val;
+ Expression(out secondValue);
+ switch(compareType)
+ {
+ case "==":
+ result = (firstValue == secondValue);
+ break;
+ case ">":
+ result = (firstValue > secondValue);
+ break;
+ case "<":
+ result = (firstValue < secondValue);
+ break;
+ case ">=":
+ result = (firstValue >= secondValue);
+ break;
+ case "<=":
+ result = (firstValue <= secondValue);
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ }
+
+ void Assignment(out decimal r) {
+ string identifier = string.Empty;
+ string expression = string.Empty;
+ decimal[] d = new decimal[0];
+ r = 0;
+
+ Expect(1);
+ identifier = t.val;
+ if (la.kind == 19) {
+ Get();
+ Expression(out r);
+ this.interpreter.Assign(identifier, r);
+ this.interpreter.ProduceOutput(r);
+ } else if (la.kind == 20) {
+ Get();
+ AnyExpression(out expression);
+ this.interpreter.Assign(identifier, expression);
+ this.interpreter.ProduceOutput(expression);
+ } else if (la.kind == 21) {
+ Get();
+ ArrayL(out d);
+ this.interpreter.Assign(identifier, d); r = 0;
+ StringBuilder builder = new StringBuilder();
+ foreach(decimal dec in d)
+ {
+ builder.Append("," + dec.ToString());
+ }
+ builder.Remove(0,1);
+ this.interpreter.ProduceOutput(builder.ToString());
+
+ } else SynErr(24);
+ }
+
+ void Expression(out decimal r) {
+ decimal r1;
+ Term(out r);
+ while (la.kind == 10 || la.kind == 11) {
+ if (la.kind == 10) {
+ Get();
+ Term(out r1);
+ r += r1;
+ } else {
+ Get();
+ Term(out r1);
+ r -= r1;
+ }
+ }
+ }
+
+ void String(out string s) {
+ Expect(6);
+ s = t.val;
+ }
+
+ void Term(out decimal r) {
+ decimal r1;
+ Factor(out r);
+ while (la.kind == 12 || la.kind == 13 || la.kind == 14) {
+ if (la.kind == 12) {
+ Get();
+ Factor(out r1);
+ r *= r1;
+ } else if (la.kind == 13) {
+ Get();
+ Factor(out r1);
+ r /= r1;
+ } else {
+ Get();
+ Term(out r1);
+ r %= r1;
+ }
+ }
+ }
+
+ void Factor(out decimal r) {
+ decimal r1;
+ Value(out r);
+ while (la.kind == 15) {
+ Get();
+ Expression(out r1);
+ r = Convert.ToDecimal(Math.Pow(Convert.ToDouble(r), Convert.ToDouble(r1)));
+ }
+ }
+
+ void Value(out decimal r) {
+ r = 0;
+ decimal r1 = 0;
+ string fn;
+ int sign = 1;
+ if (la.kind == 10 || la.kind == 11) {
+ if (la.kind == 10) {
+ Get();
+ } else {
+ Get();
+ sign = -1;
+ }
+ }
+ if (IsFunctionCall()) {
+ Function(out r);
+ r = sign * r;
+ } else if (IsArrayCall()) {
+ ArrayCall(out r);
+ r = sign * r;
+ } else if (la.kind == 1) {
+ Get();
+ if(this.interpreter.variables.ContainsKey(t.val))
+ {
+ Variable v = this.interpreter.variables[t.val];
+ if(v.Type == VariableType.Equation)
+ {
+ InputInterpreter i = new InputInterpreter(this.interpreter);
+ i.Interpret(v.Value.ToString());
+ r = i.Decimal;
+ }
+ else if(v.Type == VariableType.Decimal)
+ {
+ r = Convert.ToDecimal(v.Value);
+ }
+ else
+ {
+ r = 0;
+ }
+ }
+
+ } else if (la.kind == 5) {
+ Get();
+ r = sign * Convert.ToDecimal (t.val);
+ } else if (la.kind == 4) {
+ Get();
+ string expression = t.val.Remove(0,2);
+ try
+ {
+ decimal value = Convert.ToDecimal(Convert.ToInt64(expression, 16));
+ r = sign * value;
+ }
+ catch
+ {
+ r = 0;
+ }
+
+ } else if (la.kind == 3) {
+ Get();
+ string expression = t.val.Remove(t.val.Length - 1);
+ try
+ {
+ decimal value = Convert.ToDecimal(Convert.ToInt64(expression, 2));
+ r = sign * value;
+ }
+ catch
+ {
+ r = 0;
+ }
+
+ } else if (la.kind == 7) {
+ Get();
+ Expression(out r);
+ Expect(8);
+ r = sign * r;
+ } else SynErr(25);
+ }
+
+ void Function(out decimal r) {
+ string functionName = string.Empty;
+ decimal[] d = new decimal[0];
+
+ Expect(1);
+ functionName = t.val;
+ Expect(7);
+ CommaList(out d);
+ Expect(8);
+ r = this.interpreter.ExecuteFunction(functionName, d);
+ }
+
+ void ArrayCall(out decimal r) {
+ string ident = string.Empty; r = 0; decimal pos = 0;
+ Expect(1);
+ ident = t.val;
+ Expect(16);
+ Expression(out pos);
+ int i = 0;
+ try
+ {
+ i = Convert.ToInt32(pos);
+ if(this.interpreter.variables.ContainsKey(ident))
+ {
+ decimal[] values = this.interpreter.variables[ident].Value as decimal[];
+ if(values != null)
+ {
+ r = values[i];
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ Expect(17);
+ }
+
+ void ArrayL(out decimal[] d) {
+ Expect(16);
+ CommaList(out d);
+ Expect(17);
+ }
+
+ void CommaList(out decimal[] d) {
+ List list = new List(); decimal r = 0;
+ Expression(out r);
+ list.Add(r); d = list.ToArray();
+ while (la.kind == 18) {
+ Get();
+ Expression(out r);
+ list.Add(r); d = list.ToArray();
+ }
+ }
+
+ void AnyExpression(out string value) {
+ value = string.Empty; StringBuilder builder = new StringBuilder();
+ Get();
+ builder.Append(t.val);
+ while (StartOf(2)) {
+ Get();
+ builder.Append(t.val);
+ }
+ value = builder.ToString();
+ }
+
+
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+ CSMIC();
+ Expect(0);
+
+ Expect(0);
+ }
+
+ static readonly bool[,] set = {
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, T,T,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}
+
+ };
+} // end Parser
+
+
+public class Errors {
+ public int count = 0; // number of errors detected
+ public StringBuilder builder = new StringBuilder(); // error messages go to this stream
+ public string errMsgFormat = "-- position {0}: {1}"; // 0=line, 1=column, 2=text
+
+ public void SynErr (int line, int col, int n) {
+ string s;
+ switch (n) {
+ case 0: s = "EOF expected"; break;
+ case 1: s = "identifier expected"; break;
+ case 2: s = "sign expected"; break;
+ case 3: s = "binary expected"; break;
+ case 4: s = "hex expected"; break;
+ case 5: s = "number expected"; break;
+ case 6: s = "string expected"; break;
+ case 7: s = "LPAREN expected"; break;
+ case 8: s = "RPAREN expected"; break;
+ case 9: s = "COMPARER expected"; break;
+ case 10: s = "\"+\" expected"; break;
+ case 11: s = "\"-\" expected"; break;
+ case 12: s = "\"*\" expected"; break;
+ case 13: s = "\"/\" expected"; break;
+ case 14: s = "\"%\" expected"; break;
+ case 15: s = "\"^\" expected"; break;
+ case 16: s = "\"[\" expected"; break;
+ case 17: s = "\"]\" expected"; break;
+ case 18: s = "\",\" expected"; break;
+ case 19: s = "\"::\" expected"; break;
+ case 20: s = "\":=\" expected"; break;
+ case 21: s = "\"->\" expected"; break;
+ case 22: s = "??? expected"; break;
+ case 23: s = "invalid CSMIC"; break;
+ case 24: s = "invalid Assignment"; break;
+ case 25: s = "invalid Value"; break;
+
+ default: s = "error " + n; break;
+ }
+ builder.AppendFormat(errMsgFormat, col, s);
+ count++;
+ }
+
+ public void SemErr (int line, int col, string s) {
+ builder.AppendFormat(errMsgFormat, col, s);
+ count++;
+ }
+
+ public void SemErr (string s) {
+ builder.AppendLine(s);
+ count++;
+ }
+
+ public void Warning (int line, int col, string s) {
+ builder.AppendFormat(errMsgFormat, col, s);
+ }
+
+ public void Warning(string s) {
+ builder.AppendLine(s);
+ }
+} // Errors
+
+
+public class FatalError: Exception {
+ public FatalError(string m): base(m) {}
+}
+
+}
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/InterpreterParser/Parser.frame b/CS-MIC/csmic/csmic/InterpreterParser/Parser.frame
new file mode 100644
index 0000000..88d27f5
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpreterParser/Parser.frame
@@ -0,0 +1,160 @@
+/*----------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+----------------------------------------------------------------------*/
+-->begin
+using System;
+using System.CodeDom.Compiler;
+
+-->namespace
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Parser {
+-->constants
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+-->declarations
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (string msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+-->pragmas
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ bool StartOf (int s) {
+ return set[s, la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+
+ bool WeakSeparator(int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) {Get(); return true;}
+ else if (StartOf(repFol)) {return false;}
+ else {
+ SynErr(n);
+ while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+
+-->productions
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+-->parseRoot
+ Expect(0);
+ }
+
+ static readonly bool[,] set = {
+-->initialization
+ };
+} // end Parser
+
+
+public class Errors {
+ public int count = 0; // number of errors detected
+ public StringBuilder builder = new StringBuilder(); // error messages go to this stream
+ public string errMsgFormat = "-- position {0}: {1}"; // 0=line, 1=column, 2=text
+
+ public void SynErr (int line, int col, int n) {
+ string s;
+ switch (n) {
+-->errors
+ default: s = "error " + n; break;
+ }
+ builder.AppendFormat(errMsgFormat, col, s);
+ count++;
+ }
+
+ public void SemErr (int line, int col, string s) {
+ builder.AppendFormat(errMsgFormat, col, s);
+ count++;
+ }
+
+ public void SemErr (string s) {
+ builder.AppendLine(s);
+ count++;
+ }
+
+ public void Warning (int line, int col, string s) {
+ builder.AppendFormat(errMsgFormat, col, s);
+ }
+
+ public void Warning(string s) {
+ builder.AppendLine(s);
+ }
+} // Errors
+
+
+public class FatalError: Exception {
+ public FatalError(string m): base(m) {}
+}
+
diff --git a/CS-MIC/csmic/csmic/InterpreterParser/Scanner.cs b/CS-MIC/csmic/csmic/InterpreterParser/Scanner.cs
new file mode 100644
index 0000000..630ede2
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpreterParser/Scanner.cs
@@ -0,0 +1,491 @@
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.CodeDom.Compiler;
+
+namespace csmic.Interpreter {
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Token {
+ public int kind; // token kind
+ public int pos; // token position in bytes in the source text (starting at 0)
+ public int charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public string val; // token value
+ public Token next; // ML 2005-03-11 Tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+public class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public const int EOF = char.MaxValue + 1;
+ const int MIN_BUFFER_LENGTH = 1024; // 1KB
+ const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ byte[] buf; // input buffer
+ int bufStart; // position of first byte in buffer relative to input stream
+ int bufLen; // length of buffer
+ int fileLen; // length of input stream (may change if the stream is no file)
+ int bufPos; // current position in buffer
+ Stream stream; // input stream (seekable)
+ bool isUserStream; // was the stream opened by the user?
+
+ public Buffer (Stream s, bool isUserStream) {
+ stream = s; this.isUserStream = isUserStream;
+
+ if (stream.CanSeek) {
+ fileLen = (int) stream.Length;
+ bufLen = Math.Min(fileLen, MAX_BUFFER_LENGTH);
+ bufStart = Int32.MaxValue; // nothing in the buffer so far
+ } else {
+ fileLen = bufLen = bufStart = 0;
+ }
+
+ buf = new byte[(bufLen>0) ? bufLen : MIN_BUFFER_LENGTH];
+ if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
+ if (bufLen == fileLen && stream.CanSeek) Close();
+ }
+
+ protected Buffer(Buffer b) { // called in UTF8Buffer constructor
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ stream = b.stream;
+ // keep destructor from closing the stream
+ b.stream = null;
+ isUserStream = b.isUserStream;
+ }
+
+ ~Buffer() { Close(); }
+
+ protected void Close() {
+ if (!isUserStream && stream != null) {
+ stream.Close();
+ stream = null;
+ }
+ }
+
+ public virtual int Read () {
+ if (bufPos < bufLen) {
+ return buf[bufPos++];
+ } else if (Pos < fileLen) {
+ Pos = Pos; // shift buffer start to Pos
+ return buf[bufPos++];
+ } else if (stream != null && !stream.CanSeek && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++];
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek () {
+ int curPos = Pos;
+ int ch = Read();
+ Pos = curPos;
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public string GetString (int beg, int end) {
+ int len = 0;
+ char[] buf = new char[end - beg];
+ int oldPos = Pos;
+ Pos = beg;
+ while (Pos < end) buf[len++] = (char) Read();
+ Pos = oldPos;
+ return new String(buf, 0, len);
+ }
+
+ public int Pos {
+ get { return bufPos + bufStart; }
+ set {
+ if (value >= fileLen && stream != null && !stream.CanSeek) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = value - bufStart;
+ } else if (stream != null) { // must be swapped in
+ stream.Seek(value, SeekOrigin.Begin);
+ bufLen = stream.Read(buf, 0, buf.Length);
+ bufStart = value; bufPos = 0;
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ bufPos = fileLen - bufStart;
+ }
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.Length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ Array.Copy(buf, newBuf, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+ int read = stream.Read(buf, bufLen, free);
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+public class UTF8Buffer: Buffer {
+ public UTF8Buffer(Buffer b): base(b) {}
+
+ public override int Read() {
+ int ch;
+ do {
+ ch = base.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F; ch = base.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = base.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ const char EOL = '\n';
+ const int eofSym = 0; /* pdt */
+ const int maxT = 22;
+ const int noSym = 22;
+
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ int pos; // byte position of current character
+ int charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static readonly Dictionary start; // maps first token character to start state
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[128]; // text of current token
+ int tlen; // length of current token
+
+ static Scanner() {
+ start = new Dictionary(128);
+ for (int i = 65; i <= 90; ++i) start[i] = 1;
+ for (int i = 97; i <= 122; ++i) start[i] = 1;
+ start[43] = 2;
+ for (int i = 50; i <= 57; ++i) start[i] = 6;
+ start[48] = 17;
+ start[49] = 18;
+ start[34] = 11;
+ start[40] = 13;
+ start[41] = 14;
+ start[61] = 15;
+ start[60] = 19;
+ start[62] = 20;
+ start[42] = 21;
+ start[47] = 22;
+ start[37] = 23;
+ start[94] = 24;
+ start[91] = 25;
+ start[93] = 26;
+ start[44] = 27;
+ start[58] = 31;
+ start[45] = 32;
+ start[Buffer.EOF] = -1;
+
+ }
+
+ public Scanner (string fileName) {
+ try {
+ Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new Buffer(stream, false);
+ Init();
+ } catch (IOException) {
+ throw new FatalError("Cannot open file " + fileName);
+ }
+ }
+
+ public Scanner (Stream s) {
+ buffer = new Buffer(s, true);
+ Init();
+ }
+
+ void Init() {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError(String.Format("illegal byte order mark: EF {0,2:X} {1,2:X}", ch1, ch2));
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.Pos;
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+
+ }
+
+ void AddCh() {
+ if (tlen >= tval.Length) {
+ char[] newBuf = new char[2 * tval.Length];
+ Array.Copy(tval, 0, newBuf, 0, tval.Length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+ tval[tlen++] = (char) ch;
+ NextCh();
+ }
+ }
+
+
+
+
+ void CheckLiteral() {
+ switch (t.val) {
+ case "+": t.kind = 10; break;
+ case "-": t.kind = 11; break;
+ default: break;
+ }
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+ ch == 9 || ch == 13
+ ) NextCh();
+
+ int recKind = noSym;
+ int recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state;
+ state = (int) start[ch];
+ tlen = 0; AddCh();
+
+ switch (state) {
+ case -1: { t.kind = eofSym; break; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = recEnd - t.pos;
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break;
+ } // NextCh already done
+ case 1:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
+ else {t.kind = 1; break;}
+ case 2:
+ {t.kind = 2; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 3:
+ {t.kind = 3; break;}
+ case 4:
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {AddCh(); goto case 5;}
+ else {goto case 0;}
+ case 5:
+ recEnd = pos; recKind = 4;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {AddCh(); goto case 5;}
+ else {t.kind = 4; break;}
+ case 6:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 7:
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else if (ch == '+' || ch == '-') {AddCh(); goto case 8;}
+ else {goto case 0;}
+ case 8:
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else {goto case 0;}
+ case 9:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else {t.kind = 5; break;}
+ case 10:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 10;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else {t.kind = 5; break;}
+ case 11:
+ if (ch <= '!' || ch >= '#' && ch <= 65535) {AddCh(); goto case 11;}
+ else if (ch == '"') {AddCh(); goto case 12;}
+ else {goto case 0;}
+ case 12:
+ {t.kind = 6; break;}
+ case 13:
+ {t.kind = 7; break;}
+ case 14:
+ {t.kind = 8; break;}
+ case 15:
+ if (ch == '=') {AddCh(); goto case 16;}
+ else {goto case 0;}
+ case 16:
+ {t.kind = 9; break;}
+ case 17:
+ recEnd = pos; recKind = 5;
+ if (ch >= '2' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'B' || ch == 'b') {AddCh(); goto case 3;}
+ else if (ch >= '0' && ch <= '1') {AddCh(); goto case 18;}
+ else if (ch == 'x') {AddCh(); goto case 4;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 18:
+ recEnd = pos; recKind = 5;
+ if (ch >= '2' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'B' || ch == 'b') {AddCh(); goto case 3;}
+ else if (ch >= '0' && ch <= '1') {AddCh(); goto case 18;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 19:
+ recEnd = pos; recKind = 9;
+ if (ch == '=') {AddCh(); goto case 16;}
+ else {t.kind = 9; break;}
+ case 20:
+ recEnd = pos; recKind = 9;
+ if (ch == '=') {AddCh(); goto case 16;}
+ else {t.kind = 9; break;}
+ case 21:
+ {t.kind = 12; break;}
+ case 22:
+ {t.kind = 13; break;}
+ case 23:
+ {t.kind = 14; break;}
+ case 24:
+ {t.kind = 15; break;}
+ case 25:
+ {t.kind = 16; break;}
+ case 26:
+ {t.kind = 17; break;}
+ case 27:
+ {t.kind = 18; break;}
+ case 28:
+ {t.kind = 19; break;}
+ case 29:
+ {t.kind = 20; break;}
+ case 30:
+ {t.kind = 21; break;}
+ case 31:
+ if (ch == ':') {AddCh(); goto case 28;}
+ else if (ch == '=') {AddCh(); goto case 29;}
+ else {goto case 0;}
+ case 32:
+ recEnd = pos; recKind = 2;
+ if (ch == '>') {AddCh(); goto case 30;}
+ else {t.kind = 2; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.Pos = t.pos;
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // peek for the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at the current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
+}
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/InterpreterParser/Scanner.frame b/CS-MIC/csmic/csmic/InterpreterParser/Scanner.frame
new file mode 100644
index 0000000..8010e59
--- /dev/null
+++ b/CS-MIC/csmic/csmic/InterpreterParser/Scanner.frame
@@ -0,0 +1,383 @@
+/*----------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+-----------------------------------------------------------------------*/
+-->begin
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.CodeDom.Compiler;
+
+-->namespace
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Token {
+ public int kind; // token kind
+ public int pos; // token position in bytes in the source text (starting at 0)
+ public int charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public string val; // token value
+ public Token next; // ML 2005-03-11 Tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+public class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public const int EOF = char.MaxValue + 1;
+ const int MIN_BUFFER_LENGTH = 1024; // 1KB
+ const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ byte[] buf; // input buffer
+ int bufStart; // position of first byte in buffer relative to input stream
+ int bufLen; // length of buffer
+ int fileLen; // length of input stream (may change if the stream is no file)
+ int bufPos; // current position in buffer
+ Stream stream; // input stream (seekable)
+ bool isUserStream; // was the stream opened by the user?
+
+ public Buffer (Stream s, bool isUserStream) {
+ stream = s; this.isUserStream = isUserStream;
+
+ if (stream.CanSeek) {
+ fileLen = (int) stream.Length;
+ bufLen = Math.Min(fileLen, MAX_BUFFER_LENGTH);
+ bufStart = Int32.MaxValue; // nothing in the buffer so far
+ } else {
+ fileLen = bufLen = bufStart = 0;
+ }
+
+ buf = new byte[(bufLen>0) ? bufLen : MIN_BUFFER_LENGTH];
+ if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
+ if (bufLen == fileLen && stream.CanSeek) Close();
+ }
+
+ protected Buffer(Buffer b) { // called in UTF8Buffer constructor
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ stream = b.stream;
+ // keep destructor from closing the stream
+ b.stream = null;
+ isUserStream = b.isUserStream;
+ }
+
+ ~Buffer() { Close(); }
+
+ protected void Close() {
+ if (!isUserStream && stream != null) {
+ stream.Close();
+ stream = null;
+ }
+ }
+
+ public virtual int Read () {
+ if (bufPos < bufLen) {
+ return buf[bufPos++];
+ } else if (Pos < fileLen) {
+ Pos = Pos; // shift buffer start to Pos
+ return buf[bufPos++];
+ } else if (stream != null && !stream.CanSeek && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++];
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek () {
+ int curPos = Pos;
+ int ch = Read();
+ Pos = curPos;
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public string GetString (int beg, int end) {
+ int len = 0;
+ char[] buf = new char[end - beg];
+ int oldPos = Pos;
+ Pos = beg;
+ while (Pos < end) buf[len++] = (char) Read();
+ Pos = oldPos;
+ return new String(buf, 0, len);
+ }
+
+ public int Pos {
+ get { return bufPos + bufStart; }
+ set {
+ if (value >= fileLen && stream != null && !stream.CanSeek) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = value - bufStart;
+ } else if (stream != null) { // must be swapped in
+ stream.Seek(value, SeekOrigin.Begin);
+ bufLen = stream.Read(buf, 0, buf.Length);
+ bufStart = value; bufPos = 0;
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ bufPos = fileLen - bufStart;
+ }
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.Length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ Array.Copy(buf, newBuf, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+ int read = stream.Read(buf, bufLen, free);
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+public class UTF8Buffer: Buffer {
+ public UTF8Buffer(Buffer b): base(b) {}
+
+ public override int Read() {
+ int ch;
+ do {
+ ch = base.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F; ch = base.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = base.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ const char EOL = '\n';
+ const int eofSym = 0; /* pdt */
+-->declarations
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ int pos; // byte position of current character
+ int charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static readonly Dictionary start; // maps first token character to start state
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[128]; // text of current token
+ int tlen; // length of current token
+
+ static Scanner() {
+ start = new Dictionary(128);
+-->initialization
+ }
+
+ public Scanner (string fileName) {
+ try {
+ Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new Buffer(stream, false);
+ Init();
+ } catch (IOException) {
+ throw new FatalError("Cannot open file " + fileName);
+ }
+ }
+
+ public Scanner (Stream s) {
+ buffer = new Buffer(s, true);
+ Init();
+ }
+
+ void Init() {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError(String.Format("illegal byte order mark: EF {0,2:X} {1,2:X}", ch1, ch2));
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.Pos;
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+-->casing1
+ }
+
+ void AddCh() {
+ if (tlen >= tval.Length) {
+ char[] newBuf = new char[2 * tval.Length];
+ Array.Copy(tval, 0, newBuf, 0, tval.Length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+-->casing2
+ NextCh();
+ }
+ }
+
+
+-->comments
+
+ void CheckLiteral() {
+-->literals
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+-->scan1
+ ) NextCh();
+-->scan2
+ int recKind = noSym;
+ int recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state;
+ state = (int) start[ch];
+ tlen = 0; AddCh();
+
+ switch (state) {
+ case -1: { t.kind = eofSym; break; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = recEnd - t.pos;
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break;
+ } // NextCh already done
+-->scan3
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.Pos = t.pos;
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // peek for the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at the current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
diff --git a/CS-MIC/csmic/csmic/MacroBuilder.cs b/CS-MIC/csmic/csmic/MacroBuilder.cs
new file mode 100644
index 0000000..dad631c
--- /dev/null
+++ b/CS-MIC/csmic/csmic/MacroBuilder.cs
@@ -0,0 +1,337 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Threading;
+using csmic.Scripting;
+using System.Runtime.Remoting.Messaging;
+
+namespace csmic
+{
+ ///
+ /// A builder object that executes macro scripts.
+ ///
+ public class MacroBuilder
+ {
+ #region Members
+
+ ///
+ /// The input inputInterpreter.
+ ///
+ private InputInterpreter interpreter;
+ /// The script to run as a macro.
+ private string script;
+ ///
+ /// The output as a list of strings.
+ ///
+ private List output;
+ ///
+ /// The time for execution.
+ ///
+ private TimeSpan executionTime;
+ ///
+ /// The root macro operation.
+ ///
+ private MacroOperation rootOperation;
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Creates a new builder object that executes a given macro script.
+ ///
+ /// A list of strings representing the macro.
+ /// The InputInterpreter to be used.
+ public MacroBuilder(string script, InputInterpreter inputInterpreter)
+ {
+ this.output = new List();
+ this.executionTime = new TimeSpan();
+
+ this.script = script;
+ this.interpreter = inputInterpreter;
+ }
+
+ ///
+ /// Creates a new builder object that executes a given macro script.
+ ///
+ /// A list of strings representing the macro.
+ /// The InputInterpreter to be used.
+ internal MacroBuilder(MacroOperation script, InputInterpreter inputInterpreter)
+ {
+ this.output = new List();
+ this.executionTime = new TimeSpan();
+ DateTime timeStart = DateTime.Now;
+
+ this.interpreter = inputInterpreter;
+
+ this.rootOperation = script;
+
+ ExecuteOperation(this.rootOperation);
+
+ DateTime timeEnd = DateTime.Now;
+ this.executionTime = timeEnd - timeStart;
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets a list of strings representing the output.
+ ///
+ public List Output
+ {
+ get
+ {
+ return this.output;
+ }
+ }
+
+ ///
+ /// Gets the execution time of the last script computation.
+ ///
+ public TimeSpan LastExecutionTime
+ {
+ get
+ {
+ return this.executionTime;
+ }
+ }
+
+ ///
+ /// Gets the decimal value last computed by the macrobuilder.
+ ///
+ public string FinalOutput
+ {
+ get
+ {
+ return this.interpreter.Output;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// Runs this macro.
+ public void Run()
+ {
+ DateTime timeStart = DateTime.Now;
+
+ ASCIIEncoding encoder = new ASCIIEncoding();
+ Parser p = new Parser(new Scanner(new MemoryStream(encoder.GetBytes(this.script))));
+ p.Parse();
+
+ this.rootOperation = p.Root;
+
+ ExecuteOperation(p.Root);
+
+ DateTime timeEnd = DateTime.Now;
+ this.executionTime = timeEnd - timeStart;
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void ExecuteOperation(MacroOperation operation)
+ {
+ switch (operation.OperationType)
+ {
+ case OperationType.If:
+ if (operation.Input.Count == 1)
+ {
+ this.interpreter.Interpret(operation.Input[0]);
+ if (this.interpreter.Decimal == 1)
+ {
+ foreach (MacroOperation op in operation.Children)
+ {
+ ExecuteOperation(op);
+ }
+ }
+ }
+ break;
+ case OperationType.Else:
+ foreach (MacroOperation op in operation.Children)
+ {
+ ExecuteOperation(op);
+ }
+ break;
+ case OperationType.IfElse:
+ if (operation.Children.Count == 2 && operation.Children[0].Input.Count == 1)
+ {
+ MacroOperation ifOp = operation.Children[0];
+ MacroOperation elseOp = operation.Children[1];
+ this.interpreter.Interpret(ifOp.Input[0]);
+ if (this.interpreter.Decimal == 1)
+ {
+ foreach (MacroOperation op in ifOp.Children)
+ {
+ ExecuteOperation(op);
+ }
+ }
+ else
+ {
+ foreach (MacroOperation op in elseOp.Children)
+ {
+ ExecuteOperation(op);
+ }
+ }
+ }
+ break;
+ case OperationType.While:
+ if (operation.Input.Count == 1)
+ {
+ this.interpreter.Interpret(operation.Input[0]);
+ while (this.interpreter.Decimal == 1)
+ {
+ foreach (MacroOperation op in operation.Children)
+ {
+ ExecuteOperation(op);
+ }
+ this.interpreter.Interpret(operation.Input[0]);
+ }
+ }
+ break;
+ case OperationType.For:
+ if (operation.Input.Count == 3)
+ {
+ this.interpreter.Interpret(operation.Input[0]);
+ this.interpreter.Interpret(operation.Input[1]);
+ int loopCount = this.interpreter.Int;
+ while (this.interpreter.Int == 1)
+ {
+ foreach (MacroOperation op in operation.Children)
+ {
+ ExecuteOperation(op);
+ }
+ this.interpreter.Interpret(operation.Input[2]);
+ this.interpreter.Interpret(operation.Input[1]);
+ }
+ }
+ break;
+ case OperationType.FunctionDeclaration:
+ if (operation.Input.Count > 1)
+ {
+ string name = operation.Input[0];
+ operation.Input.RemoveAt(0);
+ StringBuilder builder = new StringBuilder();
+ operation.OperationType = OperationType.Unknown;
+ InterpretedFunction function = new InterpretedFunction(name, operation, operation.Input.ToArray());
+ if (this.interpreter.InterpretedFunctions.Contains(function))
+ {
+ this.interpreter.InterpretedFunctions[this.interpreter.InterpretedFunctions.IndexOf(function)] = function;
+ }
+ else
+ {
+ this.interpreter.InterpretedFunctions.Add(function);
+ }
+ }
+ break;
+ case OperationType.Echo:
+ if (operation.Children.Count == 1)
+ {
+ MacroOperation op = operation.Children[0];
+ if (op.OperationType == OperationType.Statement)
+ {
+ this.interpreter.Interpret(op.Input[0]);
+ this.output.Add(this.interpreter.Output);
+ }
+ }
+ break;
+ case OperationType.Say:
+ if (operation.Input.Count == 1)
+ {
+ this.output.Add(operation.Input[0]);
+ }
+ break;
+ case OperationType.Display:
+ StringBuilder sb = new StringBuilder();
+ foreach (MacroOperation op in operation.Children)
+ {
+ if (op.OperationType == OperationType.Statement)
+ {
+ if (op.Input.Count == 1)
+ {
+ this.interpreter.Interpret(op.Input[0]);
+ sb.Append(this.interpreter.Output);
+ }
+ }
+ else if (op.OperationType == OperationType.String)
+ {
+ if (op.Input.Count == 1)
+ {
+ sb.Append(op.Input[0]);
+ }
+ }
+ }
+ this.output.Add(sb.ToString());
+ break;
+ case OperationType.Statement:
+ if (operation.Input.Count == 1)
+ {
+ this.interpreter.Interpret(operation.Input[0]);
+ }
+ break;
+ case OperationType.String:
+ //Should not reach this state.
+ break;
+ case OperationType.Unknown:
+ if (operation.Children.Count > 0)
+ {
+ foreach (MacroOperation op in operation.Children)
+ {
+ ExecuteOperation(op);
+ }
+ }
+ break;
+ default:
+ //CRAP.
+ break;
+ }
+ }
+
+ #endregion
+
+ #region Asynchronous
+
+ /// Executes the asynchronous operation.
+ /// The input.
+ /// The callback.
+ public void RunAsync(string input, Action callback)
+ {
+ MacroAsyncDelegate del = new MacroAsyncDelegate(RunAsyncThreadingWork);
+ del.BeginInvoke(input, (result) =>
+ {
+ AsyncResult returned = result as AsyncResult;
+ if (returned != null)
+ {
+ MacroAsyncDelegate end = returned.AsyncDelegate as MacroAsyncDelegate;
+ if (end != null)
+ {
+ MacroBuilder returnValue = end.EndInvoke(result);
+ callback(returnValue);
+ }
+ }
+ }, null);
+ }
+
+ /// Executes the asynchronous threading work operation.
+ /// The input.
+ /// .
+ private MacroBuilder RunAsyncThreadingWork(string input)
+ {
+ Run();
+ return this;
+ }
+
+ /// Macro asynchronous delegate.
+ /// The input.
+ /// .
+ private delegate MacroBuilder MacroAsyncDelegate(string input);
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/MacroOperation.cs b/CS-MIC/csmic/csmic/MacroOperation.cs
new file mode 100644
index 0000000..4e448e7
--- /dev/null
+++ b/CS-MIC/csmic/csmic/MacroOperation.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// Represents the operation types supported by a scripted macro.
+ ///
+ internal enum OperationType
+ {
+ ///
+ /// Represents a conditional block.
+ ///
+ If,
+ ///
+ /// Represents a conditional else block.
+ ///
+ Else,
+ ///
+ /// Represents a complete conditional block.
+ ///
+ IfElse,
+ ///
+ /// A while block.
+ ///
+ While,
+ ///
+ /// A for block.
+ ///
+ For,
+ ///
+ /// A function declaration.
+ ///
+ FunctionDeclaration,
+ ///
+ /// An echo statement.
+ ///
+ Echo,
+ ///
+ /// A say statement.
+ ///
+ Say,
+ ///
+ /// A display statement.
+ ///
+ Display,
+ ///
+ /// A statement to execute.
+ ///
+ Statement,
+ ///
+ /// A string to display.
+ ///
+ String,
+ ///
+ /// An unknown or malformed block.
+ ///
+ Unknown
+ }
+
+ ///
+ /// An operation object that executes a specified action.
+ ///
+ internal class MacroOperation
+ {
+ #region Members
+
+ ///
+ /// The type of operation represented by the operation.
+ ///
+ private OperationType operationType;
+ ///
+ /// The collection of children nodes that belong to the operation.
+ ///
+ private List children;
+ ///
+ /// A list of the necesary input to execute the operation.
+ ///
+ private List input;
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Creates a new macro operation node.
+ ///
+ /// The type of operation the node represents.
+ public MacroOperation(OperationType operationType)
+ {
+ this.operationType = operationType;
+ this.children = new List();
+ this.input = new List();
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the children nodes of the operation.
+ ///
+ public List Children
+ {
+ get
+ {
+ return this.children;
+ }
+ set
+ {
+ this.children = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the input for the operation.
+ ///
+ public List Input
+ {
+ get
+ {
+ return this.input;
+ }
+ set
+ {
+ this.input = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the operation type for this operation.
+ ///
+ public OperationType OperationType
+ {
+ get
+ {
+ return this.operationType;
+ }
+ set
+ {
+ this.operationType = value;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/Properties/AssemblyInfo.cs b/CS-MIC/csmic/csmic/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..842b681
--- /dev/null
+++ b/CS-MIC/csmic/csmic/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("csmic")]
+[assembly: AssemblyDescription("A .NET component for easy access to parsing simple math and scripting.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Jordan Wages")]
+[assembly: AssemblyProduct("csmic")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e36b7d85-f0e6-4f24-ba03-ac53124dd97e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.1.5.0")]
+[assembly: AssemblyFileVersion("1.1.5.0")]
diff --git a/CS-MIC/csmic/csmic/ScriptParser/Parser.cs b/CS-MIC/csmic/csmic/ScriptParser/Parser.cs
new file mode 100644
index 0000000..4f29bbe
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ScriptParser/Parser.cs
@@ -0,0 +1,798 @@
+using csmic;
+using System.Text;
+using System.Collections.Generic;
+
+
+
+using System;
+using System.CodeDom.Compiler;
+
+namespace csmic.Scripting {
+
+
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Parser {
+ public const int _EOF = 0;
+ public const int _identifier = 1;
+ public const int _sign = 2;
+ public const int _binary = 3;
+ public const int _hex = 4;
+ public const int _number = 5;
+ public const int _newline = 6;
+ public const int _string = 7;
+ public const int _LPAREN = 8;
+ public const int _RPAREN = 9;
+ public const int _COMPARER = 10;
+ public const int maxT = 34;
+
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+private MacroOperation root = new MacroOperation(OperationType.Unknown);
+
+internal MacroOperation Root
+{
+ get
+ {
+ return this.root;
+ }
+ set
+ {
+ this.root = value;
+ }
+}
+
+bool IsFunctionCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _LPAREN && la.kind == _identifier)
+ return true;
+ return false;
+}
+
+bool IsCompare()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _COMPARER)
+ return true;
+ return false;
+}
+
+bool IsAssignment()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.val == "::" || next.val == ":=" || next.val == "->")
+ return true;
+ return false;
+}
+
+bool IsArrayCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if(next.val == "[")
+ return true;
+ return false;
+}
+
+
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (string msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ bool StartOf (int s) {
+ return set[s, la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+
+ bool WeakSeparator(int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) {Get(); return true;}
+ else if (StartOf(repFol)) {return false;}
+ else {
+ SynErr(n);
+ while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+
+ void SCRIPT() {
+ string statement = string.Empty;
+ while (StartOf(1)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ this.root.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref this.root);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref this.root);
+ break;
+ }
+ case 18: {
+ FunctionDeclaration(ref this.root);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref this.root);
+ break;
+ }
+ case 20: {
+ SayStatement(ref this.root);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref this.root);
+ break;
+ }
+ case 16: {
+ ForBlock(ref this.root);
+ break;
+ }
+ }
+ }
+ }
+
+ void Statement(out string value) {
+ value = string.Empty;
+ StringBuilder builder = new StringBuilder();
+
+ if (IsAssignment()) {
+ Assignment(ref builder);
+ value = builder.ToString();
+ } else if (StartOf(2)) {
+ Expression(ref builder);
+ value = builder.ToString();
+ } else SynErr(35);
+ }
+
+ void IfBlock(ref MacroOperation parent) {
+ MacroOperation ifBlock = new MacroOperation(OperationType.If);
+ MacroOperation elseBlock = new MacroOperation(OperationType.Else);
+ string ifStatement = string.Empty;
+ string statement = string.Empty;
+ StringBuilder builder = new StringBuilder();
+ bool hasElse = false;
+
+ Expect(11);
+ Expect(8);
+ Comparison(ref builder);
+ ifStatement = builder.ToString(); ifBlock.Input.Add(ifStatement);
+ Expect(9);
+ Expect(12);
+ while (StartOf(3)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ ifBlock.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref ifBlock);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref ifBlock);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref ifBlock);
+ break;
+ }
+ case 20: {
+ SayStatement(ref ifBlock);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref ifBlock);
+ break;
+ }
+ case 16: {
+ ForBlock(ref ifBlock);
+ break;
+ }
+ }
+ }
+ Expect(13);
+ if (la.kind == 14) {
+ Get();
+ hasElse = true;
+ Expect(12);
+ while (StartOf(3)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ elseBlock.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref elseBlock);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref elseBlock);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref elseBlock);
+ break;
+ }
+ case 20: {
+ SayStatement(ref elseBlock);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref elseBlock);
+ break;
+ }
+ case 16: {
+ ForBlock(ref elseBlock);
+ break;
+ }
+ }
+ }
+ Expect(13);
+ }
+ if(hasElse)
+ {
+ MacroOperation ifelse = new MacroOperation(OperationType.IfElse);
+ ifelse.Children.Add(ifBlock);
+ ifelse.Children.Add(elseBlock);
+ parent.Children.Add(ifelse);
+ }
+ else
+ {
+ parent.Children.Add(ifBlock);
+ }
+
+ }
+
+ void WhileBlock(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ MacroOperation whileBlock = new MacroOperation(OperationType.While);
+ string statement = string.Empty;
+
+ Expect(15);
+ Expect(8);
+ Comparison(ref builder);
+ whileBlock.Input.Add(builder.ToString());
+ Expect(9);
+ Expect(12);
+ while (StartOf(3)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ whileBlock.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref whileBlock);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref whileBlock);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref whileBlock);
+ break;
+ }
+ case 20: {
+ SayStatement(ref whileBlock);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref whileBlock);
+ break;
+ }
+ case 16: {
+ ForBlock(ref whileBlock);
+ break;
+ }
+ }
+ }
+ Expect(13);
+ parent.Children.Add(whileBlock);
+
+ }
+
+ void FunctionDeclaration(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ string statement = string.Empty;
+ MacroOperation func = new MacroOperation(OperationType.FunctionDeclaration);
+
+ Expect(18);
+ Expect(8);
+ CommaList(ref builder);
+ string[] args = builder.ToString().Split(','); func.Input.AddRange(args);
+ Expect(9);
+ Expect(12);
+ while (StartOf(3)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ func.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref func);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref func);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref func);
+ break;
+ }
+ case 20: {
+ SayStatement(ref func);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref func);
+ break;
+ }
+ case 16: {
+ ForBlock(ref func);
+ break;
+ }
+ }
+ }
+ Expect(13);
+ parent.Children.Add(func);
+
+ }
+
+ void EchoStatement(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ MacroOperation echoStatement = new MacroOperation(OperationType.Echo);
+ string statement = string.Empty;
+
+ Expect(19);
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ echoStatement.Children.Add(operation);
+ parent.Children.Add(echoStatement);
+
+ }
+
+ void SayStatement(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ MacroOperation sayStatement = new MacroOperation(OperationType.Say);
+ string statement = string.Empty;
+
+ Expect(20);
+ Expect(7);
+ statement = t.val.Replace("\"", "");
+ sayStatement.Input.Add(statement);
+ parent.Children.Add(sayStatement);
+
+ }
+
+ void DisplayStatement(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ MacroOperation displayStatement = new MacroOperation(OperationType.Display);
+ string statement = string.Empty;
+
+ Expect(21);
+ if (StartOf(2)) {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+
+ } else if (la.kind == 7) {
+ Get();
+ statement = t.val.Replace("\"", "");
+ MacroOperation operation = new MacroOperation(OperationType.String);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+
+ } else SynErr(36);
+ while (la.kind == 17) {
+ Get();
+ if (StartOf(2)) {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+
+ } else if (la.kind == 7) {
+ Get();
+ statement = t.val.Replace("\"", "");
+ MacroOperation operation = new MacroOperation(OperationType.String);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+
+ } else SynErr(37);
+ }
+ parent.Children.Add(displayStatement);
+
+ }
+
+ void ForBlock(ref MacroOperation parent) {
+ StringBuilder builder = new StringBuilder();
+ string statement = string.Empty;
+ string statement2 = string.Empty;
+ MacroOperation forBlock = new MacroOperation(OperationType.For);
+
+ Expect(16);
+ Expect(8);
+ Statement(out statement);
+ Expect(17);
+ Comparison(ref builder);
+ Expect(17);
+ Statement(out statement2);
+ forBlock.Input.Add(statement); forBlock.Input.Add(builder.ToString()); forBlock.Input.Add(statement2);
+ Expect(9);
+ Expect(12);
+ while (StartOf(3)) {
+ switch (la.kind) {
+ case 1: case 3: case 4: case 5: case 8: case 22: case 23: {
+ Statement(out statement);
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ forBlock.Children.Add(operation);
+
+ break;
+ }
+ case 11: {
+ IfBlock(ref forBlock);
+ break;
+ }
+ case 15: {
+ WhileBlock(ref forBlock);
+ break;
+ }
+ case 19: {
+ EchoStatement(ref forBlock);
+ break;
+ }
+ case 20: {
+ SayStatement(ref forBlock);
+ break;
+ }
+ case 21: {
+ DisplayStatement(ref forBlock);
+ break;
+ }
+ case 16: {
+ ForBlock(ref forBlock);
+ break;
+ }
+ }
+ }
+ Expect(13);
+ parent.Children.Add(forBlock);
+
+ }
+
+ void Comparison(ref StringBuilder result) {
+ Expression(ref result);
+ Expect(10);
+ result.Append(t.val);
+ Expression(ref result);
+ }
+
+ void CommaList(ref StringBuilder builder) {
+ Expression(ref builder);
+ while (la.kind == 17) {
+ Get();
+ builder.Append(t.val);
+ Expression(ref builder);
+ }
+ }
+
+ void Assignment(ref StringBuilder builder) {
+ Expect(1);
+ builder.Append(t.val);
+ if (la.kind == 30) {
+ Get();
+ builder.Append(t.val);
+ Expression(ref builder);
+ } else if (la.kind == 31) {
+ Get();
+ builder.Append(t.val); string value = string.Empty;
+ AnyExpression(out value);
+ builder.Append(value);
+ Expect(6);
+ } else if (la.kind == 32) {
+ Get();
+ builder.Append(t.val);
+ ArrayL(ref builder);
+ } else SynErr(38);
+ }
+
+ void Expression(ref StringBuilder builder) {
+ Term(ref builder);
+ while (la.kind == 22 || la.kind == 23 || la.kind == 24) {
+ if (la.kind == 22) {
+ Get();
+ builder.Append(t.val);
+ Term(ref builder);
+ } else if (la.kind == 23) {
+ Get();
+ builder.Append(t.val);
+ Term(ref builder);
+ } else {
+ Get();
+ builder.Append(t.val);
+ Term(ref builder);
+ }
+ }
+ }
+
+ void Term(ref StringBuilder builder) {
+ Factor(ref builder);
+ while (la.kind == 25 || la.kind == 26) {
+ if (la.kind == 25) {
+ Get();
+ builder.Append(t.val);
+ Factor(ref builder);
+ } else {
+ Get();
+ builder.Append(t.val);
+ Factor(ref builder);
+ }
+ }
+ }
+
+ void Factor(ref StringBuilder builder) {
+ Value(ref builder);
+ while (la.kind == 27) {
+ Get();
+ builder.Append(t.val);
+ Value(ref builder);
+ }
+ }
+
+ void Value(ref StringBuilder builder) {
+ if (la.kind == 22 || la.kind == 23) {
+ if (la.kind == 22) {
+ Get();
+ builder.Append(t.val);
+ } else {
+ Get();
+ builder.Append(t.val);
+ }
+ }
+ if (IsFunctionCall()) {
+ Function(ref builder);
+ } else if (IsArrayCall()) {
+ ArrayCall(ref builder);
+ } else if (la.kind == 1) {
+ Get();
+ builder.Append(t.val);
+ } else if (la.kind == 5) {
+ Get();
+ builder.Append(t.val);
+ } else if (la.kind == 4) {
+ Get();
+ builder.Append(t.val);
+ } else if (la.kind == 3) {
+ Get();
+ builder.Append(t.val);
+ } else if (la.kind == 8) {
+ Get();
+ builder.Append(t.val);
+ Expression(ref builder);
+ Expect(9);
+ builder.Append(t.val);
+ } else SynErr(39);
+ }
+
+ void Function(ref StringBuilder builder) {
+ Expect(1);
+ builder.Append(t.val);
+ Expect(8);
+ builder.Append(t.val);
+ CommaList(ref builder);
+ Expect(9);
+ builder.Append(t.val);
+ }
+
+ void ArrayCall(ref StringBuilder builder) {
+ Expect(1);
+ builder.Append(t.val);
+ Expect(28);
+ builder.Append(t.val);
+ Expression(ref builder);
+ Expect(29);
+ builder.Append(t.val);
+ }
+
+ void ArrayL(ref StringBuilder builder) {
+ Expect(28);
+ builder.Append(t.val);
+ CommaList(ref builder);
+ Expect(29);
+ builder.Append(t.val);
+ }
+
+ void AnyExpression(out string value) {
+ value = string.Empty; StringBuilder builder = new StringBuilder();
+ Get();
+ builder.Append(t.val);
+ while (StartOf(4)) {
+ Get();
+ builder.Append(t.val);
+ }
+ Expect(33);
+ value = builder.ToString();
+ }
+
+
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+ SCRIPT();
+ Expect(0);
+
+ Expect(0);
+ }
+
+ static readonly bool[,] set = {
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, T,T,x,x, T,x,x,T, x,x,x,T, T,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, T,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,T, T,T,x,x, T,x,x,T, x,x,x,T, T,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,x}
+
+ };
+} // end Parser
+
+
+public class Errors {
+ public int count = 0; // number of errors detected
+ public System.IO.TextWriter errorStream = Console.Out; // error messages go to this stream
+ public string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+
+ public void SynErr (int line, int col, int n) {
+ string s;
+ switch (n) {
+ case 0: s = "EOF expected"; break;
+ case 1: s = "identifier expected"; break;
+ case 2: s = "sign expected"; break;
+ case 3: s = "binary expected"; break;
+ case 4: s = "hex expected"; break;
+ case 5: s = "number expected"; break;
+ case 6: s = "newline expected"; break;
+ case 7: s = "string expected"; break;
+ case 8: s = "LPAREN expected"; break;
+ case 9: s = "RPAREN expected"; break;
+ case 10: s = "COMPARER expected"; break;
+ case 11: s = "\"if\" expected"; break;
+ case 12: s = "\"{\" expected"; break;
+ case 13: s = "\"}\" expected"; break;
+ case 14: s = "\"else\" expected"; break;
+ case 15: s = "\"while\" expected"; break;
+ case 16: s = "\"for\" expected"; break;
+ case 17: s = "\",\" expected"; break;
+ case 18: s = "\"function\" expected"; break;
+ case 19: s = "\"echo:\" expected"; break;
+ case 20: s = "\"say:\" expected"; break;
+ case 21: s = "\"display:\" expected"; break;
+ case 22: s = "\"+\" expected"; break;
+ case 23: s = "\"-\" expected"; break;
+ case 24: s = "\"%\" expected"; break;
+ case 25: s = "\"*\" expected"; break;
+ case 26: s = "\"/\" expected"; break;
+ case 27: s = "\"^\" expected"; break;
+ case 28: s = "\"[\" expected"; break;
+ case 29: s = "\"]\" expected"; break;
+ case 30: s = "\"::\" expected"; break;
+ case 31: s = "\":=\" expected"; break;
+ case 32: s = "\"->\" expected"; break;
+ case 33: s = "\"\\n\" expected"; break;
+ case 34: s = "??? expected"; break;
+ case 35: s = "invalid Statement"; break;
+ case 36: s = "invalid DisplayStatement"; break;
+ case 37: s = "invalid DisplayStatement"; break;
+ case 38: s = "invalid Assignment"; break;
+ case 39: s = "invalid Value"; break;
+
+ default: s = "error " + n; break;
+ }
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ count++;
+ }
+
+ public void SemErr (int line, int col, string s) {
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ count++;
+ }
+
+ public void SemErr (string s) {
+ errorStream.WriteLine(s);
+ count++;
+ }
+
+ public void Warning (int line, int col, string s) {
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ }
+
+ public void Warning(string s) {
+ errorStream.WriteLine(s);
+ }
+} // Errors
+
+
+public class FatalError: Exception {
+ public FatalError(string m): base(m) {}
+}
+
+}
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/ScriptParser/Parser.frame b/CS-MIC/csmic/csmic/ScriptParser/Parser.frame
new file mode 100644
index 0000000..ac4cdf0
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ScriptParser/Parser.frame
@@ -0,0 +1,160 @@
+/*----------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+----------------------------------------------------------------------*/
+-->begin
+using System;
+using System.CodeDom.Compiler;
+
+-->namespace
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Parser {
+-->constants
+ const bool T = true;
+ const bool x = false;
+ const int minErrDist = 2;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+-->declarations
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (string msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+-->pragmas
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ bool StartOf (int s) {
+ return set[s, la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+
+ bool WeakSeparator(int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) {Get(); return true;}
+ else if (StartOf(repFol)) {return false;}
+ else {
+ SynErr(n);
+ while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+
+-->productions
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+-->parseRoot
+ Expect(0);
+ }
+
+ static readonly bool[,] set = {
+-->initialization
+ };
+} // end Parser
+
+
+public class Errors {
+ public int count = 0; // number of errors detected
+ public System.IO.TextWriter errorStream = Console.Out; // error messages go to this stream
+ public string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+
+ public void SynErr (int line, int col, int n) {
+ string s;
+ switch (n) {
+-->errors
+ default: s = "error " + n; break;
+ }
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ count++;
+ }
+
+ public void SemErr (int line, int col, string s) {
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ count++;
+ }
+
+ public void SemErr (string s) {
+ errorStream.WriteLine(s);
+ count++;
+ }
+
+ public void Warning (int line, int col, string s) {
+ errorStream.WriteLine(errMsgFormat, line, col, s);
+ }
+
+ public void Warning(string s) {
+ errorStream.WriteLine(s);
+ }
+} // Errors
+
+
+public class FatalError: Exception {
+ public FatalError(string m): base(m) {}
+}
+
diff --git a/CS-MIC/csmic/csmic/ScriptParser/Scanner.cs b/CS-MIC/csmic/csmic/ScriptParser/Scanner.cs
new file mode 100644
index 0000000..846daae
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ScriptParser/Scanner.cs
@@ -0,0 +1,637 @@
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.CodeDom.Compiler;
+
+namespace csmic.Scripting {
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Token {
+ public int kind; // token kind
+ public int pos; // token position in bytes in the source text (starting at 0)
+ public int charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public string val; // token value
+ public Token next; // ML 2005-03-11 Tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+public class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public const int EOF = char.MaxValue + 1;
+ const int MIN_BUFFER_LENGTH = 1024; // 1KB
+ const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ byte[] buf; // input buffer
+ int bufStart; // position of first byte in buffer relative to input stream
+ int bufLen; // length of buffer
+ int fileLen; // length of input stream (may change if the stream is no file)
+ int bufPos; // current position in buffer
+ Stream stream; // input stream (seekable)
+ bool isUserStream; // was the stream opened by the user?
+
+ public Buffer (Stream s, bool isUserStream) {
+ stream = s; this.isUserStream = isUserStream;
+
+ if (stream.CanSeek) {
+ fileLen = (int) stream.Length;
+ bufLen = Math.Min(fileLen, MAX_BUFFER_LENGTH);
+ bufStart = Int32.MaxValue; // nothing in the buffer so far
+ } else {
+ fileLen = bufLen = bufStart = 0;
+ }
+
+ buf = new byte[(bufLen>0) ? bufLen : MIN_BUFFER_LENGTH];
+ if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
+ if (bufLen == fileLen && stream.CanSeek) Close();
+ }
+
+ protected Buffer(Buffer b) { // called in UTF8Buffer constructor
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ stream = b.stream;
+ // keep destructor from closing the stream
+ b.stream = null;
+ isUserStream = b.isUserStream;
+ }
+
+ ~Buffer() { Close(); }
+
+ protected void Close() {
+ if (!isUserStream && stream != null) {
+ stream.Close();
+ stream = null;
+ }
+ }
+
+ public virtual int Read () {
+ if (bufPos < bufLen) {
+ return buf[bufPos++];
+ } else if (Pos < fileLen) {
+ Pos = Pos; // shift buffer start to Pos
+ return buf[bufPos++];
+ } else if (stream != null && !stream.CanSeek && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++];
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek () {
+ int curPos = Pos;
+ int ch = Read();
+ Pos = curPos;
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public string GetString (int beg, int end) {
+ int len = 0;
+ char[] buf = new char[end - beg];
+ int oldPos = Pos;
+ Pos = beg;
+ while (Pos < end) buf[len++] = (char) Read();
+ Pos = oldPos;
+ return new String(buf, 0, len);
+ }
+
+ public int Pos {
+ get { return bufPos + bufStart; }
+ set {
+ if (value >= fileLen && stream != null && !stream.CanSeek) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = value - bufStart;
+ } else if (stream != null) { // must be swapped in
+ stream.Seek(value, SeekOrigin.Begin);
+ bufLen = stream.Read(buf, 0, buf.Length);
+ bufStart = value; bufPos = 0;
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ bufPos = fileLen - bufStart;
+ }
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.Length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ Array.Copy(buf, newBuf, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+ int read = stream.Read(buf, bufLen, free);
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+public class UTF8Buffer: Buffer {
+ public UTF8Buffer(Buffer b): base(b) {}
+
+ public override int Read() {
+ int ch;
+ do {
+ ch = base.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F; ch = base.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = base.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ const char EOL = '\n';
+ const int eofSym = 0; /* pdt */
+ const int maxT = 34;
+ const int noSym = 34;
+
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ int pos; // byte position of current character
+ int charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static readonly Dictionary start; // maps first token character to start state
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[128]; // text of current token
+ int tlen; // length of current token
+
+ static Scanner() {
+ start = new Dictionary(128);
+ for (int i = 65; i <= 90; ++i) start[i] = 1;
+ for (int i = 97; i <= 99; ++i) start[i] = 1;
+ for (int i = 102; i <= 114; ++i) start[i] = 1;
+ for (int i = 116; i <= 122; ++i) start[i] = 1;
+ start[43] = 2;
+ for (int i = 50; i <= 57; ++i) start[i] = 6;
+ for (int i = 10; i <= 10; ++i) start[i] = 12;
+ for (int i = 13; i <= 13; ++i) start[i] = 11;
+ start[48] = 19;
+ start[49] = 20;
+ start[34] = 13;
+ start[40] = 15;
+ start[41] = 16;
+ start[61] = 17;
+ start[60] = 21;
+ start[62] = 22;
+ start[123] = 23;
+ start[125] = 24;
+ start[44] = 25;
+ start[101] = 38;
+ start[115] = 39;
+ start[100] = 40;
+ start[37] = 29;
+ start[42] = 30;
+ start[47] = 31;
+ start[94] = 32;
+ start[91] = 33;
+ start[93] = 34;
+ start[58] = 41;
+ start[45] = 42;
+ start[Buffer.EOF] = -1;
+
+ }
+
+ public Scanner (string fileName) {
+ try {
+ Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new Buffer(stream, false);
+ Init();
+ } catch (IOException) {
+ throw new FatalError("Cannot open file " + fileName);
+ }
+ }
+
+ public Scanner (Stream s) {
+ buffer = new Buffer(s, true);
+ Init();
+ }
+
+ void Init() {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError(String.Format("illegal byte order mark: EF {0,2:X} {1,2:X}", ch1, ch2));
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.Pos;
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+
+ }
+
+ void AddCh() {
+ if (tlen >= tval.Length) {
+ char[] newBuf = new char[2 * tval.Length];
+ Array.Copy(tval, 0, newBuf, 0, tval.Length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+ tval[tlen++] = (char) ch;
+ NextCh();
+ }
+ }
+
+
+
+ bool Comment0() {
+ int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
+ NextCh();
+ if (ch == '/') {
+ NextCh();
+ for(;;) {
+ if (ch == 10) {
+ level--;
+ if (level == 0) { oldEols = line - line0; NextCh(); return true; }
+ NextCh();
+ } else if (ch == Buffer.EOF) return false;
+ else NextCh();
+ }
+ } else {
+ buffer.Pos = pos0; NextCh(); line = line0; col = col0; charPos = charPos0;
+ }
+ return false;
+ }
+
+ bool Comment1() {
+ int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
+ NextCh();
+ if (ch == '*') {
+ NextCh();
+ for(;;) {
+ if (ch == '*') {
+ NextCh();
+ if (ch == '/') {
+ level--;
+ if (level == 0) { oldEols = line - line0; NextCh(); return true; }
+ NextCh();
+ }
+ } else if (ch == '/') {
+ NextCh();
+ if (ch == '*') {
+ level++; NextCh();
+ }
+ } else if (ch == Buffer.EOF) return false;
+ else NextCh();
+ }
+ } else {
+ buffer.Pos = pos0; NextCh(); line = line0; col = col0; charPos = charPos0;
+ }
+ return false;
+ }
+
+
+ void CheckLiteral() {
+ switch (t.val) {
+ case "if": t.kind = 11; break;
+ case "else": t.kind = 14; break;
+ case "while": t.kind = 15; break;
+ case "for": t.kind = 16; break;
+ case "function": t.kind = 18; break;
+ case "+": t.kind = 22; break;
+ case "-": t.kind = 23; break;
+ case "\n": t.kind = 33; break;
+ default: break;
+ }
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+ ch >= 9 && ch <= 10 || ch == 13
+ ) NextCh();
+ if (ch == '/' && Comment0() ||ch == '/' && Comment1()) return NextToken();
+ int recKind = noSym;
+ int recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state;
+ state = (int) start[ch];
+ tlen = 0; AddCh();
+
+ switch (state) {
+ case -1: { t.kind = eofSym; break; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = recEnd - t.pos;
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break;
+ } // NextCh already done
+ case 1:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 2:
+ {t.kind = 2; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 3:
+ {t.kind = 3; break;}
+ case 4:
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {AddCh(); goto case 5;}
+ else {goto case 0;}
+ case 5:
+ recEnd = pos; recKind = 4;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {AddCh(); goto case 5;}
+ else {t.kind = 4; break;}
+ case 6:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 7:
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else if (ch == '+' || ch == '-') {AddCh(); goto case 8;}
+ else {goto case 0;}
+ case 8:
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else {goto case 0;}
+ case 9:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 9;}
+ else {t.kind = 5; break;}
+ case 10:
+ recEnd = pos; recKind = 5;
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 10;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else {t.kind = 5; break;}
+ case 11:
+ if (ch == 10) {AddCh(); goto case 12;}
+ else {goto case 0;}
+ case 12:
+ {t.kind = 6; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 13:
+ if (ch <= '!' || ch >= '#' && ch <= 65535) {AddCh(); goto case 13;}
+ else if (ch == '"') {AddCh(); goto case 14;}
+ else {goto case 0;}
+ case 14:
+ {t.kind = 7; break;}
+ case 15:
+ {t.kind = 8; break;}
+ case 16:
+ {t.kind = 9; break;}
+ case 17:
+ if (ch == '=') {AddCh(); goto case 18;}
+ else {goto case 0;}
+ case 18:
+ {t.kind = 10; break;}
+ case 19:
+ recEnd = pos; recKind = 5;
+ if (ch >= '2' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'B' || ch == 'b') {AddCh(); goto case 3;}
+ else if (ch >= '0' && ch <= '1') {AddCh(); goto case 20;}
+ else if (ch == 'x') {AddCh(); goto case 4;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 20:
+ recEnd = pos; recKind = 5;
+ if (ch >= '2' && ch <= '9') {AddCh(); goto case 6;}
+ else if (ch == 'B' || ch == 'b') {AddCh(); goto case 3;}
+ else if (ch >= '0' && ch <= '1') {AddCh(); goto case 20;}
+ else if (ch == 'E' || ch == 'e') {AddCh(); goto case 7;}
+ else if (ch == '.') {AddCh(); goto case 10;}
+ else {t.kind = 5; break;}
+ case 21:
+ recEnd = pos; recKind = 10;
+ if (ch == '=') {AddCh(); goto case 18;}
+ else {t.kind = 10; break;}
+ case 22:
+ recEnd = pos; recKind = 10;
+ if (ch == '=') {AddCh(); goto case 18;}
+ else {t.kind = 10; break;}
+ case 23:
+ {t.kind = 12; break;}
+ case 24:
+ {t.kind = 13; break;}
+ case 25:
+ {t.kind = 17; break;}
+ case 26:
+ {t.kind = 19; break;}
+ case 27:
+ {t.kind = 20; break;}
+ case 28:
+ {t.kind = 21; break;}
+ case 29:
+ {t.kind = 24; break;}
+ case 30:
+ {t.kind = 25; break;}
+ case 31:
+ {t.kind = 26; break;}
+ case 32:
+ {t.kind = 27; break;}
+ case 33:
+ {t.kind = 28; break;}
+ case 34:
+ {t.kind = 29; break;}
+ case 35:
+ {t.kind = 30; break;}
+ case 36:
+ {t.kind = 31; break;}
+ case 37:
+ {t.kind = 32; break;}
+ case 38:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'b' || ch >= 'd' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'c') {AddCh(); goto case 43;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 39:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'b' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'a') {AddCh(); goto case 44;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 40:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'h' || ch >= 'j' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'i') {AddCh(); goto case 45;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 41:
+ if (ch == ':') {AddCh(); goto case 35;}
+ else if (ch == '=') {AddCh(); goto case 36;}
+ else {goto case 0;}
+ case 42:
+ recEnd = pos; recKind = 2;
+ if (ch == '>') {AddCh(); goto case 37;}
+ else {t.kind = 2; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 43:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'g' || ch >= 'i' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'h') {AddCh(); goto case 46;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 44:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'x' || ch == 'z') {AddCh(); goto case 1;}
+ else if (ch == 'y') {AddCh(); goto case 47;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 45:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'r' || ch >= 't' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 's') {AddCh(); goto case 48;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 46:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'n' || ch >= 'p' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'o') {AddCh(); goto case 49;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 47:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == ':') {AddCh(); goto case 27;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 48:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'o' || ch >= 'q' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'p') {AddCh(); goto case 50;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 49:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == ':') {AddCh(); goto case 26;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 50:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'k' || ch >= 'm' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'l') {AddCh(); goto case 51;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 51:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'b' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == 'a') {AddCh(); goto case 52;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 52:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'x' || ch == 'z') {AddCh(); goto case 1;}
+ else if (ch == 'y') {AddCh(); goto case 53;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 53:
+ recEnd = pos; recKind = 1;
+ if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 1;}
+ else if (ch == ':') {AddCh(); goto case 28;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.Pos = t.pos;
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // peek for the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at the current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
+}
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/ScriptParser/Scanner.frame b/CS-MIC/csmic/csmic/ScriptParser/Scanner.frame
new file mode 100644
index 0000000..8010e59
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ScriptParser/Scanner.frame
@@ -0,0 +1,383 @@
+/*----------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+-----------------------------------------------------------------------*/
+-->begin
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.CodeDom.Compiler;
+
+-->namespace
+
+[GeneratedCodeAttribute("Coco/R", "")]
+public class Token {
+ public int kind; // token kind
+ public int pos; // token position in bytes in the source text (starting at 0)
+ public int charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public string val; // token value
+ public Token next; // ML 2005-03-11 Tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+public class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public const int EOF = char.MaxValue + 1;
+ const int MIN_BUFFER_LENGTH = 1024; // 1KB
+ const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ byte[] buf; // input buffer
+ int bufStart; // position of first byte in buffer relative to input stream
+ int bufLen; // length of buffer
+ int fileLen; // length of input stream (may change if the stream is no file)
+ int bufPos; // current position in buffer
+ Stream stream; // input stream (seekable)
+ bool isUserStream; // was the stream opened by the user?
+
+ public Buffer (Stream s, bool isUserStream) {
+ stream = s; this.isUserStream = isUserStream;
+
+ if (stream.CanSeek) {
+ fileLen = (int) stream.Length;
+ bufLen = Math.Min(fileLen, MAX_BUFFER_LENGTH);
+ bufStart = Int32.MaxValue; // nothing in the buffer so far
+ } else {
+ fileLen = bufLen = bufStart = 0;
+ }
+
+ buf = new byte[(bufLen>0) ? bufLen : MIN_BUFFER_LENGTH];
+ if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
+ if (bufLen == fileLen && stream.CanSeek) Close();
+ }
+
+ protected Buffer(Buffer b) { // called in UTF8Buffer constructor
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ stream = b.stream;
+ // keep destructor from closing the stream
+ b.stream = null;
+ isUserStream = b.isUserStream;
+ }
+
+ ~Buffer() { Close(); }
+
+ protected void Close() {
+ if (!isUserStream && stream != null) {
+ stream.Close();
+ stream = null;
+ }
+ }
+
+ public virtual int Read () {
+ if (bufPos < bufLen) {
+ return buf[bufPos++];
+ } else if (Pos < fileLen) {
+ Pos = Pos; // shift buffer start to Pos
+ return buf[bufPos++];
+ } else if (stream != null && !stream.CanSeek && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++];
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek () {
+ int curPos = Pos;
+ int ch = Read();
+ Pos = curPos;
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public string GetString (int beg, int end) {
+ int len = 0;
+ char[] buf = new char[end - beg];
+ int oldPos = Pos;
+ Pos = beg;
+ while (Pos < end) buf[len++] = (char) Read();
+ Pos = oldPos;
+ return new String(buf, 0, len);
+ }
+
+ public int Pos {
+ get { return bufPos + bufStart; }
+ set {
+ if (value >= fileLen && stream != null && !stream.CanSeek) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = value - bufStart;
+ } else if (stream != null) { // must be swapped in
+ stream.Seek(value, SeekOrigin.Begin);
+ bufLen = stream.Read(buf, 0, buf.Length);
+ bufStart = value; bufPos = 0;
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ bufPos = fileLen - bufStart;
+ }
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.Length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ Array.Copy(buf, newBuf, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+ int read = stream.Read(buf, bufLen, free);
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+public class UTF8Buffer: Buffer {
+ public UTF8Buffer(Buffer b): base(b) {}
+
+ public override int Read() {
+ int ch;
+ do {
+ ch = base.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F; ch = base.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = base.Read();
+ int c2 = ch & 0x3F; ch = base.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = base.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ const char EOL = '\n';
+ const int eofSym = 0; /* pdt */
+-->declarations
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ int pos; // byte position of current character
+ int charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static readonly Dictionary start; // maps first token character to start state
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[128]; // text of current token
+ int tlen; // length of current token
+
+ static Scanner() {
+ start = new Dictionary(128);
+-->initialization
+ }
+
+ public Scanner (string fileName) {
+ try {
+ Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new Buffer(stream, false);
+ Init();
+ } catch (IOException) {
+ throw new FatalError("Cannot open file " + fileName);
+ }
+ }
+
+ public Scanner (Stream s) {
+ buffer = new Buffer(s, true);
+ Init();
+ }
+
+ void Init() {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError(String.Format("illegal byte order mark: EF {0,2:X} {1,2:X}", ch1, ch2));
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.Pos;
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+-->casing1
+ }
+
+ void AddCh() {
+ if (tlen >= tval.Length) {
+ char[] newBuf = new char[2 * tval.Length];
+ Array.Copy(tval, 0, newBuf, 0, tval.Length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+-->casing2
+ NextCh();
+ }
+ }
+
+
+-->comments
+
+ void CheckLiteral() {
+-->literals
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+-->scan1
+ ) NextCh();
+-->scan2
+ int recKind = noSym;
+ int recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state;
+ state = (int) start[ch];
+ tlen = 0; AddCh();
+
+ switch (state) {
+ case -1: { t.kind = eofSym; break; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = recEnd - t.pos;
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break;
+ } // NextCh already done
+-->scan3
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.Pos = t.pos;
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // peek for the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at the current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
diff --git a/CS-MIC/csmic/csmic/ScriptParser/Scripting.atg b/CS-MIC/csmic/csmic/ScriptParser/Scripting.atg
new file mode 100644
index 0000000..0a5f90d
--- /dev/null
+++ b/CS-MIC/csmic/csmic/ScriptParser/Scripting.atg
@@ -0,0 +1,525 @@
+using csmic;
+using System.Text;
+using System.Collections.Generic;
+
+COMPILER SCRIPT
+
+/*
+*
+* Class Structures
+*
+*/
+
+private MacroOperation root = new MacroOperation(OperationType.Unknown);
+
+internal MacroOperation Root
+{
+ get
+ {
+ return this.root;
+ }
+ set
+ {
+ this.root = value;
+ }
+}
+
+bool IsFunctionCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _LPAREN && la.kind == _identifier)
+ return true;
+ return false;
+}
+
+bool IsCompare()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.kind == _COMPARER)
+ return true;
+ return false;
+}
+
+bool IsAssignment()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if (next.val == "::" || next.val == ":=" || next.val == "->")
+ return true;
+ return false;
+}
+
+bool IsArrayCall()
+{
+ scanner.ResetPeek();
+ Token next = scanner.Peek();
+ if(next.val == "[")
+ return true;
+ return false;
+}
+
+CHARACTERS
+
+ UpperLetter = 'A'..'Z'.
+ LowerLetter = 'a'..'z'.
+ letter = UpperLetter + LowerLetter.
+ NoQuote = ANY - '\"' .
+ digit = "0123456789" .
+ cr = '\r' .
+ lf = '\n' .
+ tab = '\t' .
+ PM = "+-" .
+
+TOKENS
+
+ identifier = letter { letter | digit }.
+ sign = PM .
+ binary = ( '0' | '1' ) { '0' | '1' } ('B' | 'b') .
+ hex = "0x" ( digit | ('A' | 'B' | 'C' | 'D' | 'E' |'F') | ('a' | 'b' | 'c' | 'd' | 'e' |'f') ) { digit | ('A' | 'B' | 'C' | 'D' | 'E' |'F') | ('a' | 'b' | 'c' | 'd' | 'e' |'f') } .
+ number = digit { digit }['.' {digit}] [('E'|'e')['+'|'-'] digit {digit}] .
+ newline = [cr] lf .
+ string = "\"" { NoQuote } "\"" .
+ LPAREN = '(' .
+ RPAREN = ')' .
+ COMPARER = "==" | "<" | ">" | "<=" | ">=" .
+
+ COMMENTS FROM "/*" TO "*/" NESTED
+ COMMENTS FROM "//" TO lf
+
+IGNORE cr + lf + tab
+
+/*
+ * Parser specification
+ *
+ */
+
+PRODUCTIONS
+
+SCRIPT (. string statement = string.Empty; .)
+=
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ this.root.Children.Add(operation);
+ .)
+ |
+ IfBlock[
+ |
+ WhileBlock][
+ |
+ FunctionDeclaration][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+.
+
+IfBlock][ (.
+ MacroOperation ifBlock = new MacroOperation(OperationType.If);
+ MacroOperation elseBlock = new MacroOperation(OperationType.Else);
+ string ifStatement = string.Empty;
+ string statement = string.Empty;
+ StringBuilder builder = new StringBuilder();
+ bool hasElse = false;
+ .)
+=
+ "if"
+ LPAREN
+ Comparison][ (. ifStatement = builder.ToString(); ifBlock.Input.Add(ifStatement); .)
+ RPAREN
+ '{'
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ ifBlock.Children.Add(operation);
+ .)
+ |
+ IfBlock][
+ |
+ WhileBlock][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+ '}'
+ [
+ "else" (. hasElse = true; .)
+ '{'
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ elseBlock.Children.Add(operation);
+ .)
+ |
+ IfBlock][
+ |
+ WhileBlock][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+ '}'
+ ]
+ (.
+ if(hasElse)
+ {
+ MacroOperation ifelse = new MacroOperation(OperationType.IfElse);
+ ifelse.Children.Add(ifBlock);
+ ifelse.Children.Add(elseBlock);
+ parent.Children.Add(ifelse);
+ }
+ else
+ {
+ parent.Children.Add(ifBlock);
+ }
+ .)
+.
+
+
+
+WhileBlock][ (.
+ StringBuilder builder = new StringBuilder();
+ MacroOperation whileBlock = new MacroOperation(OperationType.While);
+ string statement = string.Empty;
+ .)
+=
+ "while"
+ LPAREN
+ Comparison][ (. whileBlock.Input.Add(builder.ToString()); .)
+ RPAREN
+ '{'
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ whileBlock.Children.Add(operation);
+ .)
+ |
+ IfBlock][
+ |
+ WhileBlock][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+ '}'
+ (.
+ parent.Children.Add(whileBlock);
+ .)
+.
+
+ForBlock][ (.
+ StringBuilder builder = new StringBuilder();
+ string statement = string.Empty;
+ string statement2 = string.Empty;
+ MacroOperation forBlock = new MacroOperation(OperationType.For);
+ .)
+=
+ "for"
+ LPAREN
+ Statement
+ ','
+ Comparison][
+ ','
+ Statement (. forBlock.Input.Add(statement); forBlock.Input.Add(builder.ToString()); forBlock.Input.Add(statement2); .)
+ RPAREN
+ '{'
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ forBlock.Children.Add(operation);
+ .)
+ |
+ IfBlock][
+ |
+ WhileBlock][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+ '}'
+ (.
+ parent.Children.Add(forBlock);
+ .)
+.
+
+FunctionDeclaration][ (.
+ StringBuilder builder = new StringBuilder();
+ string statement = string.Empty;
+ MacroOperation func = new MacroOperation(OperationType.FunctionDeclaration);
+ .)
+=
+ "function"
+ LPAREN
+ CommaList][ (. string[] args = builder.ToString().Split(','); func.Input.AddRange(args); .)
+ RPAREN
+ '{'
+ {
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ func.Children.Add(operation);
+ .)
+ |
+ IfBlock][
+ |
+ WhileBlock][
+ |
+ EchoStatement][
+ |
+ SayStatement][
+ |
+ DisplayStatement][
+ |
+ ForBlock][
+ }
+ '}'
+ (.
+ parent.Children.Add(func);
+ .)
+.
+
+EchoStatement][ (.
+ StringBuilder builder = new StringBuilder();
+ MacroOperation echoStatement = new MacroOperation(OperationType.Echo);
+ string statement = string.Empty;
+ .)
+=
+ "echo:"
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ echoStatement.Children.Add(operation);
+ parent.Children.Add(echoStatement);
+ .)
+.
+
+SayStatement][ (.
+ StringBuilder builder = new StringBuilder();
+ MacroOperation sayStatement = new MacroOperation(OperationType.Say);
+ string statement = string.Empty;
+ .)
+=
+ "say:"
+ string (.
+ statement = t.val.Replace("\"", "");
+ sayStatement.Input.Add(statement);
+ parent.Children.Add(sayStatement);
+ .)
+.
+
+DisplayStatement][ (.
+ StringBuilder builder = new StringBuilder();
+ MacroOperation displayStatement = new MacroOperation(OperationType.Display);
+ string statement = string.Empty;
+ .)
+=
+ "display:"
+ (
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+ .)
+ |
+ string (.
+ statement = t.val.Replace("\"", "");
+ MacroOperation operation = new MacroOperation(OperationType.String);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+ .)
+ )
+ {
+ ','
+ (
+ Statement (.
+ MacroOperation operation = new MacroOperation(OperationType.Statement);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+ .)
+ |
+ string (.
+ statement = t.val.Replace("\"", "");
+ MacroOperation operation = new MacroOperation(OperationType.String);
+ operation.Input.Add(statement);
+ displayStatement.Children.Add(operation);
+ .)
+ )
+ }
+ (.
+ parent.Children.Add(displayStatement);
+ .)
+.
+
+Statement (.
+ value = string.Empty;
+ StringBuilder builder = new StringBuilder();
+ .)
+=
+ IF(IsAssignment())
+ Assignment][ (. value = builder.ToString(); .)
+ |
+ Expression][ (. value = builder.ToString(); .)
+.
+
+Expression][
+=
+Term][
+{
+ '+' (. builder.Append(t.val); .) Term][
+|
+ '-' (. builder.Append(t.val); .) Term][
+|
+ '%' (. builder.Append(t.val); .) Term][
+}
+.
+
+Term][
+=
+ Factor][
+ {
+ '*' (. builder.Append(t.val); .)
+ Factor][
+|
+ '/' (. builder.Append(t.val); .)
+ Factor][
+}
+.
+
+Factor][
+=
+ Value][
+ {
+ '^' (. builder.Append(t.val); .)
+ Value][
+ }
+.
+
+Value][
+=
+
+ [
+ "+" (. builder.Append(t.val); .)
+ |
+ "-" (. builder.Append(t.val); .)
+ ]
+(
+ IF(IsFunctionCall())
+ Function][
+|
+ IF(IsArrayCall())
+ ArrayCall][
+|
+ identifier (. builder.Append(t.val); .)
+|
+ number (. builder.Append(t.val); .)
+|
+ hex (. builder.Append(t.val); .)
+|
+ binary (. builder.Append(t.val); .)
+|
+ '(' (. builder.Append(t.val); .)
+ Expression][
+ ')' (. builder.Append(t.val); .)
+)
+.
+
+ArrayL][
+=
+'[' (. builder.Append(t.val); .)
+CommaList][
+']' (. builder.Append(t.val); .)
+.
+
+CommaList][
+=
+Expression][
+{
+ ',' (. builder.Append(t.val); .)
+ Expression][
+}
+.
+
+Assignment][
+=
+identifier (. builder.Append(t.val); .)
+(
+ (
+ "::" (. builder.Append(t.val); .)
+ Expression][
+ )
+ |
+ (
+ ":=" (. builder.Append(t.val); string value = string.Empty; .)
+ AnyExpression (. builder.Append(value); .)
+ newline
+ )
+ |
+ (
+ "->" (. builder.Append(t.val); .)
+ ArrayL][
+ )
+)
+.
+
+Function][
+=
+identifier (. builder.Append(t.val); .)
+'(' (. builder.Append(t.val); .)
+CommaList][
+')' (. builder.Append(t.val); .)
+.
+
+ArrayCall][
+=
+identifier (. builder.Append(t.val); .)
+'[' (. builder.Append(t.val); .)
+ Expression][
+']' (. builder.Append(t.val); .)
+.
+
+Comparison][
+=
+Expression][
+COMPARER (. result.Append(t.val); .)
+Expression][
+.
+
+AnyExpression (. value = string.Empty; StringBuilder builder = new StringBuilder(); .)
+=
+ANY (. builder.Append(t.val); .) { ANY (. builder.Append(t.val); .) } '\n' (. value = builder.ToString(); .)
+.
+
+
+END SCRIPT.
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/Variable.cs b/CS-MIC/csmic/csmic/Variable.cs
new file mode 100644
index 0000000..4fb9a3e
--- /dev/null
+++ b/CS-MIC/csmic/csmic/Variable.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace csmic
+{
+ ///
+ /// Represents the data types supported in a variable.
+ ///
+ public enum VariableType
+ {
+ ///
+ /// Decimal
+ ///
+ Decimal,
+ ///
+ /// Equation
+ ///
+ Equation,
+ ///
+ /// Array
+ ///
+ Array,
+ ///
+ /// Unknown
+ ///
+ Unknown,
+ ///
+ /// No type associated
+ ///
+ None
+ }
+
+ ///
+ /// An object that contains information about a variable.
+ ///
+ public class Variable
+ {
+ #region Members
+
+ ///
+ /// The type of variable.
+ ///
+ private VariableType type;
+ ///
+ /// The value of the variable.
+ ///
+ private object value;
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Creates an empty variable.
+ ///
+ public Variable()
+ {
+ this.type = VariableType.None;
+ this.value = null;
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets an object representing the variable's value.
+ ///
+ public object Value
+ {
+ get
+ {
+ return this.value;
+ }
+ set
+ {
+ this.value = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the type of the variable.
+ ///
+ public VariableType Type
+ {
+ get
+ {
+ return this.type;
+ }
+ set
+ {
+ this.type = value;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/CS-MIC/csmic/csmic/csmic.csproj b/CS-MIC/csmic/csmic/csmic.csproj
new file mode 100644
index 0000000..3e1cbe5
--- /dev/null
+++ b/CS-MIC/csmic/csmic/csmic.csproj
@@ -0,0 +1,136 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.21022
+ 2.0
+ {7BBA4BA2-E885-4D89-8710-F1A609616B7D}
+ Library
+ Properties
+ csmic
+ csmic
+ v4.0
+ 512
+ true
+ csmic_open.snk
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ bin\Debug\csmic.XML
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+
+
+ prompt
+ 4
+ bin\Release\csmic.XML
+ AllRules.ruleset
+ false
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+ "$(ProjectDir)\coco.exe" -namespace csmic.Interpreter -frames . "$(ProjectDir)\InterpreterParser\CSMIC.atg"
+"$(ProjectDir)\coco.exe" -namespace csmic.Scripting -frames . "$(ProjectDir)\ScriptParser\Scripting.atg"
+
+
\ No newline at end of file
diff --git a/CS-MIC/csmic/csmic/csmic.csproj.vspscc b/CS-MIC/csmic/csmic/csmic.csproj.vspscc
new file mode 100644
index 0000000..feffdec
--- /dev/null
+++ b/CS-MIC/csmic/csmic/csmic.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/CS-MIC/csmic/csmic/csmic_open.snk b/CS-MIC/csmic/csmic/csmic_open.snk
new file mode 100644
index 0000000..4524054
Binary files /dev/null and b/CS-MIC/csmic/csmic/csmic_open.snk differ
]