glu

package module
v0.1.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2023 License: MIT Imports: 7 Imported by: 0

README

GLU (glucose) - gopher-lua module extensions

Summary

requires
  • go 1.17 (as gopher-lua required)

Packages

  1. glu the core module:
    1. Define helper Module and Type for easier register user library and user type;
    2. Define global LState pool for reuse;
    3. Define Registry for Modulars, with optional auto-injection;
    4. Support Help(string?) for help information;
  2. json dynamic json library base on Jeffail/gabs
  3. http http server and client library base on gorilla/mux, depends on json

Samples

  1. use
package sample

import (
   "fmt"
   "github.com/ZenLiuCN/glu"
   lua "github.com/yuin/gopher-lua"
)

func main() {
   fmt.Println(DoSomeScript("1+2")==3.0)
}
func DoSomeScript(script string) float64 {
   vm := glu.Get()
   defer glu.Put(vm)
   if err := vm.DoString(script); err != nil {
      panic(err)
   }
   return float64(vm.Pop().(lua.LNumber))
}
  1. print help
       local http=require('http')
       local json=require('json')
       print(json.Help()) --will print comma split keyword list
       print(http.Help('?')) --will print module help
       print(http.Server.Help('?')) --will print type constructor help
       for word in string.gmatch(http.Server.Help(), '([^,]+)') do
          print(http.Server.Help(word)) --will print method constructor help
       end
       print(http.Ctx.Help('?'))
       for word in string.gmatch(http.Ctx.Help(), '([^,]+)') do
          print(http.Ctx.Help(word))
       end
    
  2. http server
    local http=require('http')
    local server=http.Server.new(':8081') --new Server with listen address
    server:get('/',chunk([[                -- the handler is string lua script
                local c=...                --only parameter is http.Ctx
                c:sendString(c:query('p')) --query should legal JSON string
            ]]))
    server:start(false)
    while (true) do	end
    
  3. http client
     local res,err=require('http').Client.new(5):get('http://github.com')
     print(err)
     if res:size()>0 then
     local txt=res:body()  
     print(txt)
     end 
    

Support this project

  1. offer your ideas

  2. fork and pull

License

MIT as gopher-lua did

Documentation

Overview

Package glu support yuin/gopher-lua with easy modular definition and other enchantments. glu.Modular and gua.BaseType will inject mod.Help(name string?) method to output help information. glu.Get: Pool function to get a lua.LState. glu.Put: Pool function to return a lua.LState. glu.registry: shared module registry. glu.Auto: config for autoload modules in registry into lua.LState.

Example
// fetch an instance
vm := Get()
err := vm.DoString(`print('hello lua')`)
if err != nil {
	return
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	//GluMod the global module
	GluMod = glu(0)
	//HelpKey the module help key
	HelpKey = "?"
	//HelpFunc the help function name
	HelpFunc = "help"
	//HelpPrompt the prompt for no value supply for help
	HelpPrompt = "show help with those key word:"
	HelpChunk  = `chunk(code,name string)(Chunk?,string?) ==> pre compile string into bytecode`
	HelpHelp   = HelpFunc + `(topic string?)string? ==> fetch help of topic`
	HelpTopic  = `?,chunk`
)
View Source
var (
	ErrAlreadyExists            = errors.New("element already exists")
	ErrIndexOverrideWithMethods = errors.New("element both have methods and index overrides")
	ErrIsTop                    = errors.New("element is top module")
)
View Source
var (
	//Option LState configuration
	Option      = Options{}
	InitialSize = 4
)
View Source
var (
	//OpNone operator do nothing, better to use nil
	OpNone = func(s *Vm) error { return nil }
	//OpPush operator to push N value
	OpPush = func(n ...LValue) Operator {
		return func(s *Vm) error {
			for _, value := range n {
				s.Push(value)
			}
			return nil
		}
	}
	//OpPushUserData operator to push N UserDate
	OpPushUserData = func(n ...interface{}) Operator {
		return func(s *Vm) error {
			for _, i := range n {
				ud := s.NewUserData()
				ud.Value = i
				s.Push(ud)
			}
			return nil
		}
	}
	//OpSafe operator to wrap as none error will happen
	OpSafe = func(fn func(s *Vm)) Operator {
		return func(s *Vm) error {
			fn(s)
			return nil
		}
	}
	//OpPop operator to pop and consume N value from start,then pop to n
	OpPop = func(fn func(value ...LValue), start, count int) Operator {
		if start < 0 || count <= 0 {
			panic("start must greater than 0 and count must greater than 0")
		}
		t := start + count
		return func(s *Vm) error {
			v := make([]LValue, 0, count)
			for i := start; i < t; i++ {
				v = append(v, s.Get(i))
			}
			s.Pop(t - 1)
			fn(v...)
			return nil
		}
	}
	//OpPopN operator to pop n value (Reset stack)
	OpPopN = func(count int) Operator {
		if count < 1 {
			panic("count must greater than 0")
		}
		return func(s *Vm) error {
			s.Pop(count)
			return nil
		}
	}
)
View Source
var (
	//Auto if true, will autoload modules in registry
	Auto = true
)
View Source
var (
	//ErrorSupress not raise error ,use for SafeFunc
	ErrorSupress = errors.New("")
)
View Source
var (

	// ExistNode is placeholder for a map set
	ExistNode = struct{}{}
)

