예제 #1
0
파일: Program.cs 프로젝트: LaxLacks/ls2csc
        static void Main(string[] args)
        {
            List<String> referenceFiles = new List<String>();
            List<String> inputFiles = new List<String>();
            List<SyntaxTree> inputTrees = new List<SyntaxTree>();
            String outputFile = "";
            bool help = false;
            int silence = 0;
            bool bootstrap = false;

            OptionSet Options = new OptionSet(){
                {"i|input=", "Input {file}", v => { inputFiles.Add(v); }},
                {"r|reference=", "Reference {file}", v => { referenceFiles.Add(v); }},
                {"o|output=", "Output {file}", v => { outputFile = v; }},
                {"h|?|help", "Show this help and exit", v => { help = (v != null); }},
                {"s|silent", "Silence, 1 per level", v => { silence++; }},
                {"b|bootstrap", "LS2 Bootstrap compiler mode", v => { bootstrap = (v != null); }}
            };

            Options.Parse(args);

            if (silence <= 0)
            {
                System.Console.Error.WriteLine("C# Compiler for LavishScript 2.0 Virtual Machine");
                System.Console.Error.WriteLine("- Building for LS2IL version " + LS2IL.Chunk.LS2ILVersion);
            }

            if (bootstrap)
            {
                System.Console.Error.WriteLine("- LS2 Bootstrap compiler mode");
            }

            if (help)
            {
                System.Console.Error.WriteLine("Usage: ls2csc -i input.cs -o output.il");
                Options.WriteOptionDescriptions(System.Console.Error);
                return;
            }

            TextWriter output;

            if (outputFile != "")
            {
                output = new StreamWriter(outputFile);
            }
            else
            {
                output = System.Console.Out;
            }

            if (bootstrap)
            {
                if (inputFiles.Count != 0)
                {
                    System.Console.Error.WriteLine("Input files ignored in Bootstrap compiler mode.");
                }
                inputFiles = new List<string>();

                string text = string.Empty;
                text += "#define BOOTSTRAP_MODE" + System.Environment.NewLine;
                text += Resources.Instance.DeserializeStream("ls2csc.Libraries.BootStrap.cs");
                SyntaxTree tree = CSharpSyntaxTree.ParseText(text);
                // syntaxTrees.Add(tree);
                inputTrees.Add(tree);
            }
            else
            {

                if (inputFiles.Count != 0)
                {

                    foreach (string inputfile in inputFiles)
                    {
                        if (silence <= 0)
                        {
                            System.Console.Error.WriteLine("Attempting to compile from file '" + inputfile + "'");
                        }

                        inputTrees.Add(CSharpSyntaxTree.ParseFile(inputfile));
                    }
                }
                else
                {
#if !USEPREDEF
                    System.Console.Error.WriteLine("ls2csc: Filename required");
                    System.Console.Error.WriteLine("ls2csc: To display help, use 'ls2csc -h'");
                    return;
#endif

                    // this mess is for testing.
#if USEPREDEF
                string predef = @"
/* expected
your ls2 filename: <preloaded> IsStarted=true
*/
using System;
using LavishScript2;
using LavishScriptAPI;
namespace ls2csctest
{
    public enum SomeEnum : int
    {
        SomeValue=1,
        SomeOtherValue,
    }

    public interface ISomeIFace
    {
        int SomeMethod();
        string SomeProperty { get; }
    }

    public class SomeClass : ISomeIFace
    {
        public SomeClass()
        {
            MyEnum = SomeEnum.SomeOtherValue;
        }

        public virtual int SomeMethod()
        {
            return 42;
        }

        public string SomeProperty
        {
            get { return ""What is the answer to the question of life, the universe, and everything?""; }
        }

        public SomeEnum MyEnum { get; set; }
    }

	public class Test{
		public static void Main(){
			FieldTest ft = new FieldTest();
			ft.Test();

            foreach(Script s in Script.AllScripts)
            {               
                string fname;

                try
                {
                    fname = s.Filename;
                }
                catch
                {
                    fname = ""<preloaded>""; // expected since we are currently building bytecode from ls2il in memory, instead of using a bytecode file
                }

                System.Console.WriteLine(s.Name+"": ""+fname+"" IsStarted=""+s.IsStarted.ToString());
            }

            SomeClass myClass = new SomeClass();
            if (myClass is ISomeIFace)
            {
                ISomeIFace iface = myClass as ISomeIFace;
                System.Console.WriteLine(iface.SomeProperty+"" ""+iface.SomeMethod()+"" MyEnum=""+myClass.MyEnum.ToString());
            }

/*
            using (LavishScriptObject obj = LavishScript.Objects.GetObject(""InnerSpace""), obj2 = LavishScript.Objects.GetObject(""InnerSpace""))
            {
               System.Console.WriteLine(""InnerSpace.Build==""+obj.GetMember(""Build"").ToString());
            }
*/
		}
	}
	
	public class FieldTest{
		public int num = -10;

		public void OtherTest(){
		
		}
		public void Test(){
			OtherTest();
			
			this.OtherTest();
		}
	}
}";
#endif

#if USEPREDEF
                if (silence <= 0)
                {
                    System.Console.WriteLine("Attempting to compile from pre-defined text:");
                }
                System.Console.WriteLine(predef);
                inputtrees.Add(SyntaxTree.ParseText(predef));
#endif
                }
            }
#if OUTPUTEXCEPTIONS
            try
#endif
            {
                // get libraries!

                //List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
                List<SyntaxTree> referenceTrees = new List<SyntaxTree>();

                #region Metadata == Declarations == "Libraries"
                string[] auto_reference = { 
                                              "ls2csc.Libraries.InnerSpaceAPI.cs", 
                                              "ls2csc.Libraries.LavishScriptAPI.cs", 
                                              "ls2csc.Libraries.LavishScript2.cs", 
                                              "ls2csc.Libraries.LavishSettings.cs", 
                                              "ls2csc.Libraries.System.cs",
                                              "ls2csc.Libraries.BootStrap.cs"
                                          };
                

                foreach (string s in auto_reference)
                {
                    string text = string.Empty;
                    if (bootstrap)
                    {
                        if (s.Contains("BootStrap"))
                        {
                            continue;
                        }
                        text += "#define BOOTSTRAP_MODE" + System.Environment.NewLine;
                    }
                    text += Resources.Instance.DeserializeStream(s);
                    SyntaxTree tree = CSharpSyntaxTree.ParseText(text);
                   // syntaxTrees.Add(tree);
                    referenceTrees.Add(tree);
                }



                foreach (string s in referenceFiles)
                {
                    SyntaxTree tree = CSharpSyntaxTree.ParseFile(s);
                    //syntaxTrees.Add(tree);
                    referenceTrees.Add(tree);
                }
                #endregion

                Compilation compilation = CSharpCompilation.Create("MyCompilation", syntaxTrees: referenceTrees);


                compilation = compilation.AddSyntaxTrees(inputTrees);

                #region Diagnose and display Errors on the original code
                int nErrors = 0;
                foreach (SyntaxTree tree in inputTrees)
                {
                    SemanticModel model = compilation.GetSemanticModel(tree);
                    IEnumerable<Diagnostic> diags;
                    if ((diags = model.GetDiagnostics()) != null)
                    {
                        foreach (Diagnostic diag in diags)
                        {
                            if (diag.Severity == DiagnosticSeverity.Error)
                            {
                                nErrors++;
                            }
                            int neededSilence = 1;
                            switch (diag.Severity)
                            {
                                case DiagnosticSeverity.Error:
                                    neededSilence = 3;
                                    break;
                                case DiagnosticSeverity.Warning:
                                    neededSilence = 2;
                                    break;
                                case DiagnosticSeverity.Info:
                                    neededSilence = 1;
                                    break;
                            }
                            if (silence <= neededSilence)
                            {
                                System.Console.Error.WriteLine(diag.ToString());
                            }
                        }

                    }
                }
                if (nErrors > 0)
                {
                    System.Console.Error.WriteLine("Fix " + nErrors.ToString() + " errors. :(");
                    return;
                }
                #endregion



                {
                    List<SyntaxTree> finalReferenceTrees = new List<SyntaxTree>();
                    foreach (SyntaxTree tree in referenceTrees)
                    {

                        SyntaxNode newRoot = tree.GetRoot();
                        SemanticModel model = compilation.GetSemanticModel(tree);
                        newRoot = new IndexerRewriter(model).Visit(newRoot);
                        newRoot = new EnumValueRewriter().Visit(newRoot);
                        newRoot = new AutoImplementedPropertyRewriter().Visit(newRoot);
                        finalReferenceTrees.Add((CSharpSyntaxTree.Create((CSharpSyntaxNode)newRoot)));
                    }
                    referenceTrees = finalReferenceTrees;
                }
                #region C# Code Transformations: Optimizations and other rewriters
                List<SyntaxTree> finaltrees = new List<SyntaxTree>();

                foreach (SyntaxTree tree in inputTrees)
                {
                    SyntaxNode newRoot = tree.GetRoot();
                    SemanticModel model = compilation.GetSemanticModel(tree);

                    newRoot = new IndexerRewriter(model).Visit(newRoot);
                    newRoot = new EnumValueRewriter().Visit(newRoot);
#if SCRIPTING_API_REINTRODUCED
                    newRoot = new Optimizers.CondenseLiteralsRewriter().Visit(newRoot);
#endif
                    newRoot = new PrefixUnaryToBinaryRewriter().Visit(newRoot);
                    newRoot = new FieldInitializerRewriter(model).Visit(newRoot);
                    newRoot = new ForeachRewriter().Visit(newRoot);
                    newRoot = new AutoImplementedPropertyRewriter().Visit(newRoot);

                    finaltrees.Add(CSharpSyntaxTree.Create((CSharpSyntaxNode)newRoot));
                }
                #endregion

                compilation = CSharpCompilation.Create("MyCompilation", syntaxTrees: referenceTrees);
                compilation = compilation.AddSyntaxTrees(finaltrees);

                #region LS2 IL Code Generation
                LS2IL.FlatObjectType.Compilation = compilation;
                LS2IL.Chunk chunk = new LS2IL.Chunk(compilation);

                foreach (SyntaxTree tree in referenceTrees)
                {
                    SemanticModel model = compilation.GetSemanticModel(tree);

                    SyntaxNode root = tree.GetRoot();
                    // Build up the metadata
                    DeclarationCollector dc = new DeclarationCollector(chunk, model, true); // isLibrary = true because these are the reference-only trees
                    dc.Visit(root);
                }

                foreach (SyntaxTree tree in finaltrees)
                {

                    SemanticModel model = compilation.GetSemanticModel(tree);

                    SyntaxNode root = tree.GetRoot();

                    // collect methods and properties to turn into LS2IL.Functions 
                    MethodCollector mc = new MethodCollector(chunk, model);
                    mc.Visit(root);

                    // Build up the metadata
                    DeclarationCollector dc = new DeclarationCollector(chunk, model, false); // isLibrary = false because these are the trees going into the Chunk
                    dc.Visit(root);
                }

                // TODO: command-line options for these flags
                LS2ILGeneratorOptions options = new LS2ILGeneratorOptions() { CondenseRegisters = true, ElevateLongValues = true, FilterUnusedInstructions = true, FlattenLabels = true };

                chunk.Emit(options, output);
                output.WriteLine("");
                #endregion

            }
#if OUTPUTEXCEPTIONS
            catch (Exception e)
            {
                System.Console.Error.WriteLine("ls2csc: Unhandled Exception " + e.ToString());
            }
            finally
            
#endif
            {
                output.Close();
            }
        }
