public override void Compile(Kernel k) { k.CurrentScope.PushMemory(k); Scope scope = k.PushScope(); scope.Name = "while" + scope.Parent.RequestLabelId(); string whileLabel = "sl_wl_" + k.GetScopeName(); string endLabel = "sl_wlh_" + k.GetScopeName(); Symbol breakSymbol = new Symbol() { Name = "+break", AsmName = endLabel }; k.RegisterSymbol(breakSymbol); k.Emit(Opcode.LABEL, whileLabel).Comment = "while loop"; k.Emit(Opcode.NOOP).SetDebug(File, Line, Column, DebugType.WhileLoop, ""); this.Check.Compile(k); k.Emit(Opcode.NOT); k.Emit(Opcode.GOTOF, '"' + endLabel + '"'); scope.PushMemory(k); Scope innerScope = k.PushScope(); innerScope.Name = "in"; if (this.Body != null) this.Body.Compile(k); k.EmitPush(innerScope.MemorySpace.ToString() + "u"); k.Emit(Opcode.DEALLOC); k.PopScope(); scope.PopMemory(k); k.Emit(Opcode.GOTO, '"' + whileLabel + '"'); k.Emit(Opcode.LABEL, endLabel).Comment = "end while"; k.PopScope(); k.CurrentScope.PopMemory(k); }
public override void Compile(Kernel k) { k.CurrentScope.PushMemory(k); Scope ifScope = k.PushScope(); ifScope.Name = "if" + ifScope.Parent.RequestLabelId(); string trueLabel = "sl_if_" + k.GetScopeName(); string falseLabel = "sl_fe_" + k.GetScopeName(); string endLabel = "sl_fh_" + k.GetScopeName(); this.Check.Compile(k); k.Emit(Opcode.GOTOF, '"' + trueLabel + '"').SetDebug(File, Line, Column, DebugType.Branch, ""); k.Emit(Opcode.GOTO, '"' + falseLabel + '"'); k.Emit(Opcode.LABEL, trueLabel); k.CurrentScope.PushMemory(k); Scope trueScope = k.PushScope(); trueScope.Name = "true"; if (this.BranchTrue != null) this.BranchTrue.Compile(k); k.PopScope(); k.CurrentScope.PopMemory(k); if(this.BranchFalse == null) { k.Emit(Opcode.LABEL, falseLabel).Comment = "no else block, used as end label"; } else if(this.BranchFalse != null) { k.Emit(Opcode.GOTO, '"' + endLabel + '"'); k.Emit(Opcode.LABEL, falseLabel); k.CurrentScope.PushMemory(k); Scope falseScope = k.PushScope(); falseScope.Name = "false"; this.BranchFalse.Compile(k); k.PopScope(); k.CurrentScope.PopMemory(k); k.Emit(Opcode.LABEL, endLabel).Comment = "end if"; } k.PopScope(); k.CurrentScope.PopMemory(k); }
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"; }