Functions

func CompileChunk

func CompileChunk(code string, source string) (*FunctionProto, error)

CompileChunk compile code to FunctionProto

func ExecuteChunk

func ExecuteChunk(code *FunctionProto, argN, retN int, before Operator, after Operator) (err error)

ExecuteChunk execute pre complied FunctionProto

func ExecuteCode

func ExecuteCode(code string, argsN, retN int, before Operator, after Operator) error

ExecuteCode run code in LState, use before to push args, after to extract return value

func Failed

func Failed(err error)

Failed must have error or-else throw

func MakePool

func MakePool()

MakePool manual create statePool , when need to change Option, should invoke once before use Get and Put

func Put

func Put(s *Vm)

Put LState back to statePool

func Raw added in v0.1.10

func Raw(v LValue) interface{}

Raw extract raw LValue: nil bool float64 string *LUserData *LState *LTable *LChannel

func Recover

func Recover(act func()) (err error)

Recover warp a callable func with recover

func RecoverErr

func RecoverErr(act func() error) (err error)

RecoverErr warp an error supplier func with recover

func Register

func Register(m ...Modular) (err error)

Register modular into registry

func SafeFunc added in v0.1.10

func SafeFunc(fn func(state *LState) int) LGFunction

SafeFunc no panic func

func SafeParam added in v0.1.10

func SafeParam(s *LState, start int, types ...LValueType) (r []interface{})

SafeParam extra parameter must match type or panic,use with SafeFunc.

func Success

func Success(err error)

Success must have no error or-else throw

func TableToMap

func TableToMap(s *LTable) (r map[LValue]LValue)

TableToMap convert LTable to a Map with all key values

func TableToSlice

func TableToSlice(s *LTable) (r []LValue)

TableToSlice convert LTable to a Slice with all Number index values

func TableUnpack

func TableUnpack(s *LTable, noLua bool, history map[LValue]interface{}) (r map[interface{}]interface{}, keys []interface{})

TableUnpack convert LTable to a Map with all key values

All keys and values may be:

LTNumber: float64

LTBool: bool

LTTable: map[any]any

LTString: string

(those type will not output with noLua=true )

LTFunction: *LFunction

LTUserData: *LUserData

LChannel: LChannel

Types

type BaseType

type BaseType struct {
	Mod
	HelpCtor string
	// contains filtered or unexported fields
}

BaseType define a LTable with MetaTable, which mimicry class like action in Lua

func NewSimpleType

func NewSimpleType(name string, help string, top bool) *BaseType

NewSimpleType create new BaseType without ctor

func NewType

func NewType(name string, help string, top bool, ctorHelp string, ctor func(*LState) interface{}) *BaseType

NewType create new BaseType

func NewTypeCast

func NewTypeCast(sample interface{}, name string, help string, top bool, ctorHelp string, ctor func(*LState) interface{}) *BaseType

NewTypeCast create new BaseType with reflect Signature

func (*BaseType) AddField

func (m *BaseType) AddField(name string, help string, value LValue) Type

AddField add value field to this Modular

@name the field name

@help help string, if empty will not generate into help

@value the field value

func (*BaseType) AddFunc

func (m *BaseType) AddFunc(name string, help string, fn LGFunction) Type

AddFunc add function to this Modular

@name function name, must match lua limitation

@help help string, if empty will not generate into help

@fn the LGFunction

func (*BaseType) AddMethod

func (m *BaseType) AddMethod(name string, help string, value LGFunction) Type

AddMethod add method to this type which means instance method.

func (*BaseType) AddMethodCast

func (m *BaseType) AddMethodCast(name string, help string, act func(s *LState, data interface{}) int) Type

AddMethodCast prechecked type (only create with NewTypeCast).

func (*BaseType) AddMethodUserData

func (m *BaseType) AddMethodUserData(name string, help string, act func(s *LState, data *LUserData) int) Type

AddMethodUserData add method to this type which means instance method, with auto extract first argument.

