예제 #1
0
        public void Compile(Nodes.ICompileNode root)
        {
            root.PrePass(this);
            root.PreCompile(this);
            root.Compile(this);

            if (this.CurrentImportMode == ImportMode.None)
            {
                holding = this.operations;
                this.operations = new List<Operation>();

                if(this.IsBuildingExports)
                {
                    this.EmitPush("2u");
                    this.Emit(Opcode.ALLOC);
                    this.EmitPush("0u");
                    this.Emit(Opcode.STLO);
                    this.EmitPush("1u");
                    this.Emit(Opcode.STLO);
                }

                foreach(Symbol export in this.exports)
                {
                    this.EmitPush("1u");
                    this.Emit(Opcode.PLABL, "\"" + export.AsmName + "\"");
                    this.Emit(Opcode.ASUB);
                    this.EmitPush("1u");
                    this.Emit(Opcode.LDLO);
                    this.Emit(Opcode.AADD);
                }

                foreach(string import in this.importedLibraries)
                {
                    string label = "sl_imprt_" + this.GetScopeName() + this.CurrentScope.RequestLabelId().ToString();
                    this.Emit(Opcode.PMMX);
                    this.Emit(Opcode.PLABL, "\"" + label + "\"");
                    this.Emit(Opcode.PMMX);
                    this.EmitPush("\"" + Path.Combine(Path.GetDirectoryName(import), Path.GetFileNameWithoutExtension(import)).Replace('\\', '/') + ".sxl\"");
                    this.Emit(Opcode.IMPRT).SetDebug(this.FileStack.Peek(), -1, -1, DebugType.Import, import);
                    this.Emit(Opcode.JUMP);
                    this.Emit(Opcode.LABEL, label);
                }

                if(this.imports.Count > 0)
                {
                    this.EmitPush(this.imports.Count.ToString() + "u");
                    this.Emit(Opcode.ALLOC);
                    this.imports.Reverse();
                    foreach (Symbol import in this.imports)
                    {
                        this.EmitPush(import.Id.ToString() + "u");
                        this.Emit(Opcode.STLO);
                    }
                }

                if (this.IsBuildingExports)
                {
                    this.EmitPush("0u");
                    this.Emit(Opcode.LDLO);
                    this.EmitPush("2u");
                    this.Emit(Opcode.DEALLOC);
                    this.Emit(Opcode.JUMP);
                }
                else
                {
                    FunctionCallNode node = new FunctionCallNode(-1, -1)
                    {
                        Function = "+entry",
                        Arguments = new List<ICompileNode>()
                    };
                    node.PrePass(this);
                    node.PreCompile(this);
                    node.Compile(this);
                }

                this.Emit(Opcode.HALT);

                this.holding.InsertRange(0, this.operations);
                this.operations = this.holding;
                this.holding = null;
            }
        }