예제 #2
0
파일: Chunk.cs 프로젝트: LaxLacks/ls2csc
        /// <summary>
        /// Emits the Chunk to output in LS2IL
        /// </summary>
        /// <param name="output"></param>
        public void Emit(LS2ILGeneratorOptions options, TextWriter output)
        {
            output.WriteLine("; ---- begin chunk ----");

            IMethodSymbol entryPoint = Compilation.GetEntryPoint(CancellationToken.None);

            if (entryPoint != null)
            {
                Function fEntryPoint;
                if (!Functions.TryGetValue(entryPoint, out fEntryPoint))
                {
                    throw new NotSupportedException("Entry point function not built");
                }

                output.WriteLine(".entry " + fEntryPoint.NumFunction);
            }

            for (int i = 0; i < FunctionsByNumber.Count; i++)
            {
                LS2IL.Function f = FunctionsByNumber[i];

                f.FlattenToInstructions(options);
            }

            GenerateTypesMetadata();

            EmitMetaTable(output);

            output.WriteLine("; ---- begin chunk values ----");
            foreach (string s in EmittedChunkValues)
            {
                output.WriteLine(s);
            }
            output.WriteLine("; ---- end chunk values ----");
            output.WriteLine("");

            output.WriteLine("; ---- begin functions ----");

            foreach (LS2IL.Function f in FunctionsByNumber)
            {

                f.Emit(output);
            }
            output.WriteLine("; ---- end functions ----");

            output.WriteLine("; ---- end chunk ----");
        }