func (*BaseType) AddModule

func (m *BaseType) AddModule(mod Modular) Type

AddModule add sub-module to this Modular

@mod the Mod **Note** must with TopLevel false.

func (BaseType) CanCast

func (m BaseType) CanCast() bool

CanCast check the type can use cast (when construct with NewTypeCast)

func (BaseType) Cast

func (m BaseType) Cast(u *LUserData) interface{}

Cast nil if not current type else the value

func (BaseType) CastVar

func (m BaseType) CastVar(s *LState, n int) interface{}

CastVar cast value on stack

func (BaseType) New

func (m BaseType) New(l *LState, val interface{}) int

New wrap an instance into LState

func (BaseType) NewValue

func (m BaseType) NewValue(l *LState, val interface{}) *LUserData

NewValue create new LValue

func (*BaseType) Override

func (m *BaseType) Override(op Operate, help string, fn LGFunction) Type

Override override an operator

func (*BaseType) OverrideCast

func (m *BaseType) OverrideCast(op Operate, help string, act func(s *LState, data interface{}) int) Type

OverrideCast see Override and AddMethodCast

func (*BaseType) OverrideUserData

func (m *BaseType) OverrideUserData(op Operate, help string, act func(s *LState, data *LUserData) int) Type

OverrideUserData see Override and AddMethodUserData

func (*BaseType) PreLoad

func (m *BaseType) PreLoad(l *LState)

func (*BaseType) PreloadSubModule

func (m *BaseType) PreloadSubModule(l *LState, t *LTable)

func (*BaseType) SafeFun added in v0.1.11

func (m *BaseType) SafeFun(name string, help string, fn LGFunction) Type

SafeFun warp with SafeFunc

func (*BaseType) SafeMethod added in v0.1.11

func (m *BaseType) SafeMethod(name string, help string, value LGFunction) Type

SafeMethod warp with SafeFunc

func (*BaseType) SafeOverride added in v0.1.11

func (m *BaseType) SafeOverride(op Operate, help string, fn LGFunction) Type

SafeOverride wrap with SafeFunc

func (*BaseType) Type

func (m *BaseType) Type() reflect.Type

type Chunk

type Chunk = *FunctionProto

type Mod

type Mod struct {
	Name string //Name of Modular
	Top  bool   //is top level
	Help string //Help information of this Modular
	// contains filtered or unexported fields
}

Mod define a Mod only contains Functions and value fields,maybe with submodules

func NewModule

func NewModule(name string, help string, top bool) *Mod

NewModule create New Mod

func (*Mod) AddField

func (m *Mod) AddField(name string, help string, value LValue) Module

AddField add value field to this Modular

@name the field name

@help help string, if empty will not generate into help

@value the field value

func (*Mod) AddFunc

func (m *Mod) AddFunc(name string, help string, fn LGFunction) Module

AddFunc add function to this Modular

@name function name, must match lua limitation

@help help string, if empty will not generate into help

@fn the LGFunction

func (*Mod) AddModule

func (m *Mod) AddModule(mod Modular) Module

AddModule add sub-module to this Modular

@mod the Mod **Note** must with TopLevel false.

func (*Mod) GetName

func (m *Mod) GetName() string

func (*Mod) PreLoad

func (m *Mod) PreLoad(l *LState)

func (*Mod) PreloadSubModule

func (m *Mod) PreloadSubModule(l *LState, t *LTable)

func (*Mod) SafeFun added in v0.1.11

func (m *Mod) SafeFun(name string, help string, fn LGFunction) Module

SafeFun warp with SafeFunc

func (*Mod) TopLevel

func (m *Mod) TopLevel() bool

type Modular

type Modular interface {
	//TopLevel dose this Mod is top level,means should not be submodule
	TopLevel() bool
	//PreLoad load as global Mod
	PreLoad(l *lua.LState)
	//PreloadSubModule use for submodule loading, Should NOT invoke manually
	PreloadSubModule(l *lua.LState, t *lua.LTable)
	//GetName the unique name (if is a Top Level Modular)
	GetName() string
}

Modular shared methods make it a Modular

type Module

type Module interface {
	Modular
	// AddFunc add function to this Module
	//
	// @name function name, must match lua limitation
	//
	// @help help string, if empty will generate just Module.Function as help
	//
	// @fn the LGFunction
	AddFunc(name string, help string, fn LGFunction) Module

	//SafeFun warp with SafeFunc,see AddFunc for detail
	SafeFun(name string, help string, value LGFunction) Module

	// AddField add value field to this Module (static value)
	AddField(name string, help string, value LValue) Module
	// AddModule add submodule to this Module
	//
	// @mod the Mod , requires Mod.TopLevel is false.
	AddModule(mod Modular) Module
}

