mirror of
https://github.com/wagesj45/cs-mic.git
synced 2024-12-21 17:32:28 -06:00
Migrating from Sourceforge to Codeplex. Initial checkin starting with version 1.1.5.0 source code.
This commit is contained in:
parent
f7165325f7
commit
c41167bfc4
44 changed files with 7608 additions and 0 deletions
136
CS-MIC/csmic/CSMICTests/AuthoringTests.txt
Normal file
136
CS-MIC/csmic/CSMICTests/AuthoringTests.txt
Normal file
|
@ -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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
120
CS-MIC/csmic/CSMICTests/CSMICTests.csproj
Normal file
120
CS-MIC/csmic/CSMICTests/CSMICTests.csproj
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{C03AD9DF-630F-4C88-A9D4-8B4B450CCB54}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CSMICTests</RootNamespace>
|
||||
<AssemblyName>CSMICTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="InputInterpreterTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="AuthoringTests.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\csmic\csmic.csproj">
|
||||
<Project>{7BBA4BA2-E885-4D89-8710-F1A609616B7D}</Project>
|
||||
<Name>csmic</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Shadow Include="Test References\csmic.accessor" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
10
CS-MIC/csmic/CSMICTests/CSMICTests.csproj.vspscc
Normal file
10
CS-MIC/csmic/CSMICTests/CSMICTests.csproj.vspscc
Normal file
|
@ -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"
|
||||
}
|
216
CS-MIC/csmic/CSMICTests/InputInterpreterTest.cs
Normal file
216
CS-MIC/csmic/CSMICTests/InputInterpreterTest.cs
Normal file
|
@ -0,0 +1,216 @@
|
|||
using csmic;
|
||||
using csmic.Extensions;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
namespace CSMICTests
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
///This is a test class for InputInterpreterTest and is intended
|
||||
///to contain all InputInterpreterTest Unit Tests
|
||||
///</summary>
|
||||
[TestClass()]
|
||||
public class InputInterpreterTest
|
||||
{
|
||||
|
||||
|
||||
private TestContext testContextInstance;
|
||||
|
||||
/// <summary>
|
||||
///Gets or sets the test context which provides
|
||||
///information about and functionality for the current test run.
|
||||
///</summary>
|
||||
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
|
||||
|
||||
|
||||
/// <summary>
|
||||
///A test for Interpret
|
||||
///</summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests a value repeated 10,000 times and checks for an execution time less than 200 milliseconds.
|
||||
/// </summary>
|
||||
/// <param name="target">The input interpreter.</param>
|
||||
/// <param name="value">The value to repeat and test.</param>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests a given expression for a decimal result.
|
||||
/// </summary>
|
||||
/// <param name="target">The input interpreter.</param>
|
||||
/// <param name="input">The input to execute.</param>
|
||||
/// <param name="expected">The expected value.</param>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests a given expression for a string result.
|
||||
/// </summary>
|
||||
/// <param name="target">The input interpreter.</param>
|
||||
/// <param name="input">The input to execute.</param>
|
||||
/// <param name="expected">The expected value.</param>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
35
CS-MIC/csmic/CSMICTests/Properties/AssemblyInfo.cs
Normal file
35
CS-MIC/csmic/CSMICTests/Properties/AssemblyInfo.cs
Normal file
|
@ -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")]
|
2
CS-MIC/csmic/CSMICTests/Test References/csmic.accessor
Normal file
2
CS-MIC/csmic/CSMICTests/Test References/csmic.accessor
Normal file
|
@ -0,0 +1,2 @@
|
|||
csmic.dll
|
||||
Desktop
|
87
CS-MIC/csmic/HelpFile/HelpFile.shfbproj
Normal file
87
CS-MIC/csmic/HelpFile/HelpFile.shfbproj
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<!-- The configuration and platform will be used to determine which
|
||||
assemblies to include from solution and project documentation
|
||||
sources -->
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{b60970b9-771a-4ebb-9978-89f55163888f}</ProjectGuid>
|
||||
<SHFBSchemaVersion>1.9.5.0</SHFBSchemaVersion>
|
||||
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
|
||||
Studio adds them anyway -->
|
||||
<AssemblyName>HelpFile</AssemblyName>
|
||||
<RootNamespace>HelpFile</RootNamespace>
|
||||
<Name>HelpFile</Name>
|
||||
<!-- SHFB properties -->
|
||||
<OutputPath>.\Help\</OutputPath>
|
||||
<HtmlHelpName>csmic_help</HtmlHelpName>
|
||||
<Language>en-US</Language>
|
||||
<HelpFileFormat>HtmlHelp1, Website</HelpFileFormat>
|
||||
<IndentHtml>False</IndentHtml>
|
||||
<FrameworkVersion>.NET Framework 4.0</FrameworkVersion>
|
||||
<KeepLogFile>True</KeepLogFile>
|
||||
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
|
||||
<CppCommentsFixup>False</CppCommentsFixup>
|
||||
<CleanIntermediates>True</CleanIntermediates>
|
||||
<SyntaxFilters>Standard</SyntaxFilters>
|
||||
<SdkLinkTarget>Blank</SdkLinkTarget>
|
||||
<RootNamespaceTitle>csmic</RootNamespaceTitle>
|
||||
<RootNamespaceContainer>True</RootNamespaceContainer>
|
||||
<PresentationStyle>VS2010</PresentationStyle>
|
||||
<Preliminary>False</Preliminary>
|
||||
<NamingMethod>Guid</NamingMethod>
|
||||
<HelpTitle>CS-MIC - C Sharp Math Input Control</HelpTitle>
|
||||
<FooterText>Please visit the &lt%3ba href=&quot%3bhttp://cs-mic.com&quot%3b&gt%3bofficial site&lt%3b/a&gt%3b for more information.</FooterText>
|
||||
<FeedbackEMailLinkText>Please feel free to provide feedback!</FeedbackEMailLinkText>
|
||||
<FeedbackEMailAddress>jordan%40jordanwages.com</FeedbackEMailAddress>
|
||||
<CopyrightText>Copyright 2012</CopyrightText>
|
||||
<ContentPlacement>AboveNamespaces</ContentPlacement>
|
||||
<WebsiteSdkLinkType>Msdn</WebsiteSdkLinkType>
|
||||
<HtmlSdkLinkType>Msdn</HtmlSdkLinkType>
|
||||
<IncludeFavorites>True</IncludeFavorites>
|
||||
<BinaryTOC>True</BinaryTOC>
|
||||
<ProjectSummary>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.</ProjectSummary>
|
||||
<VisibleItems>Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Internals, Protected, SealedProtected</VisibleItems>
|
||||
<DocumentationSources>
|
||||
<DocumentationSource sourceFile="..\csmic\bin\Release\csmic.dll" />
|
||||
<DocumentationSource sourceFile="..\csmic\bin\Release\csmic.xml" />
|
||||
</DocumentationSources>
|
||||
<ApiFilter />
|
||||
<ComponentConfigurations />
|
||||
<HelpAttributes />
|
||||
<NamespaceSummaries />
|
||||
<PlugInConfigurations />
|
||||
<BuildLogFile />
|
||||
<HtmlHelp1xCompilerPath />
|
||||
<HtmlHelp2xCompilerPath />
|
||||
<SandcastlePath />
|
||||
<WorkingPath />
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
</PropertyGroup>
|
||||
<!-- There are no properties for these groups. AnyCPU needs to appear in
|
||||
order for Visual Studio to perform the build. The others are optional
|
||||
common platform types that may appear. -->
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
|
||||
</PropertyGroup>
|
||||
<!-- Import the SHFB build targets -->
|
||||
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
|
||||
</Project>
|
10
CS-MIC/csmic/HelpFile/HelpFile.shfbproj.vspscc
Normal file
10
CS-MIC/csmic/HelpFile/HelpFile.shfbproj.vspscc
Normal file
|
@ -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"
|
||||
}
|
54
CS-MIC/csmic/csmic.sln
Normal file
54
CS-MIC/csmic/csmic.sln
Normal file
|
@ -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
|
10
CS-MIC/csmic/csmic.vssscc
Normal file
10
CS-MIC/csmic/csmic.vssscc
Normal file
|
@ -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"
|
||||
}
|
24
CS-MIC/csmic/csmic/CodedFunctionFactory.cs
Normal file
24
CS-MIC/csmic/csmic/CodedFunctionFactory.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary> Coded function factory. </summary>
|
||||
/// <remarks>
|
||||
/// This class generates new coded functions dynamically.
|
||||
/// </remarks>
|
||||
public static class CodedFunctionFactory
|
||||
{
|
||||
/// <summary> Creates a new ICodedFunction interface object that implements the dynamic method described. </summary>
|
||||
/// <param name="functionName"> Name of the function. </param>
|
||||
/// <param name="numExpectedArguments"> Number of expected arguments. </param>
|
||||
/// <param name="methodBody"> The method body. </param>
|
||||
/// <returns> An ICodedFunction interface object. </returns>
|
||||
public static ICodedFunction Create(string functionName, int numExpectedArguments, Func<decimal[], decimal> methodBody)
|
||||
{
|
||||
return new GenericCodedFunction(functionName, numExpectedArguments, methodBody);
|
||||
}
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Abs.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Abs.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the absolute value function.
|
||||
/// </summary>
|
||||
class CF_Abs : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "abs"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The absolute value of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Cos.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Cos.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the cosine function.
|
||||
/// </summary>
|
||||
class CF_Cos : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "cos"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The cosine of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Exp.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Exp.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the exponential function based on the constant e.
|
||||
/// </summary>
|
||||
class CF_Exp : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "exp"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The constant e raised to the power of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
57
CS-MIC/csmic/csmic/CodedFunctions/CF_Log.cs
Normal file
57
CS-MIC/csmic/csmic/CodedFunctions/CF_Log.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the log function.
|
||||
/// </summary>
|
||||
class CF_Log : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 2 arguments.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "log"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The log of the first argument to the base of the second argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
50
CS-MIC/csmic/csmic/CodedFunctions/CF_Precision.cs
Normal file
50
CS-MIC/csmic/csmic/CodedFunctions/CF_Precision.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of a precision function.
|
||||
/// </summary>
|
||||
class CF_Precision : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 2 arguments.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "precision"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The first argument to the precision of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Round.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Round.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of a rounded function.
|
||||
/// </summary>
|
||||
class CF_Round : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "round"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The rounded argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Sin.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Sin.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the sine function.
|
||||
/// </summary>
|
||||
class CF_Sin : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "sin"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The sine of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Sqrt.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Sqrt.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the squre root function.
|
||||
/// </summary>
|
||||
class CF_Sqrt : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "sqrt"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The square root of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Tan.cs
Normal file
49
CS-MIC/csmic/csmic/CodedFunctions/CF_Tan.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.CodedFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// A coded implementation of the tangent function.
|
||||
/// </summary>
|
||||
class CF_Tan : ICodedFunction
|
||||
{
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary>
|
||||
/// Expects 1 argument.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
public string FunctionName
|
||||
{
|
||||
get { return "tan"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used in the code block.</param>
|
||||
/// <returns>The tangent of the argument.</returns>
|
||||
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
|
||||
}
|
||||
}
|
182
CS-MIC/csmic/csmic/Computable/Computable.cs
Normal file
182
CS-MIC/csmic/csmic/Computable/Computable.cs
Normal file
|
@ -0,0 +1,182 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.ComputableEngine
|
||||
{
|
||||
/// <summary> Computable class. </summary>
|
||||
public sealed class Computable
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary> The expression to be built.</summary>
|
||||
private string expression;
|
||||
/// <summary> The interpreter to act as a base.</summary>
|
||||
private InputInterpreter interpreter;
|
||||
|
||||
#region Constants
|
||||
|
||||
/// <summary> The add symbol.</summary>
|
||||
private const string ADD = "+";
|
||||
/// <summary> The substract symbol.</summary>
|
||||
private const string SUBSTRACT = "-";
|
||||
/// <summary> The divide symbol.</summary>
|
||||
private const string DIVIDE = "/";
|
||||
/// <summary> The multiply symbol.</summary>
|
||||
private const string MULTIPLY = "*";
|
||||
/// <summary> The modifier symbol.</summary>
|
||||
private const string MOD = "%";
|
||||
/// <summary> The power symbol.</summary>
|
||||
private const string POWER = "^";
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary> Gets the expression. </summary>
|
||||
/// <value> The expression. </value>
|
||||
internal string Expression
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.expression;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary> Creates a Computable instance. </summary>
|
||||
/// <param name="expression"> The expression. </param>
|
||||
/// <param name="interpreter"> The interpreter. </param>
|
||||
internal Computable(string expression, InputInterpreter interpreter)
|
||||
{
|
||||
this.expression = expression;
|
||||
this.interpreter = interpreter;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary> Resolves the computable as an input interpreter having calculated the input. </summary>
|
||||
/// <returns> The computable as an input interpreter. </returns>
|
||||
public InputInterpreter Resolve()
|
||||
{
|
||||
this.interpreter.Interpret(this.Expression);
|
||||
return this.interpreter;
|
||||
}
|
||||
|
||||
/// <summary> Resolve the computer to a type <typeparamref name="T"/>. </summary>
|
||||
/// <typeparam name="T"> Generic type parameter. </typeparam>
|
||||
/// <param name="selector"> The selector function. </param>
|
||||
/// <returns> . </returns>
|
||||
public T ResolveTo<T>(Func<InputInterpreter, T> selector)
|
||||
{
|
||||
return selector(this.Resolve());
|
||||
}
|
||||
|
||||
/// <summary> Form the operation given the operation constant and an argument. </summary>
|
||||
/// <param name="operation"> The operation constant. </param>
|
||||
/// <param name="argument"> The argument. </param>
|
||||
/// <returns> A string with the given operation appended. </returns>
|
||||
private string FormOperation(string operation, object argument)
|
||||
{
|
||||
return string.Format("({0} {1} {2})", this.Expression, operation, argument);
|
||||
}
|
||||
|
||||
/// <summary> Form the function <paramref name="name"/> with the current expression as the first argument, followed by <paramref name="arguments"/>. </summary>
|
||||
/// <param name="name"> The name of the function. </param>
|
||||
/// <param name="arguments"> The arguments. </param>
|
||||
/// <returns> . </returns>
|
||||
private string FormFunction(string name, object[] arguments)
|
||||
{
|
||||
return string.Format("{0}({1})", name, string.Join(",", this.Expression, arguments));
|
||||
}
|
||||
|
||||
/// <summary> Adds addend. </summary>
|
||||
/// <param name="addend"> The decimal to add. </param>
|
||||
/// <returns> A computable class after the addition. </returns>
|
||||
public Computable Add(decimal addend)
|
||||
{
|
||||
this.expression = FormOperation(ADD, addend);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Subtracts the subtrahend. </summary>
|
||||
/// <param name="subtrahend"> The subtrahend. </param>
|
||||
/// <returns> A computable class after the subtraction. </returns>
|
||||
public Computable Subtract(decimal subtrahend)
|
||||
{
|
||||
this.expression = FormOperation(SUBSTRACT, subtrahend);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Multiplies the multiplicand. </summary>
|
||||
/// <param name="multiplicand"> The multiplicand. </param>
|
||||
/// <returns> A computable class after the mulitplication. </returns>
|
||||
public Computable Multiply(decimal multiplicand)
|
||||
{
|
||||
this.expression = FormOperation(MULTIPLY, multiplicand);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Divides the divisor. </summary>
|
||||
/// <param name="divisor"> The divisor. </param>
|
||||
/// <returns> A computable class after the divison. </returns>
|
||||
public Computable Divide(decimal divisor)
|
||||
{
|
||||
this.expression = FormOperation(DIVIDE, divisor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Mods using a given divisor. </summary>
|
||||
/// <param name="divisor"> The divisor. </param>
|
||||
/// <returns> A computable class after the mod. </returns>
|
||||
public Computable Mod(decimal divisor)
|
||||
{
|
||||
this.expression = FormOperation(MOD, divisor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Raises to power of the given integer value. </summary>
|
||||
/// <param name="power"> The power. </param>
|
||||
/// <returns> A computable class after the power operation. </returns>
|
||||
public Computable RaiseToPower(int power)
|
||||
{
|
||||
this.expression = FormOperation(POWER, power);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Applies the function <paramref name="name"/> with the current expression as the first argument, followed by <paramref name="arguments"/>. </summary>
|
||||
/// <param name="name"> The name of the function. </param>
|
||||
/// <param name="arguments"> The arguments. </param>
|
||||
/// <returns> A computable class after the function is applied. </returns>
|
||||
public Computable ApplyFunction(string name, object[] arguments)
|
||||
{
|
||||
this.expression = FormFunction(name, arguments);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Executes a command for all items in a collection. </summary>
|
||||
/// <typeparam name="T"> Generic type parameter. </typeparam>
|
||||
/// <param name="items"> The items of type <typeparamref name="T"/>. </param>
|
||||
/// <param name="action"> The action belonging to type <see cref="Computable"/>. </param>
|
||||
/// <returns> . </returns>
|
||||
public Computable ForAll<T>(ICollection<T> items, Func<Computable, Func<T, Computable>> action)
|
||||
{
|
||||
foreach (T item in items)
|
||||
{
|
||||
action(this)(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
178
CS-MIC/csmic/csmic/Extensions/CSMICExtension.cs
Normal file
178
CS-MIC/csmic/csmic/Extensions/CSMICExtension.cs
Normal file
|
@ -0,0 +1,178 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic.Extensions
|
||||
{
|
||||
/// <summary> CS-MIC extension methods. </summary>
|
||||
public static class CSMICExtension
|
||||
{
|
||||
#region String
|
||||
|
||||
/// <summary> A string extension method that interprets as input the string that calls it. </summary>
|
||||
/// <param name="input"> The input to act on. </param>
|
||||
/// <returns> The output from the interpretation of the string. </returns>
|
||||
public static string Interpret(this string input)
|
||||
{
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
interpreter.Interpret(input);
|
||||
return interpreter.Output;
|
||||
}
|
||||
|
||||
/// <summary> A string extension method that executes as macro operation. </summary>
|
||||
/// <param name="script"> The script to act on. </param>
|
||||
/// <returns> The final output of the script. </returns>
|
||||
public static string RunAsMacro(this string script)
|
||||
{
|
||||
MacroBuilder macro = new MacroBuilder(script, new InputInterpreter());
|
||||
return macro.FinalOutput;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<string>
|
||||
|
||||
/// <summary>
|
||||
/// A string extension method that interprets as input the string that calls it.
|
||||
/// </summary>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <returns> The output from the interpretation of the string. </returns>
|
||||
public static IEnumerable<string> Interpret(this IEnumerable<string> collection)
|
||||
{
|
||||
List<string> computed = new List<string>();
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
|
||||
foreach (string input in collection)
|
||||
{
|
||||
interpreter.Interpret(input);
|
||||
computed.Add(interpreter.Output);
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string extension method that interprets as input the string that calls it.
|
||||
/// </summary>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <param name="action"> The action. </param>
|
||||
/// <returns> The output from the interpretation of the string. </returns>
|
||||
public static IEnumerable<string> Interpret(this IEnumerable<string> collection, Action<InputInterpreter> action)
|
||||
{
|
||||
List<string> computed = new List<string>();
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
|
||||
foreach (string input in collection)
|
||||
{
|
||||
interpreter.Interpret(input);
|
||||
computed.Add(interpreter.Output);
|
||||
action(interpreter);
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
||||
/// <summary> Enumerates input in this collection, returning a selection on the interpreter. </summary>
|
||||
/// <typeparam name="T"> Generic type parameter. </typeparam>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <param name="selection"> The selection. </param>
|
||||
/// <returns>
|
||||
/// An enumerator that allows foreach to be used to process interpret< t> in this
|
||||
/// collection.
|
||||
/// </returns>
|
||||
public static IEnumerable<T> Interpret<T>(this IEnumerable<string> collection, Func<InputInterpreter, T> selection)
|
||||
{
|
||||
List<T> computed = new List<T>();
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
|
||||
foreach (string input in collection)
|
||||
{
|
||||
interpreter.Interpret(input);
|
||||
computed.Add(selection(interpreter));
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
||||
/// <summary> A string extension method that executes as macro operation. </summary>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <returns> The final output of the script. </returns>
|
||||
public static MacroBuilder RunAsMacro(this IEnumerable<string> collection)
|
||||
{
|
||||
return new MacroBuilder(string.Join(Environment.NewLine, collection.ToArray()), new InputInterpreter());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<string> In Parallel
|
||||
|
||||
/// <summary> Enumerates input in parallel in this collection. </summary>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <returns>
|
||||
/// An enumerator that allows foreach to be used to process interpret in parallel in this
|
||||
/// collection.
|
||||
/// </returns>
|
||||
public static IEnumerable<InputInterpreter> InterpretInParallel(this IEnumerable<string> collection)
|
||||
{
|
||||
ConcurrentBag<InputInterpreter> bag = new ConcurrentBag<InputInterpreter>();
|
||||
|
||||
collection.AsParallel().ForAll(input =>
|
||||
{
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
interpreter.Interpret(input);
|
||||
bag.Add(interpreter);
|
||||
});
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
/// <summary> Enumerates input in parallel this collection, returning a selection on the interpreter. </summary>
|
||||
/// <typeparam name="T"> Generic type parameter. </typeparam>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <param name="selection"> The selection. </param>
|
||||
/// <returns>
|
||||
/// An enumerator that allows foreach to be used to process interpret in parallel< t> in
|
||||
/// this collection.
|
||||
/// </returns>
|
||||
public static IEnumerable<T> InterpretInParallel<T>(this IEnumerable<string> collection, Func<InputInterpreter, T> selection)
|
||||
{
|
||||
ConcurrentBag<T> bag = new ConcurrentBag<T>();
|
||||
|
||||
collection.AsParallel().ForAll(input =>
|
||||
{
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
interpreter.Interpret(input);
|
||||
bag.Add(selection(interpreter));
|
||||
});
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ParallelQuery<string>
|
||||
|
||||
/// <summary>
|
||||
/// A string extension method that interprets as input the strings that calls it in parallel.
|
||||
/// </summary>
|
||||
/// <param name="collection"> The collection to act on. </param>
|
||||
/// <returns> The output from the interpretation of the string. </returns>
|
||||
public static IEnumerable<InputInterpreter> Interpret(this ParallelQuery<string> collection)
|
||||
{
|
||||
ConcurrentBag<InputInterpreter> bag = new ConcurrentBag<InputInterpreter>();
|
||||
|
||||
collection.ForAll(input =>
|
||||
{
|
||||
InputInterpreter interpreter = new InputInterpreter();
|
||||
interpreter.Interpret(input);
|
||||
bag.Add(interpreter);
|
||||
});
|
||||
|
||||
return bag;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
76
CS-MIC/csmic/csmic/GenericCodedFunction.cs
Normal file
76
CS-MIC/csmic/csmic/GenericCodedFunction.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// A generically coded implementation of the ICodedFunction interface.
|
||||
/// </summary>
|
||||
internal class GenericCodedFunction : ICodedFunction
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary> Number of expected arguments. </summary>
|
||||
private int numExpectedArguments;
|
||||
/// <summary> Name of the function. </summary>
|
||||
private string functionName;
|
||||
/// <summary> The method body. </summary>
|
||||
private Func<decimal[], decimal> methodBody;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary> Constructor. </summary>
|
||||
/// <param name="functionName"> Name of the function. </param>
|
||||
/// <param name="NumExpectedArguments"> Number of expected arguments. </param>
|
||||
/// <param name="methodBody"> The method body. </param>
|
||||
internal GenericCodedFunction(string functionName, int numExpectedArguments, Func<decimal[], decimal> methodBody)
|
||||
{
|
||||
this.functionName = functionName;
|
||||
this.numExpectedArguments = numExpectedArguments;
|
||||
this.methodBody = methodBody;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICodedFunction Members
|
||||
|
||||
/// <summary> Gets the number of expected arguments. </summary>
|
||||
/// <value> The total number of expected arguments. </value>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.numExpectedArguments;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the name of the function. </summary>
|
||||
/// <value> The name of the function. </value>
|
||||
public string FunctionName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.functionName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Executes a code block that computes the value of the function. </summary>
|
||||
/// <param name="args"> A variable-length parameters list containing arguments. </param>
|
||||
/// <returns> The decimal value computed by the function. </returns>
|
||||
public decimal Execute(params decimal[] args)
|
||||
{
|
||||
if (this.methodBody != null)
|
||||
{
|
||||
return this.methodBody(args);
|
||||
}
|
||||
|
||||
throw new MissingMethodException(this.GetType().Name, this.functionName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
73
CS-MIC/csmic/csmic/ICodedFunction.cs
Normal file
73
CS-MIC/csmic/csmic/ICodedFunction.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a function that is coded in the .Net environment.
|
||||
/// </summary>
|
||||
/// <remarks>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.</remarks>
|
||||
public interface ICodedFunction
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of expected arguments.
|
||||
/// </summary>
|
||||
int NumExpectedArguments { get; }
|
||||
/// <summary>
|
||||
/// Gets the name of the function.
|
||||
/// </summary>
|
||||
/// <remarks>The input inputInterpreter will use this function name as
|
||||
/// executable text, expecting an opening and closing parenthesis following
|
||||
/// it.</remarks>
|
||||
string FunctionName { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Executes a code block that computes the value of the function.
|
||||
/// </summary>
|
||||
/// <param name="args">An array of arguments passed to the function.</param>
|
||||
/// <returns>The decimal value computed by the function.</returns>
|
||||
/// <remarks>Any code block is valid. Error handling must be done by the
|
||||
/// developer, as the inputInterpreter cannot determine if there is an error.</remarks>
|
||||
/// <example>
|
||||
/// This example shows how to implement the sine function through the interface's
|
||||
/// Execute() function.
|
||||
/// <code>
|
||||
/// 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;
|
||||
///}
|
||||
///</code>
|
||||
///</example>
|
||||
decimal Execute(params decimal[] args);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
502
CS-MIC/csmic/csmic/InputInterpreter.cs
Normal file
502
CS-MIC/csmic/csmic/InputInterpreter.cs
Normal file
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// An interpreter object that reads user input and evaluates the code.
|
||||
/// </summary>
|
||||
/// <remarks>The interpreter does not support exceptions by design. Instead, invalid
|
||||
/// calculations, parameters, etc. will result in a result of zero.
|
||||
/// <code>
|
||||
/// InputInterpreter interpreter = new InputInterpreter();
|
||||
/// interpreter.Interpret("1/0"); // The result will be 0, not an exception.
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public class InputInterpreter
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The output generated.
|
||||
/// </summary>
|
||||
private string output;
|
||||
/// <summary>
|
||||
/// The variables assigned.
|
||||
/// </summary>
|
||||
internal Dictionary<string, Variable> variables;
|
||||
/// <summary>
|
||||
/// The time for execution.
|
||||
/// </summary>
|
||||
private TimeSpan executionTime;
|
||||
/// <summary>
|
||||
/// The verbose message of the calculation.
|
||||
/// </summary>
|
||||
private string message;
|
||||
/// <summary>
|
||||
/// The list of coded functions that can be executed.
|
||||
/// </summary>
|
||||
private List<ICodedFunction> codedFunctions;
|
||||
/// <summary>
|
||||
/// The list of user defined functions that can be executed.
|
||||
/// </summary>
|
||||
private List<InterpretedFunction> interpretedFunctions;
|
||||
/// <summary>
|
||||
/// The private calculated value.
|
||||
/// </summary>
|
||||
private decimal calculatedValue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new InputInterpreter.
|
||||
/// </summary>
|
||||
public InputInterpreter()
|
||||
{
|
||||
this.output = string.Empty;
|
||||
this.variables = new Dictionary<string, Variable>();
|
||||
this.executionTime = new TimeSpan();
|
||||
this.codedFunctions = new List<ICodedFunction>();
|
||||
this.interpretedFunctions = new List<InterpretedFunction>();
|
||||
LoadDefaultCodedFunctions();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new InputInterpreter from an original.
|
||||
/// </summary>
|
||||
/// <param name="original">The orginal input interpreter to copy.</param>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message that represents the InputInterpreters output.
|
||||
/// </summary>
|
||||
public string Output
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.output;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the verbose message that is generated with a calculation.
|
||||
/// </summary>
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.message;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the output as a decimal.
|
||||
/// </summary>
|
||||
public decimal Decimal
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.calculatedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the output cast as an int.
|
||||
/// </summary>
|
||||
public int Int
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)decimal.Round(this.calculatedValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the output cast as a float.
|
||||
/// </summary>
|
||||
public float Float
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)this.calculatedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the output cast as a double.
|
||||
/// </summary>
|
||||
public double Double
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)this.calculatedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value (cast as a long) converted to its binary equivalent.
|
||||
/// </summary>
|
||||
public string Binary
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToString((long)this.calculatedValue, 2).PadLeft(64, '0');
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution time of the last calculation.
|
||||
/// </summary>
|
||||
public TimeSpan LastExecutionTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.executionTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of coded functions that the interpreter supports.
|
||||
/// </summary>
|
||||
public List<ICodedFunction> CodedFunctions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.codedFunctions;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.codedFunctions = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of user generated interpreted functions that the interpreter supports.
|
||||
/// </summary>
|
||||
/// <value> The interpreted functions. </value>
|
||||
public List<InterpretedFunction> InterpretedFunctions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.interpretedFunctions;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.interpretedFunctions = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the variables. </summary>
|
||||
/// <value> The variables. </value>
|
||||
public Dictionary<string, Variable> Variables
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.variables;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.variables = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Interprets and executes given input.
|
||||
/// </summary>
|
||||
/// <param name="input">The input to interpret and execute.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes an expression and returns the result as a decimal.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression to be calculated.</param>
|
||||
/// <returns>The value that was computed.</returns>
|
||||
public decimal ComputeExpression(string expression)
|
||||
{
|
||||
this.Interpret(expression);
|
||||
return this.calculatedValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a decimal value to a variable.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the variable.</param>
|
||||
/// <param name="value">The value of the variable.</param>
|
||||
/// <returns>True if the variable was set, false otherwise.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a decimal value to a variable.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the variable.</param>
|
||||
/// <param name="expression">The expression of the variable.</param>
|
||||
/// <returns>True if the variable was set, false otherwise.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a decimal value to a variable.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the variable.</param>
|
||||
/// <param name="values">The values of the variable.</param>
|
||||
/// <returns>True if the variable was set, false otherwise.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function stored in the interpreter.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the function to execute.</param>
|
||||
/// <param name="args">The arguments to pass to the function.</param>
|
||||
/// <returns>The value computed from the function execution.</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Loads the default coded functions supported by the interpreter.
|
||||
/// </summary>
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces output given a single object.
|
||||
/// </summary>
|
||||
/// <param name="output">The object representing the output.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces output given an object and a message.
|
||||
/// </summary>
|
||||
/// <param name="output">The object representing the output.</param>
|
||||
/// <param name="message">The message to be displayed with the output.</param>
|
||||
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
|
||||
|
||||
/// <summary> Interpret an input asynchronously. </summary>
|
||||
/// <param name="input"> The input to interpret and execute. </param>
|
||||
/// <param name="callback"> The callback. </param>
|
||||
public void InterpretAsync(string input, Action<InputInterpreter> 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);
|
||||
}
|
||||
|
||||
/// <summary> Interpret asynchronous threading work. </summary>
|
||||
/// <param name="input"> The input to interpret and execute. </param>
|
||||
private InputInterpreter InterpretAsyncThreadingWork(string input)
|
||||
{
|
||||
Interpret(input);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Interpret asynchronous delegate. </summary>
|
||||
/// <param name="input"> The input. </param>
|
||||
/// <returns> . </returns>
|
||||
private delegate InputInterpreter InterpretAsyncDelegate(string input);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Computable
|
||||
|
||||
/// <summary> Converts this object to a computable. </summary>
|
||||
/// <returns> This object as a Computable. </returns>
|
||||
public Computable ToComputable()
|
||||
{
|
||||
return new Computable(this.Decimal.ToString(), this);
|
||||
}
|
||||
|
||||
/// <summary> Treats the current object as a computable and performs an action in that context. </summary>
|
||||
/// <param name="action"> The action to execute as a computable object. </param>
|
||||
/// <returns> This object as a Computable, after the given action. </returns>
|
||||
public Computable AsComputable(Func<Computable, Computable> action)
|
||||
{
|
||||
return action(this.ToComputable());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
151
CS-MIC/csmic/csmic/InterpretedFunction.cs
Normal file
151
CS-MIC/csmic/csmic/InterpretedFunction.cs
Normal file
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a user defined function that can be executed by the interpreter.
|
||||
/// </summary>
|
||||
public class InterpretedFunction
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The name of the function.
|
||||
/// </summary>
|
||||
private string name;
|
||||
/// <summary>
|
||||
/// The number of expected arguments.
|
||||
/// </summary>
|
||||
private int numExpectedArguments;
|
||||
/// <summary>
|
||||
/// The set of instructions to be passed to the internal inputInterpreter.
|
||||
/// </summary>
|
||||
private MacroOperation script;
|
||||
/// <summary>
|
||||
/// A set of arguments used in computation of the function.
|
||||
/// </summary>
|
||||
private InterpretedFunctionArgument[] arguments;
|
||||
/// <summary>
|
||||
/// The internal macro builder used for computation.
|
||||
/// </summary>
|
||||
private MacroBuilder macroFunction;
|
||||
/// <summary>
|
||||
/// The internal input inputInterpreter that macro builder will use for computation.
|
||||
/// </summary>
|
||||
private InputInterpreter interpreter;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new interpreted function.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the fuction.</param>
|
||||
/// <param name="script">The node to be used in computation.</param>
|
||||
/// <param name="args">A set of argument names to be used in computation.</param>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the function.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of expected arguments for the function.
|
||||
/// </summary>
|
||||
public int NumExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.numExpectedArguments;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Computes the value of the function.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments used for computation.</param>
|
||||
/// <returns>The decimal value computed by the function.</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Because a function's internal pattern may be different, we must manually check to see if the function
|
||||
/// names are the same.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to test.</param>
|
||||
/// <returns>True if the functions are the same.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
InterpretedFunction fun = obj as InterpretedFunction;
|
||||
if(fun != null)
|
||||
{
|
||||
return fun.name == this.name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary> Serves as a hash function for a particular type. </summary>
|
||||
/// <returns> A hash code for the current <see cref="T:System.Object" />. </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.script.GetHashCode() & this.name.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
84
CS-MIC/csmic/csmic/InterpretedFunctionArgument.cs
Normal file
84
CS-MIC/csmic/csmic/InterpretedFunctionArgument.cs
Normal file
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an argument made in an interpreted function.
|
||||
/// </summary>
|
||||
public class InterpretedFunctionArgument
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The name of the argument.
|
||||
/// </summary>
|
||||
private string name;
|
||||
/// <summary>
|
||||
/// The value of the argument.
|
||||
/// </summary>
|
||||
private decimal value;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new interpreted function argument.
|
||||
/// </summary>
|
||||
public InterpretedFunctionArgument()
|
||||
{
|
||||
this.name = string.Empty;
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new interpreted function argument.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the argument in the interpreted function.</param>
|
||||
/// <param name="value">The value of the argument to use in the interpreted function.</param>
|
||||
public InterpretedFunctionArgument(string name, decimal value)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the argument.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the argument.
|
||||
/// </summary>
|
||||
public decimal Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
369
CS-MIC/csmic/csmic/InterpreterParser/CSMIC.atg
Normal file
369
CS-MIC/csmic/csmic/InterpreterParser/CSMIC.atg
Normal file
|
@ -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<out success> (. this.calcValue = (success == true) ? 1 : 0; this.interpreter.ProduceOutput(success); .)
|
||||
|
|
||||
IF(IsAssignment())
|
||||
Assignment<out r> (. this.calcValue = r; .)
|
||||
|
|
||||
Expression<out r> (. this.calcValue = r; this.interpreter.ProduceOutput(r); .)
|
||||
|
|
||||
String<out s> (. this.stringValue = s; this.interpreter.ProduceOutput(s); .)
|
||||
.
|
||||
|
||||
String<out string s>
|
||||
=
|
||||
string (. s = t.val; .)
|
||||
|
||||
.
|
||||
|
||||
Expression<out decimal r>
|
||||
=
|
||||
(. decimal r1; .)
|
||||
Term<out r>
|
||||
{
|
||||
'+' Term<out r1> (. r += r1; .)
|
||||
|
|
||||
'-' Term<out r1> (. r -= r1; .)
|
||||
}
|
||||
.
|
||||
|
||||
Term<out decimal r> (. decimal r1; .)
|
||||
=
|
||||
Factor<out r>
|
||||
{
|
||||
'*'
|
||||
Factor<out r1> (. r *= r1; .)
|
||||
|
|
||||
'/'
|
||||
Factor<out r1> (. r /= r1; .)
|
||||
|
|
||||
'%' Term<out r1> (. r %= r1; .)
|
||||
}
|
||||
.
|
||||
|
||||
Factor<out decimal r> (. decimal r1; .)
|
||||
=
|
||||
Value<out r>
|
||||
{
|
||||
'^'
|
||||
Expression<out r1> (. r = Convert.ToDecimal(Math.Pow(Convert.ToDouble(r), Convert.ToDouble(r1))); .)
|
||||
}
|
||||
.
|
||||
|
||||
Value<out decimal r> (. r = 0;
|
||||
decimal r1 = 0;
|
||||
string fn;
|
||||
int sign = 1;.)
|
||||
=
|
||||
|
||||
[
|
||||
"+"
|
||||
|
|
||||
"-" (. sign = -1; .)
|
||||
]
|
||||
(
|
||||
IF(IsFunctionCall())
|
||||
Function<out r> (. r = sign * r; .)
|
||||
|
|
||||
IF(IsArrayCall())
|
||||
ArrayCall<out r> (. 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<out r>
|
||||
')' (. r = sign * r; .)
|
||||
)
|
||||
.
|
||||
|
||||
ArrayL<out decimal[] d>
|
||||
=
|
||||
'['
|
||||
CommaList<out d>
|
||||
']'
|
||||
.
|
||||
|
||||
ArrayCall<out decimal r> (. string ident = string.Empty; r = 0; decimal pos = 0; .)
|
||||
=
|
||||
identifier (. ident = t.val; .)
|
||||
'['
|
||||
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
|
||||
{
|
||||
}
|
||||
.)
|
||||
']'
|
||||
.
|
||||
|
||||
CommaList<out decimal[] d> (. List<decimal> list = new List<decimal>(); decimal r = 0; .)
|
||||
=
|
||||
Expression<out r> (. list.Add(r); d = list.ToArray(); .)
|
||||
{
|
||||
','
|
||||
Expression<out r> (. list.Add(r); d = list.ToArray(); .)
|
||||
}
|
||||
.
|
||||
|
||||
Assignment<out decimal r> (.
|
||||
string identifier = string.Empty;
|
||||
string expression = string.Empty;
|
||||
decimal[] d = new decimal[0];
|
||||
r = 0;
|
||||
.)
|
||||
=
|
||||
identifier (. identifier = t.val; .)
|
||||
(
|
||||
(
|
||||
"::"
|
||||
Expression<out r> (. this.interpreter.Assign(identifier, r); .)
|
||||
(. this.interpreter.ProduceOutput(r); .)
|
||||
)
|
||||
|
|
||||
(
|
||||
":="
|
||||
AnyExpression<out expression> (. this.interpreter.Assign(identifier, expression); .)
|
||||
(. this.interpreter.ProduceOutput(expression); .)
|
||||
)
|
||||
|
|
||||
(
|
||||
"->"
|
||||
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());
|
||||
.)
|
||||
)
|
||||
)
|
||||
.
|
||||
|
||||
Function<out decimal r> (.
|
||||
string functionName = string.Empty;
|
||||
decimal[] d = new decimal[0];
|
||||
.)
|
||||
=
|
||||
identifier (. functionName = t.val; .)
|
||||
'('
|
||||
CommaList<out d>
|
||||
')' (. r = this.interpreter.ExecuteFunction(functionName, d); .)
|
||||
.
|
||||
|
||||
Comparison<out bool result> (.
|
||||
decimal firstValue = 0;
|
||||
decimal secondValue = 0;
|
||||
string compareType = string.Empty;
|
||||
.)
|
||||
=
|
||||
Expression<out firstValue>
|
||||
COMPARER (. 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;
|
||||
}
|
||||
.)
|
||||
.
|
||||
|
||||
AnyExpression<out string value> (. value = string.Empty; StringBuilder builder = new StringBuilder(); .)
|
||||
=
|
||||
ANY (. builder.Append(t.val); .) { ANY (. builder.Append(t.val); .) } (. value = builder.ToString(); .)
|
||||
.
|
||||
|
||||
|
||||
END CSMIC.
|
534
CS-MIC/csmic/csmic/InterpreterParser/Parser.cs
Normal file
534
CS-MIC/csmic/csmic/InterpreterParser/Parser.cs
Normal file
|
@ -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<decimal> list = new List<decimal>(); 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) {}
|
||||
}
|
||||
|
||||
}
|
160
CS-MIC/csmic/csmic/InterpreterParser/Parser.frame
Normal file
160
CS-MIC/csmic/csmic/InterpreterParser/Parser.frame
Normal file
|
@ -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) {}
|
||||
}
|
||||
|
491
CS-MIC/csmic/csmic/InterpreterParser/Scanner.cs
Normal file
491
CS-MIC/csmic/csmic/InterpreterParser/Scanner.cs
Normal file
|
@ -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<int, int> 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<int, int>(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
|
||||
}
|
383
CS-MIC/csmic/csmic/InterpreterParser/Scanner.frame
Normal file
383
CS-MIC/csmic/csmic/InterpreterParser/Scanner.frame
Normal file
|
@ -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<int, int> 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<int, int>(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
|
337
CS-MIC/csmic/csmic/MacroBuilder.cs
Normal file
337
CS-MIC/csmic/csmic/MacroBuilder.cs
Normal file
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// A builder object that executes macro scripts.
|
||||
/// </summary>
|
||||
public class MacroBuilder
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The input inputInterpreter.
|
||||
/// </summary>
|
||||
private InputInterpreter interpreter;
|
||||
/// <summary> The script to run as a macro. </summary>
|
||||
private string script;
|
||||
/// <summary>
|
||||
/// The output as a list of strings.
|
||||
/// </summary>
|
||||
private List<string> output;
|
||||
/// <summary>
|
||||
/// The time for execution.
|
||||
/// </summary>
|
||||
private TimeSpan executionTime;
|
||||
/// <summary>
|
||||
/// The root macro operation.
|
||||
/// </summary>
|
||||
private MacroOperation rootOperation;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new builder object that executes a given macro script.
|
||||
/// </summary>
|
||||
/// <param name="script">A list of strings representing the macro.</param>
|
||||
/// <param name="inputInterpreter">The InputInterpreter to be used.</param>
|
||||
public MacroBuilder(string script, InputInterpreter inputInterpreter)
|
||||
{
|
||||
this.output = new List<string>();
|
||||
this.executionTime = new TimeSpan();
|
||||
|
||||
this.script = script;
|
||||
this.interpreter = inputInterpreter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new builder object that executes a given macro script.
|
||||
/// </summary>
|
||||
/// <param name="script">A list of strings representing the macro.</param>
|
||||
/// <param name="inputInterpreter">The InputInterpreter to be used.</param>
|
||||
internal MacroBuilder(MacroOperation script, InputInterpreter inputInterpreter)
|
||||
{
|
||||
this.output = new List<string>();
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of strings representing the output.
|
||||
/// </summary>
|
||||
public List<string> Output
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.output;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the execution time of the last script computation.
|
||||
/// </summary>
|
||||
public TimeSpan LastExecutionTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.executionTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the decimal value last computed by the macrobuilder.
|
||||
/// </summary>
|
||||
public string FinalOutput
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.interpreter.Output;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary> Runs this macro. </summary>
|
||||
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
|
||||
|
||||
/// <summary> Executes the asynchronous operation. </summary>
|
||||
/// <param name="input"> The input. </param>
|
||||
/// <param name="callback"> The callback. </param>
|
||||
public void RunAsync(string input, Action<MacroBuilder> 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);
|
||||
}
|
||||
|
||||
/// <summary> Executes the asynchronous threading work operation. </summary>
|
||||
/// <param name="input"> The input. </param>
|
||||
/// <returns> . </returns>
|
||||
private MacroBuilder RunAsyncThreadingWork(string input)
|
||||
{
|
||||
Run();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Macro asynchronous delegate. </summary>
|
||||
/// <param name="input"> The input. </param>
|
||||
/// <returns> . </returns>
|
||||
private delegate MacroBuilder MacroAsyncDelegate(string input);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
149
CS-MIC/csmic/csmic/MacroOperation.cs
Normal file
149
CS-MIC/csmic/csmic/MacroOperation.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the operation types supported by a scripted macro.
|
||||
/// </summary>
|
||||
internal enum OperationType
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a conditional block.
|
||||
/// </summary>
|
||||
If,
|
||||
/// <summary>
|
||||
/// Represents a conditional else block.
|
||||
/// </summary>
|
||||
Else,
|
||||
/// <summary>
|
||||
/// Represents a complete conditional block.
|
||||
/// </summary>
|
||||
IfElse,
|
||||
/// <summary>
|
||||
/// A while block.
|
||||
/// </summary>
|
||||
While,
|
||||
/// <summary>
|
||||
/// A for block.
|
||||
/// </summary>
|
||||
For,
|
||||
/// <summary>
|
||||
/// A function declaration.
|
||||
/// </summary>
|
||||
FunctionDeclaration,
|
||||
/// <summary>
|
||||
/// An echo statement.
|
||||
/// </summary>
|
||||
Echo,
|
||||
/// <summary>
|
||||
/// A say statement.
|
||||
/// </summary>
|
||||
Say,
|
||||
/// <summary>
|
||||
/// A display statement.
|
||||
/// </summary>
|
||||
Display,
|
||||
/// <summary>
|
||||
/// A statement to execute.
|
||||
/// </summary>
|
||||
Statement,
|
||||
/// <summary>
|
||||
/// A string to display.
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// An unknown or malformed block.
|
||||
/// </summary>
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An operation object that executes a specified action.
|
||||
/// </summary>
|
||||
internal class MacroOperation
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The type of operation represented by the operation.
|
||||
/// </summary>
|
||||
private OperationType operationType;
|
||||
/// <summary>
|
||||
/// The collection of children nodes that belong to the operation.
|
||||
/// </summary>
|
||||
private List<MacroOperation> children;
|
||||
/// <summary>
|
||||
/// A list of the necesary input to execute the operation.
|
||||
/// </summary>
|
||||
private List<string> input;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new macro operation node.
|
||||
/// </summary>
|
||||
/// <param name="operationType">The type of operation the node represents.</param>
|
||||
public MacroOperation(OperationType operationType)
|
||||
{
|
||||
this.operationType = operationType;
|
||||
this.children = new List<MacroOperation>();
|
||||
this.input = new List<string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the children nodes of the operation.
|
||||
/// </summary>
|
||||
public List<MacroOperation> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.children;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.children = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the input for the operation.
|
||||
/// </summary>
|
||||
public List<string> Input
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.input;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.input = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the operation type for this operation.
|
||||
/// </summary>
|
||||
public OperationType OperationType
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.operationType;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.operationType = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
36
CS-MIC/csmic/csmic/Properties/AssemblyInfo.cs
Normal file
36
CS-MIC/csmic/csmic/Properties/AssemblyInfo.cs
Normal file
|
@ -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")]
|
798
CS-MIC/csmic/csmic/ScriptParser/Parser.cs
Normal file
798
CS-MIC/csmic/csmic/ScriptParser/Parser.cs
Normal file
|
@ -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) {}
|
||||
}
|
||||
|
||||
}
|
160
CS-MIC/csmic/csmic/ScriptParser/Parser.frame
Normal file
160
CS-MIC/csmic/csmic/ScriptParser/Parser.frame
Normal file
|
@ -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) {}
|
||||
}
|
||||
|
637
CS-MIC/csmic/csmic/ScriptParser/Scanner.cs
Normal file
637
CS-MIC/csmic/csmic/ScriptParser/Scanner.cs
Normal file
|
@ -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<int, int> 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<int, int>(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
|
||||
}
|
383
CS-MIC/csmic/csmic/ScriptParser/Scanner.frame
Normal file
383
CS-MIC/csmic/csmic/ScriptParser/Scanner.frame
Normal file
|
@ -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<int, int> 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<int, int>(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
|
525
CS-MIC/csmic/csmic/ScriptParser/Scripting.atg
Normal file
525
CS-MIC/csmic/csmic/ScriptParser/Scripting.atg
Normal file
|
@ -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<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
this.root.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref this.root>
|
||||
|
|
||||
WhileBlock<ref this.root>
|
||||
|
|
||||
FunctionDeclaration<ref this.root>
|
||||
|
|
||||
EchoStatement<ref this.root>
|
||||
|
|
||||
SayStatement<ref this.root>
|
||||
|
|
||||
DisplayStatement<ref this.root>
|
||||
|
|
||||
ForBlock<ref this.root>
|
||||
}
|
||||
.
|
||||
|
||||
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;
|
||||
.)
|
||||
=
|
||||
"if"
|
||||
LPAREN
|
||||
Comparison<ref builder> (. ifStatement = builder.ToString(); ifBlock.Input.Add(ifStatement); .)
|
||||
RPAREN
|
||||
'{'
|
||||
{
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
ifBlock.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref ifBlock>
|
||||
|
|
||||
WhileBlock<ref ifBlock>
|
||||
|
|
||||
EchoStatement<ref ifBlock>
|
||||
|
|
||||
SayStatement<ref ifBlock>
|
||||
|
|
||||
DisplayStatement<ref ifBlock>
|
||||
|
|
||||
ForBlock<ref ifBlock>
|
||||
}
|
||||
'}'
|
||||
[
|
||||
"else" (. hasElse = true; .)
|
||||
'{'
|
||||
{
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
elseBlock.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref elseBlock>
|
||||
|
|
||||
WhileBlock<ref elseBlock>
|
||||
|
|
||||
EchoStatement<ref elseBlock>
|
||||
|
|
||||
SayStatement<ref elseBlock>
|
||||
|
|
||||
DisplayStatement<ref elseBlock>
|
||||
|
|
||||
ForBlock<ref elseBlock>
|
||||
}
|
||||
'}'
|
||||
]
|
||||
(.
|
||||
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<ref MacroOperation parent> (.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
MacroOperation whileBlock = new MacroOperation(OperationType.While);
|
||||
string statement = string.Empty;
|
||||
.)
|
||||
=
|
||||
"while"
|
||||
LPAREN
|
||||
Comparison<ref builder> (. whileBlock.Input.Add(builder.ToString()); .)
|
||||
RPAREN
|
||||
'{'
|
||||
{
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
whileBlock.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref whileBlock>
|
||||
|
|
||||
WhileBlock<ref whileBlock>
|
||||
|
|
||||
EchoStatement<ref whileBlock>
|
||||
|
|
||||
SayStatement<ref whileBlock>
|
||||
|
|
||||
DisplayStatement<ref whileBlock>
|
||||
|
|
||||
ForBlock<ref whileBlock>
|
||||
}
|
||||
'}'
|
||||
(.
|
||||
parent.Children.Add(whileBlock);
|
||||
.)
|
||||
.
|
||||
|
||||
ForBlock<ref MacroOperation parent> (.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
string statement = string.Empty;
|
||||
string statement2 = string.Empty;
|
||||
MacroOperation forBlock = new MacroOperation(OperationType.For);
|
||||
.)
|
||||
=
|
||||
"for"
|
||||
LPAREN
|
||||
Statement<out statement>
|
||||
','
|
||||
Comparison<ref builder>
|
||||
','
|
||||
Statement<out statement2> (. forBlock.Input.Add(statement); forBlock.Input.Add(builder.ToString()); forBlock.Input.Add(statement2); .)
|
||||
RPAREN
|
||||
'{'
|
||||
{
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
forBlock.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref forBlock>
|
||||
|
|
||||
WhileBlock<ref forBlock>
|
||||
|
|
||||
EchoStatement<ref forBlock>
|
||||
|
|
||||
SayStatement<ref forBlock>
|
||||
|
|
||||
DisplayStatement<ref forBlock>
|
||||
|
|
||||
ForBlock<ref forBlock>
|
||||
}
|
||||
'}'
|
||||
(.
|
||||
parent.Children.Add(forBlock);
|
||||
.)
|
||||
.
|
||||
|
||||
FunctionDeclaration<ref MacroOperation parent> (.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
string statement = string.Empty;
|
||||
MacroOperation func = new MacroOperation(OperationType.FunctionDeclaration);
|
||||
.)
|
||||
=
|
||||
"function"
|
||||
LPAREN
|
||||
CommaList<ref builder> (. string[] args = builder.ToString().Split(','); func.Input.AddRange(args); .)
|
||||
RPAREN
|
||||
'{'
|
||||
{
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
func.Children.Add(operation);
|
||||
.)
|
||||
|
|
||||
IfBlock<ref func>
|
||||
|
|
||||
WhileBlock<ref func>
|
||||
|
|
||||
EchoStatement<ref func>
|
||||
|
|
||||
SayStatement<ref func>
|
||||
|
|
||||
DisplayStatement<ref func>
|
||||
|
|
||||
ForBlock<ref func>
|
||||
}
|
||||
'}'
|
||||
(.
|
||||
parent.Children.Add(func);
|
||||
.)
|
||||
.
|
||||
|
||||
EchoStatement<ref MacroOperation parent> (.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
MacroOperation echoStatement = new MacroOperation(OperationType.Echo);
|
||||
string statement = string.Empty;
|
||||
.)
|
||||
=
|
||||
"echo:"
|
||||
Statement<out statement> (.
|
||||
MacroOperation operation = new MacroOperation(OperationType.Statement);
|
||||
operation.Input.Add(statement);
|
||||
echoStatement.Children.Add(operation);
|
||||
parent.Children.Add(echoStatement);
|
||||
.)
|
||||
.
|
||||
|
||||
SayStatement<ref MacroOperation parent> (.
|
||||
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<ref MacroOperation parent> (.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
MacroOperation displayStatement = new MacroOperation(OperationType.Display);
|
||||
string statement = string.Empty;
|
||||
.)
|
||||
=
|
||||
"display:"
|
||||
(
|
||||
Statement<out 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<out 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<out string value> (.
|
||||
value = string.Empty;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
.)
|
||||
=
|
||||
IF(IsAssignment())
|
||||
Assignment<ref builder> (. value = builder.ToString(); .)
|
||||
|
|
||||
Expression<ref builder> (. value = builder.ToString(); .)
|
||||
.
|
||||
|
||||
Expression<ref StringBuilder builder>
|
||||
=
|
||||
Term<ref builder>
|
||||
{
|
||||
'+' (. builder.Append(t.val); .) Term<ref builder>
|
||||
|
|
||||
'-' (. builder.Append(t.val); .) Term<ref builder>
|
||||
|
|
||||
'%' (. builder.Append(t.val); .) Term<ref builder>
|
||||
}
|
||||
.
|
||||
|
||||
Term<ref StringBuilder builder>
|
||||
=
|
||||
Factor<ref builder>
|
||||
{
|
||||
'*' (. builder.Append(t.val); .)
|
||||
Factor<ref builder>
|
||||
|
|
||||
'/' (. builder.Append(t.val); .)
|
||||
Factor<ref builder>
|
||||
}
|
||||
.
|
||||
|
||||
Factor<ref StringBuilder builder>
|
||||
=
|
||||
Value<ref builder>
|
||||
{
|
||||
'^' (. builder.Append(t.val); .)
|
||||
Value<ref builder>
|
||||
}
|
||||
.
|
||||
|
||||
Value<ref StringBuilder builder>
|
||||
=
|
||||
|
||||
[
|
||||
"+" (. builder.Append(t.val); .)
|
||||
|
|
||||
"-" (. builder.Append(t.val); .)
|
||||
]
|
||||
(
|
||||
IF(IsFunctionCall())
|
||||
Function<ref builder>
|
||||
|
|
||||
IF(IsArrayCall())
|
||||
ArrayCall<ref builder>
|
||||
|
|
||||
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<ref builder>
|
||||
')' (. builder.Append(t.val); .)
|
||||
)
|
||||
.
|
||||
|
||||
ArrayL<ref StringBuilder builder>
|
||||
=
|
||||
'[' (. builder.Append(t.val); .)
|
||||
CommaList<ref builder>
|
||||
']' (. builder.Append(t.val); .)
|
||||
.
|
||||
|
||||
CommaList<ref StringBuilder builder>
|
||||
=
|
||||
Expression<ref builder>
|
||||
{
|
||||
',' (. builder.Append(t.val); .)
|
||||
Expression<ref builder>
|
||||
}
|
||||
.
|
||||
|
||||
Assignment<ref StringBuilder builder>
|
||||
=
|
||||
identifier (. builder.Append(t.val); .)
|
||||
(
|
||||
(
|
||||
"::" (. builder.Append(t.val); .)
|
||||
Expression<ref builder>
|
||||
)
|
||||
|
|
||||
(
|
||||
":=" (. builder.Append(t.val); string value = string.Empty; .)
|
||||
AnyExpression<out value> (. builder.Append(value); .)
|
||||
newline
|
||||
)
|
||||
|
|
||||
(
|
||||
"->" (. builder.Append(t.val); .)
|
||||
ArrayL<ref builder>
|
||||
)
|
||||
)
|
||||
.
|
||||
|
||||
Function<ref StringBuilder builder>
|
||||
=
|
||||
identifier (. builder.Append(t.val); .)
|
||||
'(' (. builder.Append(t.val); .)
|
||||
CommaList<ref builder>
|
||||
')' (. builder.Append(t.val); .)
|
||||
.
|
||||
|
||||
ArrayCall<ref StringBuilder builder>
|
||||
=
|
||||
identifier (. builder.Append(t.val); .)
|
||||
'[' (. builder.Append(t.val); .)
|
||||
Expression<ref builder>
|
||||
']' (. builder.Append(t.val); .)
|
||||
.
|
||||
|
||||
Comparison<ref StringBuilder result>
|
||||
=
|
||||
Expression<ref result>
|
||||
COMPARER (. result.Append(t.val); .)
|
||||
Expression<ref result>
|
||||
.
|
||||
|
||||
AnyExpression<out string value> (. value = string.Empty; StringBuilder builder = new StringBuilder(); .)
|
||||
=
|
||||
ANY (. builder.Append(t.val); .) { ANY (. builder.Append(t.val); .) } '\n' (. value = builder.ToString(); .)
|
||||
.
|
||||
|
||||
|
||||
END SCRIPT.
|
100
CS-MIC/csmic/csmic/Variable.cs
Normal file
100
CS-MIC/csmic/csmic/Variable.cs
Normal file
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace csmic
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the data types supported in a variable.
|
||||
/// </summary>
|
||||
public enum VariableType
|
||||
{
|
||||
/// <summary>
|
||||
/// Decimal
|
||||
/// </summary>
|
||||
Decimal,
|
||||
/// <summary>
|
||||
/// Equation
|
||||
/// </summary>
|
||||
Equation,
|
||||
/// <summary>
|
||||
/// Array
|
||||
/// </summary>
|
||||
Array,
|
||||
/// <summary>
|
||||
/// Unknown
|
||||
/// </summary>
|
||||
Unknown,
|
||||
/// <summary>
|
||||
/// No type associated
|
||||
/// </summary>
|
||||
None
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An object that contains information about a variable.
|
||||
/// </summary>
|
||||
public class Variable
|
||||
{
|
||||
#region Members
|
||||
|
||||
/// <summary>
|
||||
/// The type of variable.
|
||||
/// </summary>
|
||||
private VariableType type;
|
||||
/// <summary>
|
||||
/// The value of the variable.
|
||||
/// </summary>
|
||||
private object value;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty variable.
|
||||
/// </summary>
|
||||
public Variable()
|
||||
{
|
||||
this.type = VariableType.None;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an object representing the variable's value.
|
||||
/// </summary>
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the variable.
|
||||
/// </summary>
|
||||
public VariableType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.type = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
136
CS-MIC/csmic/csmic/csmic.csproj
Normal file
136
CS-MIC/csmic/csmic/csmic.csproj
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7BBA4BA2-E885-4D89-8710-F1A609616B7D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>csmic</RootNamespace>
|
||||
<AssemblyName>csmic</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>csmic_open.snk</AssemblyOriginatorKeyFile>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Debug\csmic.XML</DocumentationFile>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Release\csmic.XML</DocumentationFile>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CodedFunctionFactory.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Abs.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Exp.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Log.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Precision.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Sqrt.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Cos.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Round.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Sin.cs" />
|
||||
<Compile Include="CodedFunctions\CF_Tan.cs" />
|
||||
<Compile Include="Computable\Computable.cs" />
|
||||
<Compile Include="Extensions\CSMICExtension.cs" />
|
||||
<Compile Include="GenericCodedFunction.cs" />
|
||||
<Compile Include="ICodedFunction.cs" />
|
||||
<Compile Include="InputInterpreter.cs" />
|
||||
<Compile Include="InterpretedFunction.cs" />
|
||||
<Compile Include="InterpretedFunctionArgument.cs" />
|
||||
<Compile Include="MacroBuilder.cs" />
|
||||
<Compile Include="MacroOperation.cs" />
|
||||
<Compile Include="InterpreterParser\Parser.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="InterpreterParser\Scanner.cs" />
|
||||
<Compile Include="ScriptParser\Parser.cs" />
|
||||
<Compile Include="ScriptParser\Scanner.cs" />
|
||||
<Compile Include="Variable.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="csmic_open.snk" />
|
||||
<None Include="InterpreterParser\Parser.frame" />
|
||||
<None Include="InterpreterParser\Scanner.frame" />
|
||||
<None Include="ScriptParser\Parser.frame" />
|
||||
<None Include="ScriptParser\Scanner.frame" />
|
||||
<None Include="ScriptParser\Scripting.atg" />
|
||||
<None Include="InterpreterParser\CSMIC.atg" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>"$(ProjectDir)\coco.exe" -namespace csmic.Interpreter -frames . "$(ProjectDir)\InterpreterParser\CSMIC.atg"
|
||||
"$(ProjectDir)\coco.exe" -namespace csmic.Scripting -frames . "$(ProjectDir)\ScriptParser\Scripting.atg"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
10
CS-MIC/csmic/csmic/csmic.csproj.vspscc
Normal file
10
CS-MIC/csmic/csmic/csmic.csproj.vspscc
Normal file
|
@ -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"
|
||||
}
|
BIN
CS-MIC/csmic/csmic/csmic_open.snk
Normal file
BIN
CS-MIC/csmic/csmic/csmic_open.snk
Normal file
Binary file not shown.
Loading…
Reference in a new issue