private static bool CheckField( Core.Session session, int structIndex, int fieldIndex, Core.Type innerType, Stack<int> seenStructs) { var fieldStruct = innerType as Core.TypeStruct; if (fieldStruct == null) return false; var st = session.GetStruct(structIndex); Core.Name fieldName; st.fieldNames.FindByValue(fieldIndex, out fieldName); session.PushContext( "in struct '" + session.GetStructName(structIndex).GetString() + "', " + "field '" + fieldName.GetString() + "'", st.GetFieldNameSpan(fieldIndex)); var err = false; if (seenStructs.Contains(fieldStruct.structIndex)) { err = true; session.AddMessage( Diagnostics.MessageKind.Error, Diagnostics.MessageCode.StructRecursion, "struct recursion", session.GetStruct(fieldStruct.structIndex).GetNameSpan(), st.GetFieldNameSpan(fieldIndex)); } if (!err) CheckStruct(session, fieldStruct.structIndex, seenStructs); session.PopContext(); return err; }
public static TokenCollection Tokenize(Core.Session session, Core.TextInput input) { var output = new TokenCollection(); // Iterate through all characters in input. var index = 0; while (index < input.Length()) { // Skip whitespace. if (IsWhitespace(input[index])) { index++; continue; } // Match next characters to a token, and add it to the output. var match = TryMatchModelToken(input, index) ?? TryMatchVaryingToken(input, index) ?? new TokenMatch(new string(input[index], 1), TokenKind.Error); var span = new Span(input, index, index + match.representation.Length); // Signal errors. if (match.kind == TokenKind.Error) { session.AddMessage(MessageKind.Error, MessageCode.UnexpectedChar, "unexpected character", span); } // Skip line comments. else if (match.kind == TokenKind.DoubleSlash) { while (index < input.Length() && input[index] != '\n') index++; continue; } // Skip multiline comments. else if (match.kind == TokenKind.SlashAsterisk) { var nesting = 1; index += 2; while (index < input.Length() - 1) { if (input[index] == '*' && input[index + 1] == '/') { nesting--; index += 2; if (nesting == 0) break; } else if (input[index] == '/' && input[index + 1] == '*') { nesting++; index += 2; } else index++; } if (nesting > 0) session.AddMessage(MessageKind.Error, MessageCode.UnexpectedChar, "unterminated comment", span); continue; } output.tokens.Add(new Token(match.kind, span)); index += match.representation.Length; } output.tokenAfterEnd = new Token(TokenKind.Error, new Diagnostics.Span(input, index, index)); return output; }
public static Core.Type ResolveStruct( Core.Session session, Grammar.ASTNodeExprName nameNode, IList<Core.UseDirective> useDirectives, bool mustBeResolved) { var nameConcreteNode = nameNode as Grammar.ASTNodeExprNameConcrete; if (nameConcreteNode == null) { if (mustBeResolved) { session.AddMessage( Diagnostics.MessageKind.Error, Diagnostics.MessageCode.Expected, "type must be known", nameNode.GetSpan()); } return new Core.TypeError(); } return ResolveStruct(session, nameConcreteNode.name, useDirectives, mustBeResolved); }
public static bool ValidateDataAccess( Core.Session session, Core.DeclFunct funct, Core.DataAccess access) { var regDeref = access as Core.DataAccessDereference; if (regDeref != null) { var innerType = GetDataAccessType(session, funct, regDeref.innerAccess); var innerPtr = innerType as Core.TypePointer; if (innerPtr == null) { session.AddMessage( Diagnostics.MessageKind.Error, Diagnostics.MessageCode.CannotDereferenceType, "dereferencing '" + innerType.GetString(session) + "'", access.span); return false; } } return true; }
public static Core.Type Resolve( Core.Session session, Grammar.ASTNodeType typeNode, IList<Core.UseDirective> useDirectives, bool mustBeResolved) { var typePlaceholderNode = typeNode as Grammar.ASTNodeTypePlaceholder; if (typePlaceholderNode != null) { if (mustBeResolved) { session.AddMessage( Diagnostics.MessageKind.Error, Diagnostics.MessageCode.Expected, "type must be known", typeNode.GetSpan()); return new Core.TypeError(); } return new Core.TypePlaceholder(); } var typeStructNode = typeNode as Grammar.ASTNodeTypeStruct; if (typeStructNode != null) { return ResolveStruct(session, typeStructNode.name, useDirectives, mustBeResolved); } var typeTupleNode = typeNode as Grammar.ASTNodeTypeTuple; if (typeTupleNode != null) { var elementTypes = new Core.Type[typeTupleNode.elements.Count]; for (var i = 0; i < typeTupleNode.elements.Count; i++) elementTypes[i] = Resolve(session, typeTupleNode.elements[i], useDirectives, mustBeResolved); return Core.TypeTuple.Of(elementTypes); } var typeFunctNode = typeNode as Grammar.ASTNodeTypeFunct; if (typeFunctNode != null) { var returnType = Resolve(session, typeFunctNode.returnType, useDirectives, mustBeResolved); var parameterTypes = new Core.Type[typeFunctNode.parameters.Count]; for (var i = 0; i < typeFunctNode.parameters.Count; i++) parameterTypes[i] = Resolve(session, typeFunctNode.parameters[i], useDirectives, mustBeResolved); return Core.TypeFunct.Of(returnType, parameterTypes); } var typeRefNode = typeNode as Grammar.ASTNodeTypePointer; if (typeRefNode != null) { return Core.TypePointer.Of( typeRefNode.mutable, Resolve(session, typeRefNode.referenced, useDirectives, mustBeResolved)); } throw new System.NotImplementedException(); }