Beispiel #1
0
        public SourceUnitTree Parse(SourceUnit /*!*/ sourceUnit, RubyCompilerOptions /*!*/ options, ErrorSink /*!*/ errorSink)
        {
            Assert.NotNull(sourceUnit, options, errorSink);

            ErrorCounter counter = new ErrorCounter(errorSink);

            _tokenizer.ErrorSink     = counter;
            _tokenizer.Compatibility = options.Compatibility;

            _lexicalScopes.Clear();

            EnterScope(CreateTopScope(options.LocalNames));

            using (SourceCodeReader reader = sourceUnit.GetReader()) {
                _sourceUnit = sourceUnit;
                _tokenizer.Initialize(null, reader, sourceUnit, options.InitialLocation);

                // Default encoding when hosted (ignore KCODE, we are reading from Unicode buffer):
                _tokenizer.Encoding = (reader.Encoding != null) ? RubyEncoding.GetRubyEncoding(reader.Encoding) : RubyEncoding.UTF8;
                _tokenizer.AllowNonAsciiIdentifiers = _tokenizer.Encoding != RubyEncoding.Binary;

                try {
                    Parse();
                    LeaveScope();
                } catch (InternalSyntaxError) {
                    _ast = null;
                    _lexicalScopes.Clear();
                } finally {
                    ScriptCodeParseResult props;
                    if (counter.AnyError)
                    {
                        _ast = null;

                        if (_tokenizer.UnterminatedToken)
                        {
                            props = ScriptCodeParseResult.IncompleteToken;
                        }
                        else if (_tokenizer.EndOfFileReached)
                        {
                            props = ScriptCodeParseResult.IncompleteStatement;
                        }
                        else
                        {
                            props = ScriptCodeParseResult.Invalid;
                        }
                    }
                    else
                    {
                        props = ScriptCodeParseResult.Complete;
                    }

                    sourceUnit.CodeProperties = props;
                }

                return(_ast);
            }
        }
Beispiel #2
0
        public SourceUnitTree Parse(SourceUnit /*!*/ sourceUnit, RubyCompilerOptions /*!*/ options, ErrorSink /*!*/ errorSink)
        {
            Assert.NotNull(sourceUnit, options, errorSink);

            ErrorCounter counter = new ErrorCounter(errorSink);

            _tokenizer.ErrorSink     = counter;
            _tokenizer.Compatibility = options.Compatibility;

            _lexicalScopes.Clear();

            EnterScope(CreateTopScope(options.LocalNames));

            using (SourceCodeReader reader = sourceUnit.GetReader()) {
                _sourceUnit = sourceUnit;
                _tokenizer.Initialize(null, reader, sourceUnit, options.InitialLocation);

                // default encoding when hosted:
                _encoding = reader.Encoding ?? RubyEncoding.GetDefaultHostEncoding(options.Compatibility);

                try {
                    Parse();
                    LeaveScope();
                } catch (InternalSyntaxError) {
                    _ast = null;
                    _lexicalScopes.Clear();
                } finally {
                    ScriptCodeParseResult props;
                    if (counter.AnyError)
                    {
                        _ast = null;

                        if (_tokenizer.UnterminatedToken)
                        {
                            props = ScriptCodeParseResult.IncompleteToken;
                        }
                        else if (_tokenizer.IsEndOfFile)
                        {
                            props = ScriptCodeParseResult.IncompleteStatement;
                        }
                        else
                        {
                            props = ScriptCodeParseResult.Invalid;
                        }
                    }
                    else
                    {
                        props = ScriptCodeParseResult.Complete;
                    }

                    sourceUnit.CodeProperties = props;
                }

                return(_ast);
            }
        }
Beispiel #3
0
		public SourceUnitTree CreateAst(string fileName, ITextBuffer fileContent)
		{
			if (scriptEngine == null) {
				scriptEngine = Ruby.CreateEngine();
			}
			
			RubyContext rubyContext = HostingHelpers.GetLanguageContext(scriptEngine) as RubyContext;
			sourceUnit = rubyContext.CreateFileUnit(fileName, fileContent.Text);
			RubyCompilerSink sink = new RubyCompilerSink();
			RubyCompilerOptions compilerOptions = new RubyCompilerOptions((RubyOptions)rubyContext.Options);
			Parser parser = new Parser();
			return parser.Parse(sourceUnit, compilerOptions, sink);
		}
Beispiel #4
0
        private void ParserLoggingTest() {
#if DEBUG
            string source = "def foo(a); end";
            var sourceUnit = Context.CreateSnippet(source, SourceCodeKind.Statements);
            var options = new RubyCompilerOptions();

            string temp = Path.Combine(Path.GetTempPath(), "RubyParser");
            Console.WriteLine("> see {0}", temp);
            Directory.CreateDirectory(temp);

            Parser parser = new Parser();
            using (TextWriter writer = File.CreateText(Path.Combine(temp, "default.log"))) {
                DefaultParserLogger.Attach(parser, writer);
                parser.Parse(sourceUnit, options, ErrorSink.Null);
            }

            using (TextWriter writer = File.CreateText(Path.Combine(temp, "tables.csv"))) {
                parser.DumpTables(writer);
            }

            using (TextWriter writer = File.CreateText(Path.Combine(temp, "productions.txt"))) {
                for (int i = 0; i < parser.Rules.Length; i++) {
                    writer.WriteLine("{0}\t{1}", i, parser.RuleToString(i));
                }
            }

            parser = new Parser();
            using (TextWriter writer = File.CreateText(Path.Combine(temp, "productions.txt"))) {
                for (int i = 0; i < parser.Rules.Length; i++) {
                    writer.WriteLine("{0}\t{1}", i, parser.RuleToString(i));
                }
            }

            using (TextWriter writer = File.CreateText(Path.Combine(temp, "second_order.log"))) {
                parser.EnableLogging(new CoverageParserLogger(parser, writer));
                parser.Parse(sourceUnit, options, ErrorSink.Null);
            }
#endif
        }
Beispiel #5
0
        private void ExecuteRubySourceUnit(SourceUnit/*!*/ sourceUnit, Scope/*!*/ globalScope, LoadFlags flags) {
            Assert.NotNull(sourceUnit, globalScope);
            
            // TODO: check file timestamp
            string fullPath = Platform.GetFullPath(sourceUnit.Path);
            CompiledFile compiledFile;
            if (TryGetCompiledFile(fullPath, out compiledFile)) {
                Utils.Log(String.Format("{0}: {1}", ++_cacheHitCount, sourceUnit.Path), "LOAD_CACHED");
                compiledFile.CompiledCode.Run(globalScope);
            } else {
                Utils.Log(String.Format("{0}: {1}", ++_compiledFileCount, sourceUnit.Path), "LOAD_COMPILED");

                RubyCompilerOptions options = new RubyCompilerOptions(_context.RubyOptions) {
                    IsIncluded = true,
                    IsWrapped = (flags & LoadFlags.LoadIsolated) != 0,
                };

                long ts1 = Stopwatch.GetTimestamp();
                ScriptCode compiledCode = sourceUnit.Compile(options, _context.RuntimeErrorSink);
                long ts2 = Stopwatch.GetTimestamp();
                Interlocked.Add(ref _ScriptCodeGenerationTimeTicks, ts2 - ts1);

                AddCompiledFile(fullPath, compiledCode);

                CompileAndRun(globalScope, compiledCode, _context.Options.InterpretedMode);
            }
        }
