private Executable ParseBreak(TokenStream tokens, TopLevelConstruct owner) { Token breakToken = tokens.PopExpected(this.parser.Keywords.BREAK); tokens.PopExpected(";"); return(new BreakStatement(breakToken, owner)); }
// Generally this is used with the name resolver. So for example, you have a refernce to a ClassDefinition // instance from the resolver, but you want to turn it into a ClassReference instance. public static Expression ConvertStaticReferenceToExpression(TopLevelConstruct item, Token primaryToken, TopLevelConstruct owner) { if (item is Namespace) { return(new PartialNamespaceReference(primaryToken, ((Namespace)item).Name, owner)); } if (item is ClassDefinition) { return(new ClassReference(primaryToken, (ClassDefinition)item, owner)); } if (item is EnumDefinition) { return(new EnumReference(primaryToken, (EnumDefinition)item, owner)); } if (item is ConstStatement) { return(new ConstReference(primaryToken, (ConstStatement)item, owner)); } if (item is FunctionDefinition) { return(new FunctionReference(primaryToken, (FunctionDefinition)item, owner)); } throw new InvalidOperationException(); }
private Executable ParseContinue(TokenStream tokens, TopLevelConstruct owner) { Token continueToken = tokens.PopExpected(this.parser.Keywords.CONTINUE); tokens.PopExpected(";"); return(new ContinueStatement(continueToken, owner)); }
public void ParseInterpretedCode(string filename, string code) { FileScope fileScope = new FileScope(filename); int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList, filename); List <string> namespaceImportsBuilder = new List <string>(); tokens.InsertTokens(this.GetImplicitCoreImport()); if (this.CurrentLibrary != null && this.CurrentLibrary.CanonicalKey != "en:Core") { Library coreLibrary = this.LibraryManager.GetCoreLibrary(this); this.CurrentLibrary.AddLibraryDependency(coreLibrary); } List <CompilationScope> scopesAdded = new List <CompilationScope>(); while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT)) { ImportStatement importStatement = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); Library library = this.LibraryManager.ImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath); if (library == null) { this.unresolvedImports.Add(importStatement); } else { if (this.CurrentLibrary != null) { this.CurrentLibrary.AddLibraryDependency(library); } scopesAdded.Add(library.Scope); } } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { TopLevelConstruct executable = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope); if (executable is ImportStatement) { throw new ParserException( executable.FirstToken, this.CurrentLocale.Strings.Get("ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE")); } this.CurrentScope.AddExecutable(executable); } }
private ConstructorDefinition ParseConstructor( TokenStream tokens, TopLevelConstruct owner, AnnotationCollection annotations) { Token constructorToken = tokens.PopExpected(this.parser.Keywords.CONSTRUCTOR); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> argValues = new List <Expression>(); bool optionalArgFound = false; while (!tokens.PopIfPresent(")")) { if (argNames.Count > 0) { tokens.PopExpected(","); } Token argName = tokens.Pop(); this.parser.VerifyIdentifier(argName); Expression defaultValue = null; if (tokens.PopIfPresent("=")) { defaultValue = this.parser.ExpressionParser.Parse(tokens, owner); optionalArgFound = true; } else if (optionalArgFound) { throw this.parser.GenerateParseError( ErrorMessages.OPTIONAL_ARGUMENT_WAS_NOT_AT_END_OF_ARGUMENT_LIST, argName); } argNames.Add(argName); argValues.Add(defaultValue); } List <Expression> baseArgs = new List <Expression>(); Token baseToken = null; if (tokens.PopIfPresent(":")) { baseToken = tokens.PopExpected(this.parser.Keywords.BASE); tokens.PopExpected("("); while (!tokens.PopIfPresent(")")) { if (baseArgs.Count > 0) { tokens.PopExpected(","); } baseArgs.Add(this.parser.ExpressionParser.Parse(tokens, owner)); } } IList <Executable> code = ParserContext.ParseBlock(parser, tokens, true, owner); return(new ConstructorDefinition(constructorToken, argNames, argValues, baseArgs, code, baseToken, annotations, owner)); }
private Executable ParseThrow(TokenStream tokens, TopLevelConstruct owner) { Token throwToken = tokens.PopExpected(this.parser.Keywords.THROW); Expression throwExpression = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(";"); return(new ThrowStatement(throwToken, throwExpression, owner)); }
private Executable ParseFor(TokenStream tokens, TopLevelConstruct owner) { Token forToken = tokens.PopExpected(this.parser.Keywords.FOR); tokens.PopExpected("("); if (!tokens.HasMore) { tokens.ThrowEofException(); } if (this.parser.IsValidIdentifier(tokens.PeekValue()) && tokens.PeekValue(1) == ":") { Token iteratorToken = tokens.Pop(); if (this.parser.IsReservedKeyword(iteratorToken.Value)) { throw new ParserException(iteratorToken, "Cannot use this name for an iterator."); } tokens.PopExpected(":"); Expression iterationExpression = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(")"); IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner); return(new ForEachLoop(forToken, iteratorToken, iterationExpression, body, owner)); } else { List <Executable> init = new List <Executable>(); while (!tokens.PopIfPresent(";")) { if (init.Count > 0) { tokens.PopExpected(","); } init.Add(this.Parse(tokens, true, false, owner)); } Expression condition = null; if (!tokens.PopIfPresent(";")) { condition = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(";"); } List <Executable> step = new List <Executable>(); while (!tokens.PopIfPresent(")")) { if (step.Count > 0) { tokens.PopExpected(","); } step.Add(this.Parse(tokens, true, false, owner)); } IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner); return(new ForLoop(forToken, init, condition, step, body, owner)); } }
private FunctionDefinition ParseFunction( TokenStream tokens, TopLevelConstruct nullableOwner, FileScope fileScope, AnnotationCollection annotations) { bool isStatic = nullableOwner != null && nullableOwner is ClassDefinition && tokens.PopIfPresent(this.parser.Keywords.STATIC); Token functionToken = tokens.PopExpected(this.parser.Keywords.FUNCTION); Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(functionToken, parser.CurrentLibrary, nullableOwner, isStatic, functionNameToken, annotations, fileScope); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); bool optionalArgFound = false; while (!tokens.PopIfPresent(")")) { if (argNames.Count > 0) { tokens.PopExpected(","); } Token argName = tokens.Pop(); Expression defaultValue = null; this.parser.VerifyIdentifier(argName); if (tokens.PopIfPresent("=")) { optionalArgFound = true; defaultValue = this.parser.ExpressionParser.Parse(tokens, fd); } else if (optionalArgFound) { throw new ParserException(argName, "All optional arguments must come at the end of the argument list."); } argNames.Add(argName); defaultValues.Add(defaultValue); } IList <Executable> code = ParserContext.ParseBlock(parser, tokens, true, fd); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.Code = code.ToArray(); return(fd); }
private ConstructorDefinition ParseConstructor(TokenStream tokens, TopLevelConstruct owner) { Token constructorToken = tokens.PopExpected(this.parser.Keywords.CONSTRUCTOR); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> argValues = new List <Expression>(); bool optionalArgFound = false; while (!tokens.PopIfPresent(")")) { if (argNames.Count > 0) { tokens.PopExpected(","); } Token argName = tokens.Pop(); this.parser.VerifyIdentifier(argName); Expression defaultValue = null; if (tokens.PopIfPresent("=")) { defaultValue = this.parser.ExpressionParser.Parse(tokens, owner); optionalArgFound = true; } else if (optionalArgFound) { throw new ParserException(argName, "All optional arguments must come at the end of the argument list."); } argNames.Add(argName); argValues.Add(defaultValue); } List <Expression> baseArgs = new List <Expression>(); Token baseToken = null; if (tokens.PopIfPresent(":")) { baseToken = tokens.PopExpected(this.parser.Keywords.BASE); tokens.PopExpected("("); while (!tokens.PopIfPresent(")")) { if (baseArgs.Count > 0) { tokens.PopExpected(","); } baseArgs.Add(this.parser.ExpressionParser.Parse(tokens, owner)); } } IList <Executable> code = Parser.ParseBlock(parser, tokens, true, owner); return(new ConstructorDefinition(constructorToken, argNames, argValues, baseArgs, code, baseToken, owner)); }
private Expression ParseNullCoalescing(TokenStream tokens, TopLevelConstruct owner) { Expression root = ParseBooleanCombination(tokens, owner); if (tokens.PopIfPresent("??")) { Expression secondaryExpression = ParseNullCoalescing(tokens, owner); return(new NullCoalescer(root, secondaryExpression, owner)); } return(root); }
private Namespace ParseNamespace(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { Token namespaceToken = tokens.PopExpected(this.parser.Keywords.NAMESPACE); Token first = tokens.Pop(); this.parser.VerifyIdentifier(first); List <Token> namespacePieces = new List <Token>() { first }; string namespaceBuilder = first.Value; parser.RegisterNamespace(namespaceBuilder); while (tokens.PopIfPresent(".")) { Token nsToken = tokens.Pop(); this.parser.VerifyIdentifier(nsToken); namespacePieces.Add(nsToken); namespaceBuilder += "." + nsToken.Value; parser.RegisterNamespace(namespaceBuilder); } string name = string.Join(".", namespacePieces.Select <Token, string>(t => t.Value)); parser.PushNamespacePrefix(name); Namespace namespaceInstance = new Namespace(namespaceToken, name, owner, parser.CurrentLibrary, fileScope); tokens.PopExpected("{"); List <TopLevelConstruct> namespaceMembers = new List <TopLevelConstruct>(); while (!tokens.PopIfPresent("}")) { TopLevelConstruct executable = this.parser.ExecutableParser.ParseTopLevel(tokens, namespaceInstance, fileScope); if (executable is FunctionDefinition || executable is ClassDefinition || executable is EnumDefinition || executable is ConstStatement || executable is Namespace) { namespaceMembers.Add(executable); } else { throw new ParserException(executable.FirstToken, "Only function, class, and nested namespace declarations may exist as direct members of a namespace."); } } namespaceInstance.Code = namespaceMembers.ToArray(); parser.PopNamespacePrefix(); return(namespaceInstance); }
public void AddExecutable(TopLevelConstruct executable) { if (executable is Namespace) { ((Namespace)executable).GetFlattenedCode(this.executables); } else { this.executables.Add(executable); } }
// Note: wraapping namespaces is a list of the namespace chains in a popped order... // namespace MyNamespace.Foo.Bar.Baz { ... } will result in... // ["MyNamespace.Foo.Bar.Baz", "MyNamespace.Foo.Bar", "MyNamespace.Foo", "MyNamespace"] public object DoLookupImpl( string name, TopLevelConstruct currentEntity) { // check for that entity in the current compilation scope, if (scopeLookup.ContainsKey(name)) { return(scopeLookup[name]); } // check for that entity in another compilation scope if (depsLookup.ContainsKey(name)) { return(depsLookup[name]); } string[] wrappingNamespaces = currentEntity.GetWrappingNamespaceIncrements(this.fileScope.CompilationScope.Locale); // if there's a namespace or series of namespaces, check if it's in that fully-specified namespace if (wrappingNamespaces.Length > 0) { string fullyQualified = wrappingNamespaces[0] + "." + name; if (scopeLookup.ContainsKey(fullyQualified)) { return(scopeLookup[fullyQualified]); } } // Go through all the imports and check to see if any of them fully qualify it as a prefix. for (int i = 0; i < this.importStatements.Length; ++i) { string fullyQualified = this.importStatements[i] + "." + name; if (scopeLookup.ContainsKey(fullyQualified)) { return(scopeLookup[fullyQualified]); } if (depsLookup.ContainsKey(fullyQualified)) { return(depsLookup[fullyQualified]); } } // Now go back through the wrapping namespaces and check each fragment in decreasing order. for (int i = 1; i < wrappingNamespaces.Length; ++i) { string fullyQualified = wrappingNamespaces[i] + "." + name; if (scopeLookup.ContainsKey(fullyQualified)) { return(scopeLookup[fullyQualified]); } } return(null); }
private Executable ParseWhile(TokenStream tokens, TopLevelConstruct owner) { Token whileToken = tokens.PopExpected(this.parser.Keywords.WHILE); tokens.PopExpected("("); Expression condition = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(")"); IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner); return(new WhileLoop(whileToken, condition, body, owner)); }
private Expression ParseBitShift(TokenStream tokens, TopLevelConstruct owner) { Expression expr = ParseAddition(tokens, owner); string next = tokens.PeekValue(); if (next == "<<" || next == ">>") { Token opToken = tokens.Pop(); Expression rightExpr = ParseBitShift(tokens, owner); return(new BinaryOpChain(expr, opToken, rightExpr, owner)); } return(expr); }
private Expression ParseExponents(TokenStream tokens, TopLevelConstruct owner) { Expression expr = ParseIncrement(tokens, owner); string next = tokens.PeekValue(); if (next == "**") { Token op = tokens.Pop(); Expression right = ParseNegate(tokens, owner); expr = new BinaryOpChain(expr, op, right, owner); } return(expr); }
private Expression ParseEqualityComparison(TokenStream tokens, TopLevelConstruct owner) { Expression expr = ParseInequalityComparison(tokens, owner); string next = tokens.PeekValue(); if (next == "==" || next == "!=") { Token equalityToken = tokens.Pop(); Expression rightExpr = ParseEqualityComparison(tokens, owner); return(new BinaryOpChain(expr, equalityToken, rightExpr, owner)); } return(expr); }
private Executable ParseReturn(TokenStream tokens, TopLevelConstruct owner) { Token returnToken = tokens.PopExpected(this.parser.Keywords.RETURN); Expression expr = null; if (!tokens.PopIfPresent(";")) { expr = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(";"); } return(new ReturnStatement(returnToken, expr, owner)); }
private Executable ParseDoWhile(TokenStream tokens, TopLevelConstruct owner) { Token doToken = tokens.PopExpected(this.parser.Keywords.DO); IList <Executable> body = Parser.ParseBlock(parser, tokens, true, owner); tokens.PopExpected(this.parser.Keywords.DO_WHILE_END); tokens.PopExpected("("); Expression condition = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(")"); tokens.PopExpected(";"); return(new DoWhileLoop(doToken, body, condition, owner)); }
private ConstStatement ParseConst(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope) { Token constToken = tokens.PopExpected(this.parser.Keywords.CONST); Token nameToken = tokens.Pop(); ConstStatement constStatement = new ConstStatement(constToken, nameToken, parser.CurrentNamespace, owner, parser.CurrentLibrary, fileScope); this.parser.VerifyIdentifier(nameToken); tokens.PopExpected("="); constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement); tokens.PopExpected(";"); return(constStatement); }
private Expression ParseMultiplication(TokenStream tokens, TopLevelConstruct owner) { Expression expr = ParseNegate(tokens, owner); string next = tokens.PeekValue(); while (MULTIPLICATION_OPS.Contains(next)) { Token op = tokens.Pop(); Expression right = ParseNegate(tokens, owner); expr = new BinaryOpChain(expr, op, right, owner); next = tokens.PeekValue(); } return(expr); }
private Expression ParseTernary(TokenStream tokens, TopLevelConstruct owner) { Expression root = ParseNullCoalescing(tokens, owner); if (tokens.PopIfPresent("?")) { Expression trueExpr = ParseTernary(tokens, owner); tokens.PopExpected(":"); Expression falseExpr = ParseTernary(tokens, owner); return(new Ternary(root, trueExpr, falseExpr, owner)); } return(root); }
private Expression ParseInequalityComparison(TokenStream tokens, TopLevelConstruct owner) { Expression expr = ParseBitShift(tokens, owner); string next = tokens.PeekValue(); if (next == "<" || next == ">" || next == "<=" || next == ">=") { // Don't allow chaining of inqeualities Token opToken = tokens.Pop(); Expression rightExpr = ParseBitShift(tokens, owner); return(new BinaryOpChain(expr, opToken, rightExpr, owner)); } return(expr); }
public void ParseInterpretedCode(string filename, string code) { FileScope fileScope = new FileScope(filename, this.CurrentScope); int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList, filename); List <string> namespaceImportsBuilder = new List <string>(); // Implicitly import the Core library for the current locale. LocalizedLibraryView implicitCoreImport = this.LibraryManager.GetCoreLibrary(this); namespaceImportsBuilder.Add(implicitCoreImport.Name); fileScope.Imports.Add(new ImportStatement(null, implicitCoreImport.Name, this.CurrentLibrary, fileScope)); while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT)) { ImportStatement importStatement = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); LocalizedLibraryView localizedLibraryView = this.LibraryManager.GetOrImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath); if (localizedLibraryView == null) { this.unresolvedImports.Add(importStatement); } } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { TopLevelConstruct executable = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope); if (executable is ImportStatement) { throw this.GenerateParseError( ErrorMessages.ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE, executable.FirstToken); } this.CurrentScope.AddExecutable(executable); } }
public void AddExecutable(TopLevelConstruct executable) { if (executable is Namespace) { Namespace ns = (Namespace)executable; this.namespaceFlattener.AddNamespace(ns); foreach (TopLevelConstruct tlc in ns.Code) { this.AddExecutable(tlc); } } else { this.executables.Add(executable); } }
public Expression Parse(TokenStream tokens, TopLevelConstruct owner) { Dictionary <string, Annotation> annotations = null; if (tokens.IsNext("@")) { annotations = new Dictionary <string, Annotation>(); while (tokens.IsNext("@")) { Annotation annotation = this.parser.AnnotationParser.ParseAnnotation(tokens); annotations[annotation.Type] = annotation; } } Expression output = ParseTernary(tokens, owner); output.Annotations = annotations; return(output); }
private Expression ParseIncrement(TokenStream tokens, TopLevelConstruct owner) { Expression root; if (tokens.IsNext("++") || tokens.IsNext("--")) { Token incrementToken = tokens.Pop(); root = this.ParseEntity(tokens, owner); return(new Increment(incrementToken, incrementToken, incrementToken.Value == "++", true, root, owner)); } root = this.ParseEntity(tokens, owner); if (tokens.IsNext("++") || tokens.IsNext("--")) { Token incrementToken = tokens.Pop(); return(new Increment(root.FirstToken, incrementToken, incrementToken.Value == "++", false, root, owner)); } return(root); }
private Expression ParseInstantiate(TokenStream tokens, TopLevelConstruct owner) { Token newToken = tokens.PopExpected(this.parser.Keywords.NEW); Token classNameToken = tokens.Pop(); string name = this.parser.PopClassNameWithFirstTokenAlreadyPopped(tokens, classNameToken); List <Expression> args = new List <Expression>(); tokens.PopExpected("("); while (!tokens.PopIfPresent(")")) { if (args.Count > 0) { tokens.PopExpected(","); } args.Add(Parse(tokens, owner)); } return(new Instantiate(newToken, classNameToken, name, args, owner)); }
private Expression ParseNegate(TokenStream tokens, TopLevelConstruct owner) { string next = tokens.PeekValue(); if (NEGATE_OPS.Contains(next)) { Token negateOp = tokens.Pop(); Expression root = ParseNegate(tokens, owner); if (negateOp.Value == "!") { return(new BooleanNot(negateOp, root, owner)); } if (negateOp.Value == "-") { return(new NegativeSign(negateOp, root, owner)); } throw new Exception("This shouldn't happen."); } return(ParseExponents(tokens, owner)); }
private Executable ParseIf(TokenStream tokens, TopLevelConstruct owner) { Token ifToken = tokens.PopExpected(this.parser.Keywords.IF); tokens.PopExpected("("); Expression condition = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(")"); IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner); IList <Executable> elseBody; if (tokens.PopIfPresent(this.parser.Keywords.ELSE)) { elseBody = Parser.ParseBlock(parser, tokens, false, owner); } else { elseBody = new Executable[0]; } return(new IfStatement(ifToken, condition, body, elseBody, owner)); }