type Operate

type Operate int
const (
	OPERATE_INVALID   Operate = iota
	OPERATE_ADD               // +
	OPERATE_SUB               // -
	OPERATE_MUL               // *
	OPERATE_DIV               // /
	OPERATE_UNM               // -
	OPERATE_MOD               // %
	OPERATE_POW               // ^
	OPERATE_CONCAT            // ..
	OPERATE_EQ                // ==
	OPERATE_LT                // <
	OPERATE_LE                // <=
	OPERATE_LEN               // #
	OPERATE_INDEX             // []
	OPERATE_NEWINDEX          // []=
	OPERATE_TO_STRING         // tostring
	OPERATE_CALL              // ()
)

noinspection GoSnakeCaseUsage,GoUnusedConst

type Operator

type Operator = func(s *Vm) error

Operator operate stored state

type Type

type Type interface {
	Modular
	// Type the real go type
	Type() reflect.Type
	// New create new instance
	New(l *LState, val interface{}) int
	// NewValue create new LValue
	NewValue(l *LState, val interface{}) *LUserData
	// CanCast check the type can use cast (when construct with NewTypeCast)
	CanCast() bool
	// CastVar  cast value on stack (already have error processed)
	CastVar(s *LState, n int) interface{}
	// Cast nil if not current type else the value
	Cast(u *LUserData) interface{}

	// AddFunc static function
	AddFunc(name string, help string, fn LGFunction) Type
	//SafeFun warp with SafeFunc
	SafeFun(name string, help string, value LGFunction) Type

	// AddField static field
	AddField(name string, help string, value LValue) Type
	//SafeMethod warp with SafeFunc
	SafeMethod(name string, help string, value LGFunction) Type
	// AddMethod add method to this type which means instance method.
	AddMethod(name string, help string, value LGFunction) Type

	// AddMethodUserData add method to this type which means instance method, with auto extract first argument.
	AddMethodUserData(name string, help string, act func(s *LState, u *LUserData) int) Type

	// AddMethodCast prechecked type (only create with NewTypeCast).
	AddMethodCast(name string, help string, act func(s *LState, i interface{}) int) Type

	// Override override an operator
	Override(op Operate, help string, fn LGFunction) Type

	//SafeOverride warp with SafeFunc
	SafeOverride(op Operate, help string, value LGFunction) Type

	// OverrideUserData see Override and AddMethodUserData
	OverrideUserData(op Operate, help string, act func(s *LState, u *LUserData) int) Type

	// OverrideCast see Override and AddMethodCast
	OverrideCast(op Operate, help string, act func(s *LState, i interface{}) int) Type
}

type Vm

type Vm struct {
	*LState
	// contains filtered or unexported fields
}

Vm take Env Snapshot to protect from Global pollution

func Get

func Get() *Vm

Get LState from statePool

func (*Vm) OpenLibsWithout

func (s *Vm) OpenLibsWithout(names ...string) *Vm

OpenLibsWithout open gopher-lua libs but filter some by name @fluent

func (*Vm) Polluted

func (s *Vm) Polluted() (r bool)

Polluted check if the Env is polluted

func (*Vm) Reset

func (s *Vm) Reset() (r *Vm)

Reset reset Env @fluent

func (*Vm) Snapshot

func (s *Vm) Snapshot() *Vm

Snapshot take snapshot for Env

func (*Vm) TabChildEqualTo

func (s *Vm) TabChildEqualTo(t1 *LTable, t2 *LTable, keys ...string) (r bool)

func (*Vm) TabCopyChildNew

func (s *Vm) TabCopyChildNew(f *LTable, keys ...string) *LTable

func (*Vm) TabCopyNew

func (s *Vm) TabCopyNew(f *LTable) *LTable

func (*Vm) TabEqualTo

func (s *Vm) TabEqualTo(t1 *LTable, t2 *LTable) (r bool)

type VmPool

type VmPool struct {
	// contains filtered or unexported fields
}

VmPool threadsafe LState Pool

func CreatePool

func CreatePool() *VmPool

func CreatePoolWith

func CreatePoolWith(ctor func() *LState) *VmPool

CreatePoolWith create pool with user defined constructor

GluMod will auto registered

func (*VmPool) Get

func (pl *VmPool) Get() *Vm

func (*VmPool) Put

func (pl *VmPool) Put(L *Vm)

func (*VmPool) Recycle

func (pl *VmPool) Recycle(max int)

Recycle the pool space to max size

func (*VmPool) Shutdown

func (pl *VmPool) Shutdown()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL