Migrating from Sourceforge to Codeplex. Initial checkin starting with version 1.1.5.0 source code.

This commit is contained in:
Jordan Wages 2013-10-20 03:46:38 +00:00
commit c41167bfc4
44 changed files with 7608 additions and 0 deletions

View 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);
}
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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&lt; t&gt; 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&lt; t&gt; 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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();
}
}
}

View 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
}
}

View 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.

View 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) {}
}
}

View 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) {}
}

View 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
}

View 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

View 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
}
}

View 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
}
}

View 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")]

View 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) {}
}
}

View 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) {}
}

View 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
}

View 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

View 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.

View 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
}
}

View 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>

View 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"
}

Binary file not shown.