using System;
using System.Collections.Generic;
namespace DigitalSamurai.SpellSharp.InputProcessing.Processors
{
public partial class CSharpProcessor
{
public partial class CSharpParser
{
public static class Expressions
{
private delegate void ParseMethod (CSharpParsingState current);
private static Dictionary<LexicalElements, ParseMethod> expressions;
static Expressions ()
{
expressions = new Dictionary<LexicalElements, ParseMethod> ();
// -- Operators --
expressions.Add (LexicalElements.Symbol_Minus, null);
expressions.Add (LexicalElements.Symbol_Minus_Minus, null);
expressions.Add (LexicalElements.Symbol_ExclamationMark, null);
expressions.Add (LexicalElements.Symbol_Tilde, null);
expressions.Add (LexicalElements.Symbol_Plus, null);
expressions.Add (LexicalElements.Symbol_Plus_Plus, null);
expressions.Add (LexicalElements.SizeOf, Parse_ParenthesisScopedType);
expressions.Add (LexicalElements.TypeOf, Parse_ParenthesisScopedType);
expressions.Add (LexicalElements.Symbol_ParenthesisOpen, Parse_ParenthesisOpen);
// -- Language (defined) types --
expressions.Add (LexicalElements.Bool, Parse_StaticMethod);
expressions.Add (LexicalElements.Byte, Parse_StaticMethod);
expressions.Add (LexicalElements.Char, Parse_StaticMethod);
expressions.Add (LexicalElements.Decimal, Parse_StaticMethod);
expressions.Add (LexicalElements.Double, Parse_StaticMethod);
expressions.Add (LexicalElements.Float, Parse_StaticMethod);
expressions.Add (LexicalElements.Int, Parse_StaticMethod);
expressions.Add (LexicalElements.Long, Parse_StaticMethod);
expressions.Add (LexicalElements.Object, Parse_StaticMethod);
expressions.Add (LexicalElements.SByte, Parse_StaticMethod);
expressions.Add (LexicalElements.Short, Parse_StaticMethod);
expressions.Add (LexicalElements.String, Parse_StaticMethod);
expressions.Add (LexicalElements.UInt, Parse_StaticMethod);
expressions.Add (LexicalElements.ULong, Parse_StaticMethod);
expressions.Add (LexicalElements.UShort, Parse_StaticMethod);
// -- Values --
expressions.Add (LexicalElements.CharValue, null);
expressions.Add (LexicalElements.StringValue, Parse_StringValue);
expressions.Add (LexicalElements.IntegerValue, null);
expressions.Add (LexicalElements.RealValue, null);
expressions.Add (LexicalElements.False, null);
expressions.Add (LexicalElements.Null, null);
expressions.Add (LexicalElements.True, null);
// -- Query statements --
expressions.Add (LexicalElements.From, Query.Parse_From);
// -- Various --
expressions.Add (LexicalElements.Base, Parse_Base);
expressions.Add (LexicalElements.This, Parse_This);
expressions.Add (LexicalElements.Value, null);
expressions.Add (LexicalElements.New, Parse_New);
expressions.Add (LexicalElements.StackAlloc, Parse_StackAlloc);
// -- Various : undocumented keywords
expressions.Add (LexicalElements.MakeRef, Parse_ParenthesisScopedExpression);
expressions.Add (LexicalElements.RefType, Parse_ParenthesisScopedExpression);
expressions.Add (LexicalElements.RefValue, Parse_ParenthesisScopedExpression);
expressions.Add (LexicalElements.ArgList, Parse_ParenthesisScopedExpression);
}
public static void Parse (CSharpParsingState current)
{
if (current == null)
{
throw new ArgumentNullException ("current");
}
if (current.LexicalElement == LexicalElements.Symbol_ParenthesisClose)
{
return;
}
ParseMethod method;
if (!expressions.TryGetValue (current.LexicalElement, out method))
{
if (!Declarations.IsUnknown (current))
{
throw new ParseException ();
}
method = Parse_Unknown;
}
if (method == null)
{
ParseDefault (current);
return;
}
method (current);
switch (current.LexicalElement)
{
case LexicalElements.As:
case LexicalElements.Is:
current.MoveToNextExplicit ();
ReferencedType.Skip (current);
return;
case LexicalElements.Symbol_SquaredBracketOpen:
Parse_SquaredBracketOpen (current);
return;
case LexicalElements.Symbol_Comma:
case LexicalElements.Symbol_SemiColon:
case LexicalElements.Symbol_CurlyBracketClose:
case LexicalElements.Symbol_SquaredBracketClose:
case LexicalElements.Symbol_ParenthesisClose:
return;
}
if (current.IsLexicalElementMemberOf (LexicalElements.Group_Operators))
{
current.MoveToNextExplicit ();
Parse (current);
}
}
private static void ParseDefault (CSharpParsingState current)
{
current.MoveToNextExplicit ();
switch (current.LexicalElement)
{
case LexicalElements.Symbol_Comma:
case LexicalElements.Symbol_SemiColon:
case LexicalElements.Symbol_CurlyBracketClose:
case LexicalElements.Symbol_SquaredBracketClose:
case LexicalElements.Symbol_ParenthesisClose:
return;
default:
if (current.IsLexicalElementMemberOf (LexicalElements.Group_Operators))
{
current.MoveToNextExplicit ();
}
Parse (current);
return;
}
}
private static void Parse_ParenthesisScopedType (CSharpParsingState current)
{
current.MoveToNextExplicit ();
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisOpen);
current.MoveToNextExplicit ();
ReferencedType.Skip (current);
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisClose);
current.MoveToNextExplicit ();
}
private static void Parse_ParenthesisOpen (CSharpParsingState current)
{
current.StartScope (ScopeTypes.Parenthesis);
try
{
var afterParenthesisNode = current.PeekSkipOver (LexicalElements.Symbol_ParenthesisClose);
if (afterParenthesisNode != null)
{
switch (afterParenthesisNode.Token.LexicalElement)
{
case LexicalElements.Symbol_EqualsTo_AngledBracketClose:
Parse_LambdaParameters (current);
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisClose);
current.CommitScopeAndMoveToNext ();
current.IsLexicalElementExpected (LexicalElements.Symbol_EqualsTo_AngledBracketClose);
current.MoveToNextExplicit ();
Statements.Parse (current);
return;
case LexicalElements.Symbol_CurlyBracketOpen:
current.CommitScope ();
Type.ParseMethodParameters (current);
Statements.Parse_Scoped (current);
return;
}
}
current.MoveToNextExplicit ();
if (ReferencedType.Skip (current, false))
{
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisClose);
current.CommitScopeAndMoveToNext ();
Parse (current);
}
else
{
Parse (current);
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisClose);
current.CommitScopeAndMoveToNext ();
}
}
catch
{
current.RollbackScopeAndSkipOver (LexicalElements.Symbol_ParenthesisClose);
}
}
private static void Parse_StaticMethod (CSharpParsingState current)
{
current.MoveToNextExplicit ();
current.IsLexicalElementExpected (LexicalElements.Symbol_Dot);
current.MoveToNextExplicit ();
Declarations.ExpectedUnknown (current);
current.MoveToNextExplicit ();
ParseMethodCallArguments (current);
}
private static void Parse_StringValue (CSharpParsingState current)
{
current.SelectTokenUsingProcessorAndMoveToNext (ProcessorType.XmlFragment);
}
private static void Parse_Base (CSharpParsingState current)
{
current.MoveToNextExplicit ();
current.IsLexicalElementExpected (LexicalElements.Symbol_Dot);
current.MoveToNextExplicit ();
Declarations.ExpectedUnknown (current);
Parse_Unknown (current);
}
private static void Parse_This (CSharpParsingState current)
{
current.MoveToNextExplicit ();
if (current.LexicalElement == LexicalElements.Symbol_Dot)
{
current.MoveToNextExplicit ();
Declarations.ExpectedUnknown (current);
Parse_Unknown (current);
}
}
private static void Parse_New (CSharpParsingState current)
{
current.MoveToNextExplicit ();
if (Parse_NewArrayInitializer (current))
{
return;
}
ReferencedType.Skip (current);
if (Parse_NewArrayInitializer (current))
{
return;
}
switch (current.LexicalElement)
{
case LexicalElements.Symbol_ParenthesisOpen:
ParseMethodCallArguments (current);
return;
case LexicalElements.Symbol_SquaredBracketOpen:
Parse_SquaredBracketOpen (current);
return;
}
}
private static bool Parse_NewArrayInitializer (CSharpParsingState current)
{
if ((current.LexicalElement != LexicalElements.Symbol_SquaredBracketOpen) || (current.PeekLexicalElement (1) != LexicalElements.Symbol_SquaredBracketClose))
{
return false;
}
current.MoveToNextExplicit ();
current.MoveToNextExplicit ();
ParseCallArguments (current, LexicalElements.Symbol_CurlyBracketOpen, LexicalElements.Symbol_CurlyBracketClose);
return true;
}
private static void Parse_StackAlloc (CSharpParsingState current)
{
current.MoveToNextExplicit ();
ReferencedType.Skip (current);
}
private static void Parse_Unknown (CSharpParsingState current)
{
ReferencedType.Skip (current);
switch (current.LexicalElement)
{
case LexicalElements.Symbol_ParenthesisOpen:
ParseMethodCallArguments (current);
return;
case LexicalElements.Symbol_SquaredBracketOpen:
Parse_SquaredBracketOpen (current);
return;
}
}
private static void Parse_SquaredBracketOpen (CSharpParsingState current)
{
ParseCallArguments (current, LexicalElements.Symbol_SquaredBracketOpen, LexicalElements.Symbol_SquaredBracketClose);
}
private static void Parse_LambdaParameters (CSharpParsingState current)
{
current.StartScope (ScopeTypes.ParameterList);
try
{
current.MoveToNextExplicit ();
while (!current.HasReachedElementOrEndOfStream (LexicalElements.Symbol_ParenthesisClose))
{
Parse_LambdaParameter (current);
}
current.CommitScopeAndMoveToNext ();
}
catch
{
current.RollbackScopeAndSkipOver (LexicalElements.Symbol_ParenthesisClose);
}
}
private static void Parse_LambdaParameter (CSharpParsingState current)
{
current.StartScope (ScopeTypes.Parameter);
try
{
switch (current.LexicalElement)
{
case LexicalElements.Out:
case LexicalElements.Ref:
current.MoveToNextExplicit ();
break;
}
Declarations.ExpectedUnknown (current);
current.SelectTokenUsingProcessorAndMoveToNext (ProcessorType.DotNetNaming);
switch (current.LexicalElement)
{
case LexicalElements.Symbol_ParenthesisClose:
current.CommitScope ();
return;
case LexicalElements.Symbol_Comma:
current.CommitScopeAndMoveToNext ();
return;
}
}
catch
{
current.RollbackScope ();
throw;
}
}
private static void Parse_ParenthesisScopedExpression (CSharpParsingState current)
{
current.MoveToNextExplicit ();
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisOpen);
current.MoveToNextExplicit ();
Expressions.Parse (current);
current.IsLexicalElementExpected (LexicalElements.Symbol_ParenthesisClose);
current.MoveToNextExplicit ();
}
public static void ParseMethodCallArguments (CSharpParsingState current)
{
if (current == null)
{
throw new ArgumentNullException ("current");
}
ParseCallArguments (current, LexicalElements.Symbol_ParenthesisOpen, LexicalElements.Symbol_ParenthesisClose);
}
private static void ParseCallArguments (CSharpParsingState current, LexicalElements startElement, LexicalElements endElement)
{
current.IsLexicalElementExpected (startElement);
current.StartScope (ScopeTypes.CallArguments);
try
{
for (current.MoveToNextExplicit (); ; current.MoveToNextExplicit ())
{
if (Declarations.IsUnknown (current) && (current.PeekLexicalElement (1) == LexicalElements.Symbol_Colon))
{
current.MoveToNextExplicit ();
current.MoveToNextExplicit ();
}
Expressions.Parse (current);
if (current.LexicalElement == LexicalElements.Symbol_Comma)
{
continue;
}
if (current.LexicalElement == endElement)
{
current.CommitScopeAndMoveToNext ();
return;
}
else
{
throw new ParseException ();
}
}
}
catch
{
current.RollbackScopeAndSkipOver (endElement, LexicalElements.Symbol_SemiColon);
}
}
}
}
}
}