Esempio n. 1
0
        public override void Compile(Kernel k)
        {
            Symbol symbol = new Symbol()
                {
                    Name = this.Function,
                    SMode = Symbol.Mode.Intern,
                    SType = Symbol.Type.Function,
                    Args = (uint)this.Arguments.Count
                };

            k.RegisterSymbol(symbol);

            Scope scope = k.PushScope();
            scope.Name = this.Function;
            scope.MemorySpace += (uint)this.Arguments.Count + 1;

            symbol.AsmName = string.Format("sl_f_{0}", k.GetScopeName());

            switch(k.CurrentImportMode)
            {
                case ImportMode.Library:
                    k.PopScope();
                    symbol.SMode = Symbol.Mode.Library;
                    symbol.Id = k.CurrentScope.RequestId();
                    k.CurrentScope.MemorySpace++;
                    k.AddImport(symbol);
                    return;

                case ImportMode.Export:
                    k.AddExport(symbol);
                    break;
            }

            k.Emit(Opcode.LABEL, symbol.AsmName).Comment = "function " + this.Function; // function label
            k.Emit(Opcode.NOOP).SetDebug(File, Line, Column, DebugType.Function, this.Function);

            k.EmitPush(scope.MemorySpace.ToString() + "u").Comment = "allocate function parameter memory"; // allocate memory space for arguments and return location
            k.Emit(Opcode.ALLOC);

            Symbol returnSymbol = new Symbol()
                {
                    Name = "+return",
                    SMode = Symbol.Mode.Intern,
                    SType = Symbol.Type.Variable,
                    Id = k.CurrentScope.RequestId()
                };
            k.RegisterSymbol(returnSymbol);

            k.EmitPush(returnSymbol.Id.ToString() + "u").Comment = "store return location"; // store the return location
            k.Emit(Opcode.STLO);

            foreach(string arg in this.Arguments)
            {
                Symbol argSymbol = new Symbol()
                    {
                        Name = arg,
                        SMode = Symbol.Mode.Intern,
                        SType = Symbol.Type.Variable,
                        Id = k.CurrentScope.RequestId()
                    };
                k.RegisterSymbol(argSymbol);

                k.EmitPush(argSymbol.Id.ToString() + "u").Comment = "store argument " + arg; // store the argument
                k.Emit(Opcode.STLO);
            }

            k.Emit(Opcode.NOOP).Comment = "function body";

            if (this.Body != null)
                this.Body.Compile(k);

            new ReturnNode(-1, -1).Compile(k);

            k.PopScope();

            k.Emit(Opcode.NOOP).Comment = "end of function";
        }