Ejemplo n.º 1
0
        public ImmutableArray <Diagnostic> Emit(BoundProgram program, string outputPath)
        {
            if (_diagnostics.Any())
            {
                return(_diagnostics.ToImmutableArray());
            }

            var objectType = _knownTypes[TypeSymbol.Any];

            _typeDefinition = new TypeDefinition("", "Program", TypeAttributes.Abstract | TypeAttributes.Sealed, objectType);
            _assemblyDefinition.MainModule.Types.Add(_typeDefinition);

            foreach (var functionWithBody in program.Functions)
            {
                EmitFunctionDeclaration(functionWithBody.Key);
            }

            foreach (var functionWithBody in program.Functions)
            {
                EmitFunctionBody(functionWithBody.Key, functionWithBody.Value);
            }

            if (program.MainFunction != null)
            {
                _assemblyDefinition.EntryPoint = _methods[program.MainFunction];
            }

            _assemblyDefinition.Write(outputPath);

            return(_diagnostics.ToImmutableArray());
        }
Ejemplo n.º 2
0
 internal Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)
 {
     diagnostics = new DiagnosticContainer();
     Program     = program;
     globals     = variables;
     locals      = new Stack <Dictionary <VariableSymbol, object> >();
 }
Ejemplo n.º 3
0
        public EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables)
        {
            ImmutableArray <Diagnostic> diagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray();

            if (diagnostics.Any())
            {
                return(new EvaluationResult(diagnostics, null));
            }

            BoundProgram program = Binder.BindProgram(GlobalScope);

            string appPath      = Environment.GetCommandLineArgs()[0];
            string appDirectory = Path.GetDirectoryName(appPath);
            string cfgPath      = Path.Combine(appDirectory, "cfg.dot");
            BoundBlockStatement cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any()
                                                  ? program.Functions.Last().Value
                                                  : program.Statement;
            var cfg = ControlFlowGraph.Create(cfgStatement);

            using (StreamWriter streamWriter = new StreamWriter(cfgPath))
                cfg.WriteTo(streamWriter);

            if (program.Diagnostics.Any())
            {
                return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null));
            }

            Evaluator evaluator = new Evaluator(program, variables);
            object    value     = evaluator.Evaluate();

            return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value));
        }
Ejemplo n.º 4
0
 private static void WriteBoundProgram(this IndentedTextWriter writer, BoundProgram node)
 {
     foreach (var pair in node.Functions)
     {
         writer.WriteFunctionSymbol(pair.Key);
         writer.WriteLine();
         writer.WriteBoundBlockStatement(pair.Value);
         writer.WriteLine();
         writer.WriteLine();
     }
 }
Ejemplo n.º 5
0
        public static ImmutableArray <Diagnostic> Emit(BoundProgram program, string moduleName, string[] references, string outputPath)
        {
            if (program.Diagnostics.Any())
            {
                return(program.Diagnostics);
            }

            var emitter = new Emitter(moduleName, references);

            return(emitter.Emit(program, outputPath));
        }
Ejemplo n.º 6
0
        public Evaluator(BoundProgram program, CompilationContext context, bool inRepl)
        {
            _program = program;
            _context = context;
            var outerScope = new EvaluationScope();

            _scopeStack.Push(outerScope);
            _inRepl = inRepl;
            foreach (var pair in program.Functions)
            {
                _functions[pair.Key] = pair.Value;
            }
        }
Ejemplo n.º 7
0
        public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)
        {
            this.Program = program;
            this.Globals = variables;
            this.Locals.Push(new Dictionary <VariableSymbol, object>());

            var c = this.Program;

            while (c != null)
            {
                foreach (var f in c.Functions)
                {
                    this.Functions.Add(f.Key, f.Value);
                }

                c = c.Previous;
            }
        }
Ejemplo n.º 8
0
        private ImmutableArray <Diagnostic> EmitAssembly(BoundProgram program)
        {
            var header              = new PEHeaderBuilder();
            var metadataBuilder     = new MetadataBuilder();
            var metadataRootBuilder = new MetadataRootBuilder(metadataBuilder);
            var blobBuilder         = new BlobBuilder();
            var peBuilder           = new ManagedPEBuilder(header, metadataRootBuilder, blobBuilder);

            peBuilder.Serialize(blobBuilder);

            // TODO: Produce portable assembly contents here
            using (var stream = new StreamWriter(program.PackageName + ".dll"))
            {
                blobBuilder.WriteContentTo(stream.BaseStream);
            }

            return(ImmutableArray <Diagnostic> .Empty);
        }
Ejemplo n.º 9
0
        public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)
        {
            _program = program;
            _globals = variables;
            _locals.Push(new Dictionary <VariableSymbol, object>());

            var current = program;

            while (current != null)
            {
                // TODO: Flagged (kv)
                foreach (var(function, body) in current.Functions)
                {
                    _functions.Add(function, body);
                }

                current = current.Previous;
            }
        }
Ejemplo n.º 10
0
        public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)

        {
            _program = program;
            _globals = variables;
            _locals.Push(new Dictionary <VariableSymbol, object>());

            var current = program;

            while (current != null)
            {
                foreach (var kv in current.Functions)
                {
                    var function = kv.Key;
                    var body     = kv.Value;
                    _functions.Add(function, body);
                }
                current = current.Previous;
            }
        }
Ejemplo n.º 11
0
        public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> globalVariables)
        {
            this.program = program ?? throw new ArgumentNullException(nameof(program));

            globals = globalVariables;

            var current = program;

            while (current is not null)
            {
                foreach (var kv in current.Functions)
                {
                    var function = kv.Key;
                    var body     = kv.Value;
                    functions.Add(function, body);
                }

                current = current.Previous;
            }
        }
Ejemplo n.º 12
0
        private Compilation(IEnumerable <SourceText> sourceTexts, string moduleName, string[] referencePaths, bool isScript)
        {
            this.referencePaths = referencePaths;
            this.isScript       = isScript;
            this.SourceTexts    = sourceTexts;
            this.moduleName     = moduleName;
            var diagnosticBuilder = ImmutableArray.CreateBuilder <Diagnostic>();
            var trees             = new List <SyntaxTree>();

            foreach (var text in sourceTexts)
            {
                var tree = SyntaxTree.ParseSyntaxTree(text, isScript);
                diagnosticBuilder.AddRange(tree.GetDiagnostics());
                trees.Add(tree);
            }

            program = Binder.BindProgram(moduleName, referencePaths, isScript, trees.Select(t => t.Root));
            diagnosticBuilder.AddRange(program.Diagnostics);

            Diagnostics = new DiagnosticReport(diagnosticBuilder.ToImmutable());
        }
Ejemplo n.º 13
0
        public static ImmutableArray <Diagnostic> Emit(BoundProgram program, string moduleName, string[] references, string outputPath)
        {
            if (program.Diagnostics.Any())
            {
                return(program.Diagnostics);
            }

            var result = new DiagnosticBag();

            var assemblyName       = new AssemblyNameDefinition(moduleName, new Version(1, 0));
            var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, moduleName, ModuleKind.Console);

            var typeDefinition = new TypeDefinition("", "Program", TypeAttributes.Abstract | TypeAttributes.Sealed);

            assemblyDefinition.MainModule.Types.Add(typeDefinition);

            // var main = new MethodDefinition("Main", MethodAttributes.Static, voidType);
            assemblyDefinition.Write(outputPath);

            return(result.ToImmutableArray());
        }
Ejemplo n.º 14
0
        public void EmitTree(TextWriter writer)
        {
            BoundProgram program = Binder.BindProgram(GlobalScope);

            if (program.Statement.Statements.Any())
            {
                program.Statement.WriteTo(writer);
            }
            else
            {
                foreach (var functionBody in program.Functions)
                {
                    if (!GlobalScope.Functions.Contains(functionBody.Key))
                    {
                        continue;
                    }

                    functionBody.Key.WriteTo(writer);
                    functionBody.Value.WriteTo(writer);
                }
            }
        }
Ejemplo n.º 15
0
        public static ImmutableArray <Diagnostic> Emit(BoundProgram program, string moduleName, string[] references, string outputPath)
        {
            if (program.Diagnostics.Any())
            {
                return(program.Diagnostics);
            }

            var assemblies = new List <AssemblyDefinition>();

            var result = new DiagnosticBag();

            foreach (var reference in references)
            {
                try
                {
                    var assembly = AssemblyDefinition.ReadAssembly(reference);
                    assemblies.Add(assembly);
                }
                catch (BadImageFormatException)
                {
                    result.ReportInvalidReference(reference);
                }
            }

            var builtInTypes = new List <(TypeSymbol type, string MetadataName)>()
            {
                (TypeSymbol.Any, "System.Object"),
                (TypeSymbol.Bool, "System.Boolean"),
                (TypeSymbol.Int, "System.Int32"),
                (TypeSymbol.String, "System.String"),
                (TypeSymbol.Void, "System.Void"),
            };

            var assemblyName       = new AssemblyNameDefinition(moduleName, new Version(1, 0));
            var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, moduleName, ModuleKind.Console);
            var knownTypes         = new Dictionary <TypeSymbol, TypeReference>();

            foreach (var(typeSymbol, metadataName) in builtInTypes)
            {
                var typeReference = ResolveType(typeSymbol.Name, metadataName);
                knownTypes.Add(typeSymbol, typeReference);
            }

            TypeReference ResolveType(string minskName, string metadataName)
            {
                var foundTypes = assemblies.SelectMany(a => a.Modules)
                                 .SelectMany(m => m.Types)
                                 .Where(t => t.FullName == metadataName)
                                 .ToArray();

                if (foundTypes.Length == 1)
                {
                    var typeReference = assemblyDefinition.MainModule.ImportReference(foundTypes[0]);
                    return(typeReference);
                }
                else if (foundTypes.Length == 0)
                {
                    result.ReportRequiredTypeNotFound(minskName, metadataName);
                }
                else
                {
                    result.ReportRequiredTypeAmbiguous(minskName, metadataName, foundTypes);
                }

                return(null);
            }

            MethodReference ResolveMethod(string typeName, string methodName, string[] parameterTypeNames)
            {
                var foundTypes = assemblies.SelectMany(a => a.Modules)
                                 .SelectMany(m => m.Types)
                                 .Where(t => t.FullName == typeName)
                                 .ToArray();

                if (foundTypes.Length == 1)
                {
                    var foundType = foundTypes[0];
                    var methods   = foundType.Methods.Where(m => m.Name == methodName);

                    foreach (var method in methods)
                    {
                        if (method.Parameters.Count != parameterTypeNames.Length)
                        {
                            continue;
                        }

                        var allParametersMatch = true;

                        for (var i = 0; i < parameterTypeNames.Length; i++)
                        {
                            if (method.Parameters[i].ParameterType.FullName != parameterTypeNames[i])
                            {
                                allParametersMatch = false;
                                break;
                            }
                        }

                        if (!allParametersMatch)
                        {
                            continue;
                        }

                        return(assemblyDefinition.MainModule.ImportReference(method));
                    }

                    result.ReportRequiredMethodNotFound(typeName, methodName, parameterTypeNames);
                    return(null);
                }
                else if (foundTypes.Length == 0)
                {
                    result.ReportRequiredTypeNotFound(null, typeName);
                }
                else
                {
                    result.ReportRequiredTypeAmbiguous(null, typeName, foundTypes);
                }

                return(null);
            }

            var consoleWriteLineReference = ResolveMethod("System.Console", "WriteLine", new [] { "System.String" });

            if (result.Any())
            {
                return(result.ToImmutableArray());
            }

            var objectType     = knownTypes[TypeSymbol.Any];
            var typeDefinition = new TypeDefinition("", "Program", TypeAttributes.Abstract | TypeAttributes.Sealed, objectType);

            assemblyDefinition.MainModule.Types.Add(typeDefinition);

            var voidType   = knownTypes[TypeSymbol.Void];
            var mainMethod = new MethodDefinition("Main", MethodAttributes.Static | MethodAttributes.Private, voidType);

            typeDefinition.Methods.Add(mainMethod);

            var ilProcessor = mainMethod.Body.GetILProcessor();

            ilProcessor.Emit(OpCodes.Ldstr, "Hello world from Minsk!");
            ilProcessor.Emit(OpCodes.Call, consoleWriteLineReference);
            ilProcessor.Emit(OpCodes.Ret);

            assemblyDefinition.EntryPoint = mainMethod;

            assemblyDefinition.Write(outputPath);

            return(result.ToImmutableArray());
        }
Ejemplo n.º 16
0
 public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)
 {
     _program = program;
     _globals = variables;
     _locals.Push(new Dictionary <VariableSymbol, object>());
 }
Ejemplo n.º 17
0
 public Evaluator(BoundProgram program, Dictionary <VariableSymbol, object> variables)
 {
     _program = program;
     _globals = variables;
 }