lua

package module
v0.0.0-...-88f43f8 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2021 License: MIT Imports: 13 Imported by: 1

README

Go Lua Compiler and VM

This is a Lua 5.3 VM and compiler written in Go. This is intended to allow easy embedding into Go programs, with minimal fuss and bother. It can also run in a browser by Webassembly.

This repository is forked from milochristiansen/lua, and I made some incompatible changes. So it's unlikely to be merged into the original repository.

The strftime function and string pattern matching is currently copied from yuin/gopher-lua. It may be rewritten in the future.

Usage

package main

import (
	"ofunc/lua/util"
)

func main() {
	l := util.NewState()
	util.Run(l, "main.lua")
}
local js = require 'js'
local window = js.global

window:setTimeout(function()
	window:alert('Hello world!')
end, 1000)

Please refer to the README for standard libraries.

Dependencies

Modules

  • ioc - Inversion of Control module for Lua.
  • lmodbolt - boltdb/bolt bindings for Lua.
  • lmodhttpclient - http.Client bindings for Lua.
  • lmodmsgpack - MessagePack for Lua.
  • lmodoffice - A simple Lua module for converting various office documents into OOXML format files.
  • lmodxlsx - plandem/xlsx bindings for Lua.
  • mithril - Mithril.js bindings for Lua.
  • stream - A simple lazy list module for Lua.

Missing Stuff

The following standard functions are not available:

  • collectgarbage (not possible, VM uses the Go collector)
  • xpcall (VM has no concept of a message handler)
  • next (I don't need it at this time)
  • load (violates my security policy)
  • dofile (violates my security policy, use require)
  • loadfile (violates my security policy, use require)
  • string.dump (violates my security policy)
  • string.pack (I don't need it at this time, use msgpack)
  • string.packsize (I don't need it at this time, use msgpack)
  • string.unpack (I don't need it at this time, use msgpack)

The following standard modules are not available:

  • package (violates my security policy, use util.AddPath)
  • debug (violates my security policy)
  • coroutine (no coroutine support yet, use goroutine)

The following modules are not implemented exactly as the Lua 5.3 specification requires:

  • math.random (initialize the seed by default using program startup time)
  • os (Go style functions)
  • io (Go style functions)

There are a few things that are implemented exactly as the Lua 5.3 specification requires, where the reference Lua implementation does not follow the specification exactly:

  • The # (length) operator always returns the number of positive integer keys. When the table is a sequence, it's exactly equal to the sequence's length.
  • Modulo operator (%) is implemented the same way most languages implement it, not the way Lua does. This does not matter unless you are using negative operands.

The following core language features are not supported:

  • Hexadecimal floating point literals are not supported at this time.
  • Weak references of any kind are not supported. This is because the VM uses Go's garbage collector, and it does not support weak references.
  • Finalizers are not supported.

TODO

  • More tests.
  • Better error hints.
  • Code optimization.

Documentation

Overview

Go Lua Compiler and VM

This is a Lua 5.3 VM and compiler written in Go. This is intended to allow easy embedding into Go programs, with minimal fuss and bother.

Index

Constants

View Source
const (

	// These exported values are used in calls to Arith
	OpAdd opCode
	OpSub
	OpMul
	OpMod
	OpPow
	OpDiv
	OpIDiv
	OpBinAND
	OpBinOR
	OpBinXOR
	OpBinShiftL
	OpBinShiftR
	OpUMinus
	OpBinNot

	OpEqual
	OpLessThan
	OpLessOrEqual
)
View Source
const (
	// Registry table index
	RegistryIndex = -1000000 - iota
	// Globals table index
	GlobalsIndex
	// To get a specific upvalue use "FirstUpVal-<upvalue index>"
	FirstUpVal
)

Variables

This section is empty.

Functions

This section is empty.

Types

type STypeID

type STypeID int
const (
	STypeUnknown STypeID = iota
	STypeInteger
	STypeFloat
)

func (STypeID) String

func (typ STypeID) String() string

type State

type State struct {
	// Add a native stack trace to errors that have attached stack traces.
	NativeTrace bool
	// contains filtered or unexported fields
}

State is the central arbitrator of all Lua operations.

func NewState

func NewState() *State

NewState creates a new State, ready to use.

func (*State) AbsIndex

func (l *State) AbsIndex(i int) int

AbsIndex converts the given index into an absolute index. Use -1 as the index to get the number of items currently on the stack.

func (*State) Arith

func (l *State) Arith(op opCode)

Arith performs the specified the arithmetic operator with the top two items on the stack (or just the top item for OpUMinus and OpBinNot). The result is pushed onto the stack. This may raise an error if they values are not appropriate for the given operator.

func (*State) Call

func (l *State) Call(args, rtns int)

Call runs a function with the given number of arguments and results. The function must be on the stack just before the first argument. If this raises an error the stack is NOT unwound! Call this only from code that is below a call to PCall unless you want your State to be permanently trashed!

func (*State) Compare

func (l *State) Compare(i1, i2 int, op opCode) bool

Compare performs the specified the comparison operator with the items at the given stack indexes. This may raise an error if they values are not appropriate for the given operator.

func (*State) CompareRaw

func (l *State) CompareRaw(i1, i2 int, op opCode) bool

CompareRaw is exactly like Compare, but without meta-methods.

func (*State) Count

func (l *State) Count(i int) int

Count returns the raw table pairs number.

func (*State) Dump

func (l *State) Dump(i int, strip bool) []byte

Dump converts the Lua function at the given index to a binary chunk. The returned value may be used with LoadBinary to get a function equivalent to the dumped function (but without the original function's up values). Currently the "strip" argument does nothing. This (obviously) only works with Lua functions, trying to dump a native function or a non-function value will raise an error.

func (*State) Error

func (l *State) Error()

Error pops a value off the top of the stack and raises it as an error.

func (*State) ForEach

func (l *State) ForEach(t int, f func() bool)

ForEach is a fancy version of ForEachRaw that respects metamethods (to be specific, __pairs).

func (*State) ForEachRaw

func (l *State) ForEachRaw(t int, f func() bool)

ForEachRaw is a simple wrapper around GetIter and is provided as a convenience. The given function is called once for every item in the table at t. For each call of the function the value is at -1 and the key at -2. You MUST keep the stack balanced inside the function! Do not pop the key and value off the stack before returning! The value returned by the iteration function determines if ForEach should return early. Return false to break, return true to continue to the next iteration.

func (*State) GetIter

func (l *State) GetIter(i int)

GetIter pushes a table iterator onto the stack. If the given value is not a table this will raise an error.

func (*State) GetMetaField

func (l *State) GetMetaField(i int, name string) TypeID

GetMetaField pushes the meta method with the given name for the item at the given index onto the stack, then returns the type of the pushed item. If the item does not have a meta table or does not have the specified method this does nothing and returns TypNil.

func (*State) GetMetaTable

func (l *State) GetMetaTable(i int) bool

GetMetaTable gets the meta table for the value at the given index and pushes it onto the stack. If the value does not have a meta table then this returns false and pushes nothing.

func (*State) GetRaw

func (l *State) GetRaw(i int) interface{}

GetRaw gets the raw data for a Lua value. Lua types use the following mapping:

nil -> nil
number -> int64 or float64
string -> string
bool -> bool
table -> string: "table: <pointer as hexadecimal>"
function -> string: "function: <pointer as hexadecimal>"
userdata -> The raw user data value

func (*State) GetTable

func (l *State) GetTable(i int) TypeID

GetTable reads from the table at the given index, popping the key from the stack and pushing the result. The type of the pushed object is returned. This may raise an error if the value is not a table or is lacking the __index meta method.

func (*State) GetTableRaw

func (l *State) GetTableRaw(i int) TypeID

GetTableRaw is like GetTable except it ignores meta methods. This may raise an error if the value is not a table.

func (*State) Insert

func (l *State) Insert(i int)

Insert takes the item from the TOS and inserts it at the given stack index.

func (*State) IsNil

func (l *State) IsNil(i int) bool

IsNil check if the value at the given index is nil. Nonexistent values are always nil.

func (*State) Length

func (l *State) Length(i int) int

Returns the "length" of the item at the given index, exactly like the "#" operator would. If this calls a meta method it may raise an error if the length is not an integer.

func (*State) LengthRaw

func (l *State) LengthRaw(i int) int

Returns the length of the table or string at the given index. This does not call meta methods. If the value is not a table or string this will raise an error.

func (*State) LoadBinary

func (l *State) LoadBinary(in io.Reader, name string, env int) error

LoadBinary loads a binary chunk into memory and pushes the result onto the stack. If there is an error it is returned and nothing is pushed. Set env to 0 to use the default environment.

func (*State) LoadString

func (l *State) LoadString(src, name string, env int) error

func (*State) LoadText

func (l *State) LoadText(in io.Reader, name string, env int) error

LoadText loads a text chunk into memory and pushes the result onto the stack. If there is an error it is returned and nothing is pushed. Set env to 0 to use the default environment.

func (*State) NewTable

func (l *State) NewTable(as, hs int)

NewTable creates a new table with "as" preallocated array elements and "hs" preallocated hash elements.

func (*State) OptFloat

func (l *State) OptFloat(i int, d float64) float64

OptFloat is the same as ToFloat, except the given default is returned if the value is nil or non-existent.

func (*State) OptInteger

func (l *State) OptInteger(i int, d int64) int64

OptInteger is the same as ToInt, except the given default is returned if the value is nil or non-existent.

func (*State) OptString

func (l *State) OptString(i int, d string) string

OptString is the same as ToString, except the given default is returned if the value is nil or non-existent.

func (*State) PCall

func (l *State) PCall(args, rtns int, trace bool) (msg interface{})

PCall is exactly like Call, except instead of panicking when it encounters an error the error is cleanly recovered and returned. On error the stack is reset to the way it was before the call minus the function and it's arguments, the State may then be reused.

func (*State) Pop

func (l *State) Pop(n int)

Pop removes the top n items from the stack.

func (*State) Preload

func (l *State) Preload(name string, loader func(*State) int)

Preload adds the given loader function for "require".

func (*State) PrintStack

func (l *State) PrintStack()

PrintStack prints some stack information for sanity checking during test runs.

func (*State) Push

func (l *State) Push(v interface{})

Push pushes the given value onto the stack. If the value is not one of nil, float32, float64, int, int32, int64, string or bool, it is converted to a userdata value before being pushed.

func (*State) PushClosure

func (l *State) PushClosure(f func(*State) int, v ...int)

PushClosure pushes a native function as a closure.

func (*State) PushIndex

func (l *State) PushIndex(i int)

PushIndex pushes a copy of the value at the given index onto the stack.

func (*State) STypeOf

func (l *State) STypeOf(i int) STypeID

STypeOf returns the sub-type of the value at the given index.

func (*State) Set

func (l *State) Set(d, s int)

Set sets the value at index d to the value at index s (d = s). Trying to set the registry or an invalid index will do nothing. Setting an absolute index will never fail, the stack will be extended as needed. Be careful not to waste stack space or you could run out of memory! This function is mostly for setting up-values and things like that.

func (*State) SetGlobal

func (l *State) SetGlobal(name string)

SetGlobal pops a value from the stack and sets it as the new value of global name.

func (*State) SetMetaTable

func (l *State) SetMetaTable(i int)

SetMetaTable pops a table from the stack and sets it as the meta table of the value at the given index. If the value is not a userdata or table then the meta table is set for ALL values of that type! If you try to set a metatable that is not a table or try to pass an invalid type this will raise an error.

func (*State) SetTable

func (l *State) SetTable(i int)

SetTable writes to the table at the given index, popping the key and value from the stack. This may raise an error if the value is not a table or is lacking the __newindex meta method. The value must be on TOS, the key TOS-1.

func (*State) SetTableRaw

func (l *State) SetTableRaw(i int)

SetTableRaw is like SetTable except it ignores meta methods. This may raise an error if the value is not a table.

func (*State) SetUpValue

func (l *State) SetUpValue(f, i, v int) bool

SetUpVal sets upvalue "i" in the function at "f" to the value at "v". If the upvalue index is out of range, "f" is not a function, or the upvalue is not closed, false is returned and nothing is done, else returns true and sets the upvalue. Any other functions that share this upvalue will also be affected!

func (*State) ToBoolean

func (l *State) ToBoolean(i int) bool

ToBoolean reads a value from the stack at the given index and interprets it as a boolean.

func (*State) ToFloat

func (l *State) ToFloat(i int) float64

ToFloat reads a floating point value from the stack at the given index. If the value is not an float and cannot be converted to one this may panic.

func (*State) ToInteger

func (l *State) ToInteger(i int) int64

ToInteger reads an integer value from the stack at the given index. If the value is not an integer and cannot be converted to one this may panic.

func (*State) ToString

func (l *State) ToString(i int) string

ToString reads a value from the stack at the given index and formats it as a string. This will call a __tostring metamethod if provided. This is safe if no metamethods are called, but may panic if the metamethod errors out.

func (*State) TryFloat

func (l *State) TryFloat(i int) (float64, error)

TryFloat attempts to read the value at the given index as a floating point number.

func (*State) TryInteger

func (l *State) TryInteger(i int) (int64, error)

TryInteger attempts to read the value at the given index as a integer number.

func (*State) TypeOf

func (l *State) TypeOf(i int) TypeID

TypeOf returns the type of the value at the given index.

type TypeID

type TypeID int
const (
	TypeUnknown TypeID = iota
	TypeNil
	TypeNumber
	TypeString
	TypeBoolean
	TypeTable
	TypeFunction
	TypeUserData
)

func (TypeID) String

func (typ TypeID) String() string

Directories

Path Synopsis
pm
Utility for Lua
Utility for Lua

Jump to

Keyboard shortcuts

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