代码拉取完成,页面将自动刷新
同步操作将从 landy/qlang 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package exec
import (
"errors"
"fmt"
"os"
)
var (
// ErrReturn is used for `panic(ErrReturn)`
ErrReturn = errors.New("return")
)
// -----------------------------------------------------------------------------
// Exit
func doExit(ret interface{}) {
code := 0
if ret != nil {
code = ret.(int)
}
os.Exit(code)
}
var (
// Exit is the instruction that executes `exit(<code>)`.
Exit = Call(doExit)
)
// -----------------------------------------------------------------------------
// Return
type iReturn int
func (arity iReturn) Exec(stk *Stack, ctx *Context) {
if arity == 0 {
ctx.ret = nil
} else if arity == 1 {
ctx.ret, _ = stk.Pop()
} else {
ctx.ret = stk.PopNArgs(int(arity))
}
if ctx.parent != nil {
panic(ErrReturn) // 利用 panic 来实现 return (正常退出)
}
ctx.ExecDefers()
if ctx.ret == nil {
os.Exit(0)
}
if v, ok := ctx.ret.(int); ok {
os.Exit(v)
}
panic("must return `int` for main function")
}
// Return returns an instruction that means `return <expr1>, ..., <exprN>`.
//
func Return(arity int) Instr {
return iReturn(arity)
}
// -----------------------------------------------------------------------------
// Defer
type iDefer struct {
start int
end int
}
func (p *iDefer) Exec(stk *Stack, ctx *Context) {
ctx.defers = &theDefer{
next: ctx.defers,
start: p.start,
end: p.end,
}
}
// Defer returns an instruction that executes `defer <expr>`.
//
func Defer(start, end int) Instr {
return &iDefer{start, end}
}
// -----------------------------------------------------------------------------
// Recover
type iRecover int
func (p iRecover) Exec(stk *Stack, ctx *Context) {
if parent := ctx.parent; parent != nil {
e := parent.Recov
parent.Recov = nil
stk.Push(e)
} else {
stk.Push(nil)
}
}
var (
// Recover is the instruction that executes `recover()`.
Recover Instr = iRecover(0)
)
// -----------------------------------------------------------------------------
// NewFunction
// A Function represents a function object.
//
type Function struct {
Cls *Class
Parent *Context
start int
end int
Args []string
Variadic bool
}
// NewFunction creates a new function object.
//
func NewFunction(cls *Class, start, end int, args []string, variadic bool) *Function {
return &Function{cls, nil, start, end, args, variadic}
}
// Call calls this function with default context.
//
func (p *Function) Call(args ...interface{}) (ret interface{}) {
return p.ExtCall(nil, args...)
}
// ExtCall calls this function with a specified context.
//
func (p *Function) ExtCall(ctx *Context, args ...interface{}) (ret interface{}) {
n := len(p.Args)
if p.Variadic {
if len(args) < n-1 {
panic(fmt.Sprintf("function requires >= %d arguments, but we got %d", n-1, len(args)))
}
} else {
if len(args) != n {
panic(fmt.Sprintf("function requires %d arguments, but we got %d", n, len(args)))
}
}
if p.start == p.end {
return nil
}
var base int
var vars map[string]interface{}
var stk *Stack
if ctx == nil {
parent := p.Parent
vars = make(map[string]interface{})
stk = parent.Stack
base = stk.BaseFrame()
ctx = &Context{
parent: parent,
Stack: stk,
Code: parent.Code,
modmgr: parent.modmgr,
vars: vars,
base: base,
}
} else {
vars = ctx.vars
stk = ctx.Stack
base = stk.BaseFrame()
}
if p.Variadic {
for i := 0; i < n-1; i++ {
vars[p.Args[i]] = args[i]
}
vars[p.Args[n-1]] = args[n-1:]
} else {
for i, arg := range args {
vars[p.Args[i]] = arg
}
}
defer func() {
if e := recover(); e != ErrReturn { // 正常 return 导致,见 (*iReturn).Exec 函数
ctx.Recov = e
}
ret = ctx.ret
ctx.ExecDefers()
stk.SetFrame(base)
if ctx.Recov != nil {
panic(ctx.Recov)
}
}()
ctx.Code.Exec(p.start, p.end, stk, ctx)
return
}
// -----------------------------------------------------------------------------
type iFunc Function
func (p *iFunc) Exec(stk *Stack, ctx *Context) {
p.Parent = ctx
stk.Push((*Function)(p))
}
// Func returns an instruction that create a function object.
//
func Func(cls *Class, start, end int, args []string, variadic bool) Instr {
f := NewFunction(cls, start, end, args, variadic)
return (*iFunc)(f)
}
// -----------------------------------------------------------------------------
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。