Beispiel #6
0
        private void AstLocations1() {
            // DumpExpression uses private reflection:
            if (_driver.PartialTrust) return;

            var sourceUnit = Context.CreateSnippet(@"
def add a,b
  a + b
end

add 1, 1
add 'foo', 'bar'
", SourceCodeKind.Expression);

            var options = new RubyCompilerOptions();
            var parser = new Parser();
            var tokens = new List<KeyValuePair<SourceSpan, Tokens>>();

            parser.TokenSink = (token, span) => { tokens.Add(new KeyValuePair<SourceSpan, Tokens>(span, token)); };
            var ast = parser.Parse(sourceUnit, options, Context.RuntimeErrorSink);

            const int Id = 0x12345678;

            var lambda = CallSiteTracer.Transform<Func<Scope, LanguageContext, object>>(ast, sourceUnit, options, Id);
            var code = new RubyScriptCode(lambda, sourceUnit);

            var locations = new List<int>();
            CallSiteTracer.Register((context, args, result, id, location) => {
                locations.Add(location);
                Debug.Assert(id == Id);
                Debug.Assert(location > 0);

                //Console.WriteLine("-- {0} ---------", location);
                //Console.WriteLine(this);
                //Console.WriteLine(AstUtils.DumpExpression(result.Restrictions.ToExpression()));
                //Console.WriteLine();
                //Console.WriteLine(AstUtils.DumpExpression(result.Expression));
                //Console.WriteLine("----------------");
            });

            code.Run();

            Debug.Assert(locations.Count == 4 && locations[0] == 31 && locations[1] == 19 && locations[2] == 41 && locations[3] == 19);
        }
        private void Benchmark(List<string>/*!*/ files) {
            
            var sources = new List<SourceUnit>();
            Stopwatch readTime = new Stopwatch();
            long totalSize = 0;
            readTime.Start();
            foreach (string path in files) {
                try {
                    byte[] data = File.ReadAllBytes(path);
                    sources.Add(_context.CreateSourceUnit(new BinaryContentProvider(data), path, Encoding.Default, SourceCodeKind.File));
                    totalSize += data.Length;
                } catch (Exception) {
                    Console.WriteLine("Error: {0}", path);
                }
            }
            readTime.Stop();

            Console.WriteLine("Read: {0} kB in {1}", totalSize / 1024, readTime.Elapsed);
            
#if F
            Stopwatch tokenizeTime = new Stopwatch();
            tokenizeTime.Start();
            foreach (var source in sources) {
                try {
                    var tokenizer = new Tokenizer();
                    tokenizer.Initialize(source);

                    Tokens token;
                    do {
                        token = tokenizer.GetNextToken();
                    } while (token != Tokens.EndOfFile);
                } catch (Exception) {
                    Console.WriteLine("Tokenization error: {0}", source.Path);
                    break;
                }
            }
            tokenizeTime.Stop();
#endif
            //var stackSizes = new Dictionary<int, int>();

            var options = new RubyCompilerOptions();
            Stopwatch parseTime = new Stopwatch();
            Stopwatch transformTime = new Stopwatch();
            foreach (var source in sources) {
                try {
                    parseTime.Start();
                    var parser = new Parser();
                    var rubyTree = parser.Parse(source, options, ErrorSink.Null);
                    //int mt;
                    //stackSizes[parser.StackMaxTop] = stackSizes.TryGetValue(parser.StackMaxTop, out mt) ? mt + 1 : 1;
                    parseTime.Stop();
#if F
                    if (rubyTree != null) {
                        transformTime.Start();
                        var lambda = _context.TransformTree<DlrMainCallTarget>(rubyTree, source, options);
                        transformTime.Stop();
                    } else {
                        Console.WriteLine("SyntaxError: {0}", source.Path);
                    }
#endif
                } catch (Exception e) {
                    Console.WriteLine("{0}: {1}: {2}", e.GetType().Name, source.Path, e.Message);
                    break;
                }
            }

          //  Console.WriteLine("Tokenize:        {0}", tokenizeTime.Elapsed);
            Console.WriteLine("Parse:           {0}", parseTime.Elapsed);
            //Console.WriteLine("Idf/Kwd/Loc: {0}/{1}/{2}", Tokenizer.IdfLength, Tokenizer.KwdLength, Tokenizer.LocLength);
           // Console.WriteLine("Transform:       {0}", transformTime.Elapsed);

            //PerfTrack.DumpHistogram(Parser.Reductions);
            //PerfTrack.DumpHistogram(stackSizes);
        }
Beispiel #8
0
        private ScriptCode/*!*/ CompileRubySource(SourceUnit/*!*/ sourceUnit, LoadFlags flags) {
            Assert.NotNull(sourceUnit);
            
            // TODO: check file timestamp
            string fullPath = Platform.GetFullPath(sourceUnit.Path);
            CompiledFile compiledFile;
            if (TryGetCompiledFile(fullPath, out compiledFile)) {
                Utils.Log(String.Format("{0}: {1}", ++_cacheHitCount, sourceUnit.Path), "LOAD_CACHED");

                return compiledFile.CompiledCode;
            } else {
                Utils.Log(String.Format("{0}: {1}", ++_compiledFileCount, sourceUnit.Path), "LOAD_COMPILED");

                RubyCompilerOptions options = new RubyCompilerOptions(_context.RubyOptions) {
                    FactoryKind = (flags & LoadFlags.LoadIsolated) != 0 ? TopScopeFactoryKind.WrappedFile : TopScopeFactoryKind.File
                };

                long ts1 = Stopwatch.GetTimestamp();
                ScriptCode compiledCode = sourceUnit.Compile(options, _context.RuntimeErrorSink);
                long ts2 = Stopwatch.GetTimestamp();
                Interlocked.Add(ref _ScriptCodeGenerationTimeTicks, ts2 - ts1);

                AddCompiledFile(fullPath, compiledCode);

                return compiledCode;
            }
        }
Beispiel #9
0
        private ScriptCode/*!*/ CompileRubySource(SourceUnit/*!*/ sourceUnit, LoadFlags flags) {
            Assert.NotNull(sourceUnit);
            
            // TODO: check file timestamp
            string fullPath = Platform.GetFullPath(sourceUnit.Path);

#if FEATURE_FILESYSTEM
            CompiledFile compiledFile;
            if (TryGetCompiledFile(fullPath, out compiledFile)) {
                Utils.Log(String.Format("{0}: {1}", ++_cacheHitCount, sourceUnit.Path), "LOAD_CACHED");

                return compiledFile.CompiledCode;
            } 

            Utils.Log(String.Format("{0}: {1}", ++_compiledFileCount, sourceUnit.Path), "LOAD_COMPILED");
#endif

            RubyCompilerOptions options = new RubyCompilerOptions(_context.RubyOptions) {
                FactoryKind = (flags & LoadFlags.LoadIsolated) != 0 ? TopScopeFactoryKind.WrappedFile : TopScopeFactoryKind.File
            };

            ScriptCode compiledCode = sourceUnit.Compile(options, _context.RuntimeErrorSink);

#if FEATURE_FILESYSTEM
            AddCompiledFile(fullPath, compiledCode);
#endif
            return compiledCode;
        }