private static int CountCommas(LexList list, int rank, bool arrayIndexActualsAllowed) { Stack <string> stack = new Stack <string>(); if (arrayIndexActualsAllowed) { int saveIndex = list.Index - 1; bool finished = false; while (!list.AtEnd() && !finished) { switch (list.Str) { case ",": if (stack.Count == 0) { rank++; } break; case "(": stack.Push(")"); break; case "{": stack.Push("}"); break; case "[": stack.Push("]"); break; case ")": case "}": if (stack.Pop() != list.Str) { list.ThrowException("Unbalanced brackets in array initialiser"); } break; case "]": if (stack.Count == 0) { list.Prev(); finished = true; } else { if (stack.Pop() != list.Str) { list.ThrowException("Unbalanced brackets in array initialiser"); } } break; } list.Next(); } list.Index = saveIndex; } else { while (list.Str == ",") { list.Next(); rank++; } } return(rank); }
public void CheckArithmetical(ExpState state) { if (state == null) { if ((List.Str == "-" || List.Str == "+") && List.Prev().Str == List.Str) { List.ThrowException("Sorry, " + List.Str + List.Str + " is not implemented."); } List.ThrowException("Missing operand here."); } if (state.ResultType == typeof(char) && (StartType == typeof(int) || StartType == typeof(long))) { return; } if (state.ResultType == typeof(bool) && ((Sizes & OperandSizes.Bool) == OperandSizes.Bool)) { return; } if ((state.ResultType == typeof(int) || state.ResultType == typeof(long)) && ((Sizes & OperandSizes.Integer) == OperandSizes.Integer)) { return; } if ((state.ResultType == typeof(float) || state.ResultType == typeof(double)) && ((Sizes & OperandSizes.Real) == OperandSizes.Real)) { return; } string s = ""; if (((Sizes & OperandSizes.Bool) == OperandSizes.Bool)) { s += "bool "; } if (((Sizes & OperandSizes.Integer) == OperandSizes.Integer)) { if (s != "") { s += "or "; } s += "integer "; } if (((Sizes & OperandSizes.Real) == OperandSizes.Real)) { if (s != "") { s += "or "; } s += "real "; } List.ThrowException("Expected an operand of type '" + s + "'."); }
// Syntax: // Member = '.' StaticMember . public ExpState ParseMember(Type theClass, LexList list, BindingFlags flags, bool implicitDot) { if (!implicitDot) { list.CheckStrAndAdvance(".", "Expected a dot followed by a static member name here."); } LexToken token = list.CurrentToken(); string name = list.GetIdentifier("Expected the name of a static member here."); FieldInfo fi = theClass.GetField(name, flags); if (fi != null) { return(new ExpState(fi)); } list.Prev(); return(null); }
private Type ParseArrayTypeModifier(LexList list, Type returnType, bool arrayIndexActualsAllowed) { if (list.Str == "[") { list.Next(); if (list.Kind == LexKind.End) { list.ThrowException("Unexpected end of input."); } if (!arrayIndexActualsAllowed) { if (list.Str != "]") { list.ThrowException("Expected a ']' here."); } list.Next(); } Type arrayType = returnType.MakeArrayType(); while (list.Str == "[") { list.Next(); arrayType = arrayType.MakeArrayType(); if (list.Str != "]") { list.ThrowException("Expected a ']' here"); } list.Next(); } if (arrayIndexActualsAllowed) { list.Prev(); } return(arrayType); } else { return(returnType); } }
// Syntax: // Type = TypeNonArray [ TypeArrayPart ] . // TypeNonArray = TypeIdAndGenerics *( '.' TypeIdAndGenerics ) . // TypeIdAndGenerics = TypeIdentifier [ Generics ] . // Generics = '<' Type *( ',' Type ) '>' . // TypeArrayPart = '[' ']' *( '[' ']' ) . public Type Parse(LexList list, bool typeOnly, bool arrayIndexActualsAllowed, out bool pendingCloseAngle, BindingFlags visibility) { string id = ""; Type returnType = null; int checkPoint = list.Index; pendingCloseAngle = false; while (true) { if (list.Kind == LexKind.Type) { returnType = list.CurrentToken().ActualObject as Type; list.Next(); return(returnType); } if (list.Kind != LexKind.Identifier) { if (typeOnly) { list.ThrowException("Unable to convert this to a type."); } return(returnType); } if (id != "") { id += "."; } id += list.GetIdentifier(); Type ty = null; if (list.Str != "<" || !IsGenericSpec(list)) { ty = FindTypeFromDottedIds(returnType, id, visibility); } if (ty != null) { id = ""; returnType = ty; checkPoint = list.Index; if (list.Kind == LexKind.End) { return(returnType); } if (list.Str != ".") { return(ParseArrayTypeModifier(list, returnType, arrayIndexActualsAllowed)); } } else if (ty == null && list.Str == "<" && IsGenericSpec(list)) { // The test for the GenericSpec is needed to separate out comparision '<' or shift '<' from generic brackets. int save = list.Index; Type[] types = ParseGenericTypeModifier(list, out pendingCloseAngle, visibility); id += "`" + types.Length.ToString(); ty = FindTypeFromDottedIds(returnType, id, visibility); if (ty != null) { ty = ty.MakeGenericType(types.ToArray()); } if (ty == null) { if (typeOnly) { list[save].ThrowException("Unable to resolve generic type.", list); } list.Index = checkPoint; return(returnType); } return(ParseArrayTypeModifier(list, ty, arrayIndexActualsAllowed)); } else { if (list.Str != ".") { if (typeOnly) { list.Prev(); list.ThrowException("Unable to convert this to a type."); } list.Index = checkPoint; return(returnType); } } list.Next(); // skips over the '.' } }