예제 #3
0
파일: Function.cs 프로젝트: LaxLacks/ls2csc
        public void FlattenToInstructions(LS2ILGeneratorOptions options)
        {
            List<FlatStatement> list = Flatten();

            ControlFlowGraph cfg = new ControlFlowGraph(this, list);
            cfg.Build(options.FilterUnusedInstructions);

            if (options.CondenseRegisters)
            {
                PackedRegisters = RegisterPackers.Pack(cfg);
            }
            else
            {
                PackedRegisters = this.Registers.Count;
            }

            if (PackedRegisters > 256)
            {
                throw new NotSupportedException("Too many registers used in function " + this.IMethodSymbol.GetFullyQualifiedName());
            }

            list = cfg.Flatten();
            if (options.ElevateLongValues)
            {
                foreach (FlatStatement fs in list)
                {
                    if (fs.Operands == null)
                        continue;

                    string emitted = fs.Emit();
                    if (emitted.Length < 192)
                        continue;

                    // let's shorten this baby up.
                    for (int i = 0; i < fs.Operands.Count; i++)
                    {
                        FlatOperand fo = fs.Operands[i];
                        if (fo.OperandType != FlatOperandType.OPND_IMMEDIATE)
                            continue;

                        if (fo.ImmediateValue.ToString().Length > 63)
                        {
                            int nValue = FunctionValues.Count;
                            FunctionValues.Add(fo.ImmediateValue);
                            fs.Operands[i] = FlatOperand.FunctionValueRef(nValue, fo.ImmediateValue);
                        }
                    }
                }
            }

            if (options.FlattenLabels)
            {
                FlattenLabels(list);

                foreach (FlatValue fv in FunctionValues)
                {
                    if (fv.ValueType == FlatValueType.VT_Label)
                    {
                        // get label target
                        int labelValue;
                        if (!EmittedLabels.TryGetValue(fv.ValueText, out labelValue))
                        {
                            throw new LS2ILLabelException("Unresolved label " + fv.ValueText);
                        }

                        fv.ValueType = FlatValueType.VT_Int32;
                        fv.ValueText = labelValue.ToString();
                        fv.Object = labelValue;
                    }
                    else if (fv.Object is FlatArrayBuilder)
                    {
                        FlatArrayBuilder fab = (FlatArrayBuilder)fv.Object;
                        fab.FlattenLabels(this);
                    }
                    else if (fv.Object is FlatTableBuilder)
                    {
                        FlatTableBuilder fab = (FlatTableBuilder)fv.Object;
                        fab.FlattenLabels(this);
                    }
                }
            }

            if (options.FlattenLabels)
            {
                foreach (FlatStatement fs in list)
                {
                    if (fs.Instruction != Instruction.meta_LABEL)
                        EmitInstruction(fs.Emit());
                }
            }
            else
            {
                foreach (FlatStatement fs in list)
                {
                    EmitInstruction(fs.Emit());
                }
            }
        }