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 &lt%3ba href=&quot%3bhttp://cs-mic.com&quot%3b&gt%3bofficial site&lt%3b/a&gt%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