gruby

package module
v0.0.0-...-f69614b Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2024 License: MIT Imports: 10 Imported by: 0

README

Gruby - Go bindings to mruby

This is a fork of amazing go-mruby. I'm not sure if I want and I can maintain it for a long time, but I updated it to support mruby 3.3 and go 1.22.

The project in being heavily refactored and partially rewritten. Backwards compatibility with go-mruby is broken.

gruby provides mruby bindings for Go. This allows Go applications to run a lightweight embedded Ruby VM. Using the mruby library, Go applications can call Ruby code, and Ruby code can call Go code (that is properly exposed)!

At the time of writing, this is the most comprehensive mruby library for Go by far. It is also the only mruby library for Go that enables exposing Go functions to Ruby as well as being able to generically convert complex Ruby types into Go types. Our goal is to implement all of the mruby API.

Project Status: The major portions of the mruby API are implemented, but the mruby API is huge. If there is something that is missing, please issue a pull request and I'd be happy to add it! We're also not yet ready to promise API backwards compatibility on a Go-level, but we're getting there.

Installation

Installation is a little trickier than a standard Go library, but not by much. You can't simply go get this library, unfortunately. This is because mruby must first be built. We don't ship a pre-built version of mruby because the build step of mruby is important in customizing what aspects of the standard library you want available, as well as any other extensions.

To build mruby, we've made it very easy. You will need the following packages available on your host operating system:

  • bison
  • flex
  • ruby 3.x

Then just type:

$ make

This will download mruby, compile it, and run the tests for gruby, verifying that your build is functional. By default, gruby will download and build a default version of mruby, but this is customizable.

Compiling/installing the gruby library should work on Linux, Mac OS X, and Windows. On Windows, msys is the only supported build toolchain (same as Go itself).

Due to this linking, it is strongly recommended that you vendor this repository and bake our build system into your process.

Customizing the mruby Compilation

You can customize the mruby compilation by setting a couple environmental variables prior to calling make:

  • MRUBY_COMMIT is the git ref that will be checked out for gruby. This defaults to to a recently tagged version. Many versions before 1.2.0 do not work with gruby. It is recommend you explicitly set this to a ref that works for you to avoid any changes in this library later.

  • MRUBY_CONFIG is the path to a build_config.rb file used to configure how mruby is built. If this is not set, gruby will use the default build config that comes with gruby. You can learn more about configuring the mruby build here.

Usage

gruby exposes the mruby API in a way that is idiomatic Go, so that it is comfortable to use by a standard Go programmer without having intimate knowledge of how mruby works.

For usage examples and documentation, please see the gruby GoDoc, which we keep up to date and full of examples.

For a quick taste of what using gruby looks like, though, we provide an example below:

package main

import (
	"fmt"

	"github.com/zhulik/gruby"
)

func main() {
	grb := gruby.New()
	defer grb.Close()

	// Our custom function we'll expose to Ruby. The first return
	// value is what to return from the func and the second is an
	// exception to raise (if any).
	addFunc := func(grb *gruby.GRuby, self gruby.Value) (gruby.Value, gruby.Value) {
		args := grb.GetArgs()
		return gruby.ToRuby(grb, gruby.ToGo[int](args[0])+gruby.ToGo[int](args[1])), nil
	}

	// Lets define a custom class and a class method we can call.
	class := grb.DefineClass("Example", nil)
	class.DefineClassMethod("add", addFunc, gruby.ArgsReq(2))

	// Let's call it and inspect the result
	result, err := grb.LoadString(`Example.add(12, 30)`)
	if err != nil {
		panic(err.Error())
	}

	// This will output "Result: 42"
	fmt.Printf("Result: %s\n", result.String())
}

Documentation

Index

Examples

Constants

View Source
const (
	MethodTypeInstance = iota
	MethodTypeClass
)
View Source
const (
	// TypeFalse is `false`
	TypeFalse = ValueType(C.MRB_TT_FALSE)
	// TypeTrue is `true`
	TypeTrue = ValueType(C.MRB_TT_TRUE)
	// TypeFloat is any floating point number such as 1.2, etc.
	TypeFloat = ValueType(C.MRB_TT_FLOAT)
	// TypeFixnum is fixnums, or integers for this case.
	TypeFixnum = ValueType(C.MRB_TT_FIXNUM)
	// TypeSymbol is for entities in ruby that look like `:this`
	TypeSymbol = ValueType(C.MRB_TT_SYMBOL)
	// TypeUndef is a value internal to ruby for uninstantiated vars.
	TypeUndef = ValueType(C.MRB_TT_UNDEF)
	// TypeCptr is a void*
	TypeCptr = ValueType(C.MRB_TT_CPTR)
	// TypeFree is ?
	TypeFree = ValueType(C.MRB_TT_FREE)
	// TypeClass is the base class of all classes.
	TypeObject = ValueType(C.MRB_TT_OBJECT)
	// TypeClass is the base class of all classes.
	TypeClass = ValueType(C.MRB_TT_CLASS)
	// TypeModule is the base class of all Modules.
	TypeModule = ValueType(C.MRB_TT_MODULE)
	// TypeIClass is ?
	TypeIClass = ValueType(C.MRB_TT_ICLASS)
	// TypeSClass is ?
	TypeSClass = ValueType(C.MRB_TT_SCLASS)
	// TypeProc are procs (concrete block definitons)
	TypeProc = ValueType(C.MRB_TT_PROC)
	// TypeArray is []
	TypeArray = ValueType(C.MRB_TT_ARRAY)
	// TypeHash is { }
	TypeHash = ValueType(C.MRB_TT_HASH)
	// TypeString is ""
	TypeString = ValueType(C.MRB_TT_STRING)
	// TypeRange is (0..x)
	TypeRange = ValueType(C.MRB_TT_RANGE)
	// TypeException is raised when using the raise keyword
	TypeException = ValueType(C.MRB_TT_EXCEPTION)
	// TypeEnv is for getenv/setenv etc
	TypeEnv = ValueType(C.MRB_TT_ENV)
	// TypeData is ?
	TypeData = ValueType(C.MRB_TT_DATA)
	// TypeFiber is for members of the Fiber class
	TypeFiber = ValueType(C.MRB_TT_FIBER)
	// TypeIsStruct is ?
	TypeIsStruct = ValueType(C.MRB_TT_STRUCT)
	// TypeMaxBreak is ?
	TypeBreak = ValueType(C.MRB_TT_BREAK)
	// TypeMaxDefine is ?
	TypeMaxDefine = ValueType(C.MRB_TT_MAXDEFINE)
	// TypeNil is nil
	TypeNil ValueType = 0xffffffff
)

Variables

View Source
var (
	ErrValueMustBePointer = errors.New("result must be a pointer")
	ErrUnknownType        = errors.New("unknown type")
	ErrNonStringKeys      = errors.New("keys must be strings")
	ErrInvalidField       = errors.New("field is not valid")
)
View Source
var ErrEmptyArgs = errors.New("args must be non-empty and have a proc at the end")

Functions

func Decode

func Decode(out interface{}, v Value) error

Decode converts the Ruby value to a Go value.

The Decode process may call Ruby code and may generate Ruby garbage, but it collects all of its own garbage. You don't need to GC around this.

See the tests (decode_test.go) for detailed and specific examples of how this function decodes. Basic examples are also available here and in the README.

For primitives, the decoding process is likely what you expect. For Ruby, this is booleans, strings, fixnums, and floats. These map directly to effectively equivalent Go types: bool, string, int, float64. Hash and Arrays can map directly to maps and slices in Go, and Decode will handle this as you expect.

The only remaining data type in Go is a struct. A struct in Go can map to any object in Ruby. If the data in Ruby is a hash, then the struct keys will map directly to the hash keys. If the data in Ruby is an object, then one of two things will be done. First: if the object responds to the `to_gomruby` function, then this will be called and the resulting value is expected to be a Hash and will be used to decode into the struct. If the object does NOT respond to that function, then any struct fields will invoke the corresponding Ruby method to attain the value.

Note that with structs you can use the `mruby` tag to specify the Hash key or method name to call. Example:

type Foo struct {
    Field string `mruby:"read_field"`
}
Example
package main

import (
	"fmt"

	"github.com/zhulik/gruby"
)

func main() {
	grb := gruby.Must(gruby.New())
	defer grb.Close()

	// Our custom function we'll expose to Ruby
	var logData interface{}
	logFunc := func(grb *gruby.GRuby, self gruby.Value) (gruby.Value, gruby.Value) {
		args := grb.GetArgs()
		if err := gruby.Decode(&logData, args[0]); err != nil {
			panic(err)
		}

		return nil, nil
	}

	// Lets define a custom class and a class method we can call.
	class := grb.DefineClass("Example", nil)
	class.DefineClassMethod("log", logFunc, gruby.ArgsReq(1))

	// Let's call it and inspect the result
	if _, err := grb.LoadString(`Example.log({"foo" => "bar"})`); err != nil {
		panic(err)
	}

	fmt.Printf("Result: %v\n", logData)
}
Output:

Result: map[foo:bar]

func Must

func Must[T any](val T, err error) T

func MustToGo

func MustToGo[T SupportedTypes](value Value) T

func MustToGoArray

func MustToGoArray[T SupportedTypes](array Values) []T

func ToGo

func ToGo[T SupportedTypes](value Value) (T, error)

func ToGoArray

func ToGoArray[T SupportedTypes](array Values) ([]T, error)

TODO: Must version

func ToGoMap

func ToGoMap[K SupportedComparables, V SupportedTypes](hash Hash) (map[K]V, error)

TODO: Must version

Types

type ArenaIndex

type ArenaIndex int

ArenaIndex represents the index into the arena portion of the GC.

See ArenaSave for more information.

type ArgSpec

type ArgSpec C.mrb_aspec

ArgSpec defines how many arguments a function should take and what kind. Multiple ArgSpecs can be combined using the "|" operator.

func ArgsAny

func ArgsAny() ArgSpec

ArgsAny allows any number of arguments.

func ArgsArg

func ArgsArg(r, o int) ArgSpec

ArgsArg says the given number of arguments are required and the second number is optional.

func ArgsBlock

func ArgsBlock() ArgSpec

ArgsBlock says it takes a block argument.

func ArgsNone

func ArgsNone() ArgSpec

ArgsNone says it takes no arguments.

func ArgsOpt

func ArgsOpt(n int) ArgSpec

ArgsOpt says that the given number of arguments are optional.

func ArgsReq

func ArgsReq(n int) ArgSpec

ArgsReq says that the given number of arguments are required.

type Class

type Class struct {
	Value
	// contains filtered or unexported fields
}

Class is a class in gruby. To obtain a Class, use DefineClass or one of the variants on the GRuby structure.

func (*Class) DefineClassMethod

func (c *Class) DefineClassMethod(name string, cb Func, spec ArgSpec)

DefineClassMethod defines a class-level method on the given class.

func (*Class) DefineConst

func (c *Class) DefineConst(name string, value Value)

DefineConst defines a constant within this class.

func (*Class) DefineMethod

func (c *Class) DefineMethod(name string, cb Func, spec ArgSpec)

DefineMethod defines an instance method on the class.

func (*Class) New

func (c *Class) New(args ...Value) (Value, error)

New instantiates the class with the given args.

func (*Class) String

func (c *Class) String() string

String returns the "to_s" result of this value.

type CompileContext

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

CompileContext represents a context for code compilation.

CompileContexts keep track of things such as filenames, line numbers, as well as some settings for how to parse and execute code.

Example
package main

import (
	"fmt"

	"github.com/zhulik/gruby"
)

func main() {
	grb := gruby.Must(gruby.New())
	defer grb.Close()

	ctx1 := gruby.NewCompileContext(grb)
	defer ctx1.Close()
	ctx1.SetFilename("foo.rb")

	ctx2 := gruby.NewCompileContext(grb)
	defer ctx2.Close()
	ctx2.SetFilename("bar.rb")

	parser := gruby.NewParser(grb)
	defer parser.Close()

	if _, err := parser.Parse("def foo; bar; end", ctx1); err != nil {
		panic(err)
	}
	code1 := parser.GenerateCode()

	if _, err := parser.Parse("def bar; 42; end", ctx2); err != nil {
		panic(err)
	}
	code2 := parser.GenerateCode()

	if _, err := grb.Run(code1, nil); err != nil {
		panic(err)
	}

	if _, err := grb.Run(code2, nil); err != nil {
		panic(err)
	}

	result, err := grb.LoadString("foo")
	if err != nil {
		panic(err)
	}

	fmt.Printf("Result: %s\n", result)
}
Output:

Result: 42

func NewCompileContext

func NewCompileContext(grb *GRuby) *CompileContext

NewCompileContext constructs a *CompileContext from a *GRuby

func (*CompileContext) CaptureErrors

func (c *CompileContext) CaptureErrors(yes bool)

CaptureErrors toggles the capture errors feature of the parser, which swallows errors. This allows repls and other partial parsing tools (formatters, f.e.) to function.

func (*CompileContext) Close

func (c *CompileContext) Close()

Close the context, freeing any resources associated with it.

This is safe to call once the context has been used for parsing/loading any Ruby code.

func (*CompileContext) Filename

func (c *CompileContext) Filename() string

Filename returns the filename associated with this context.

func (*CompileContext) SetFilename

func (c *CompileContext) SetFilename(f string)

SetFilename sets the filename associated with this compilation context.

Code parsed under this context will be from this file.

type ExceptionError

type ExceptionError struct {
	Value
	File      string
	Line      int
	Message   string
	Backtrace []string
}

ExceptionError is a special type of value that represents an error and implements the Error interface.

func (*ExceptionError) Error

func (e *ExceptionError) Error() string

type Func

type Func func(grb *GRuby, self Value) (Value, Value)

Func is the signature of a function in Go that you use to expose to Ruby code.

The first return value is the actual return value for the code.

The second return value is an exception, if any. This will be raised.

type GRuby

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

GRuby represents a single instance of gruby.

func New

func New(mutators ...Mutator) (*GRuby, error)

New creates a new instance of GRuby, representing the state of a single Ruby VM. Calls mutators one after another against newly created instance. If a mutator fails, closes the mruby instance and returns an error.

When you're finished with the VM, clean up all resources it is using by calling the Close method.

func (*GRuby) ArenaRestore

func (g *GRuby) ArenaRestore(idx ArenaIndex)

ArenaRestore restores the arena index so the objects between the save and this point can be garbage collected in the future.

See ArenaSave for more documentation.

func (*GRuby) ArenaSave

func (g *GRuby) ArenaSave() ArenaIndex

ArenaSave saves the index into the arena.

Restore the arena index later by calling ArenaRestore.

The arena is where objects returned by functions such as LoadString are stored. By saving the index and then later restoring it with ArenaRestore, these objects can be garbage collected. Otherwise, the objects will never be garbage collected.

The recommended usage pattern for memory management is to save the arena index prior to any Ruby execution, to turn the resulting Ruby value into Go values as you see fit, then to restore the arena index so that GC can collect any values.

Of course, when Close() is called, all objects in the arena are garbage collected anyways, so if you're only calling mruby for a short period of time, you might not have to worry about saving/restoring the arena.

func (*GRuby) Backtrace

func (g *GRuby) Backtrace() []string

When called from a instanceMethods defined in Go, returns current ruby backtrace.

func (*GRuby) CalledFromFile

func (g *GRuby) CalledFromFile() string

When called from a method defined in Go, returns a full name of a file the method was called from. Currently implemented using the backtrace. TODO: a better way?

func (*GRuby) Class

func (g *GRuby) Class(name string, super *Class) *Class

Class returns the class with the kgiven name and superclass. Note that if you call this with a class that doesn't exist, mruby will abort the application (like a panic, but not a Go panic).

super can be nil, in which case the Object class will be used.

func (*GRuby) Close

func (g *GRuby) Close()

Close a Gruby, this must be called to properly free resources, and should only be called once.

func (*GRuby) ConstDefined

func (g *GRuby) ConstDefined(name string, scope Value) bool

ConstDefined checks if the given constant is defined in the scope.

This should be used, for example, before a call to Class, because a failure in Class will crash your program (by design). You can retrieve the Value of a Class by calling Value().

func (*GRuby) DefineClass

func (g *GRuby) DefineClass(name string, super *Class) *Class

DefineClass defines a new top-level class.

If super is nil, the class will be defined under Object.

Example
package main

import (
	"fmt"

	"github.com/zhulik/gruby"
)

func main() {
	grb := gruby.Must(gruby.New())
	defer grb.Close()

	// Our custom function we'll expose to Ruby
	addFunc := func(grb *gruby.GRuby, self gruby.Value) (gruby.Value, gruby.Value) {
		args := grb.GetArgs()
		return gruby.MustToRuby(grb, gruby.MustToGo[int](args[0])+gruby.MustToGo[int](args[1])), nil
	}

	// Lets define a custom class and a class method we can call.
	class := grb.DefineClass("Example", nil)
	class.DefineClassMethod("add", addFunc, gruby.ArgsReq(2))

	// Let's call it and inspect the result
	result, err := grb.LoadString(`Example.add(12, 30)`)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Result: %s\n", result.String())
}
Output:

Result: 42

func (*GRuby) DefineClassUnder

func (g *GRuby) DefineClassUnder(name string, super *Class, outer *Class) *Class

DefineClassUnder defines a new class under another class.

This is, for example, how you would define the World class in `Hello::World` where Hello is the "outer" class.

func (*GRuby) DefineModule

func (g *GRuby) DefineModule(name string) *Class

DefineModule defines a top-level module.

func (*GRuby) DefineModuleUnder

func (g *GRuby) DefineModuleUnder(name string, outer *Class) *Class

DefineModuleUnder defines a module under another class/module.

func (*GRuby) DisableGC

func (g *GRuby) DisableGC()

DisableGC disables the garbage collector for this mruby instance. It returns true if it was previously disabled.

func (*GRuby) EnableGC

func (g *GRuby) EnableGC()

EnableGC enables the garbage collector for this mruby instance. It returns true if garbage collection was previously disabled.

func (*GRuby) FalseValue

func (g *GRuby) FalseValue() Value

FalseValue returns a Value for "false"

func (*GRuby) FullGC

func (g *GRuby) FullGC()

FullGC executes a complete GC cycle on the VM.

func (*GRuby) GetArgs

func (g *GRuby) GetArgs() Values

GetArgs returns all the arguments that were given to the currnetly called function (currently on the stack).

func (*GRuby) GetGlobalVariable

func (g *GRuby) GetGlobalVariable(name string) Value

GetGlobalVariable returns the value of the global variable by the given name.

func (*GRuby) IncrementalGC

func (g *GRuby) IncrementalGC()

IncrementalGC runs an incremental GC step. It is much less expensive than a FullGC, but must be called multiple times for GC to actually happen.

This function is best called periodically when executing Ruby in the VM many times (thousands of times).

func (*GRuby) KernelModule

func (g *GRuby) KernelModule() *Class

KernelModule returns the Kernel top-level module.

func (*GRuby) LiveObjectCount

func (g *GRuby) LiveObjectCount() int

LiveObjectCount returns the number of objects that have not been collected (aka, alive).

func (*GRuby) LoadFile

func (g *GRuby) LoadFile(path string, content string) (bool, *CompileContext, error)

func (*GRuby) LoadString

func (g *GRuby) LoadString(code string) (Value, error)

LoadString loads the given code, executes it, and returns its final value that it might return.

func (*GRuby) LoadStringWithContext

func (g *GRuby) LoadStringWithContext(code string, ctx *CompileContext) (Value, error)

LoadStringWith loads the given code, executes it within the given context, and returns its final value that it might return.

func (*GRuby) Module

func (g *GRuby) Module(name string) *Class

Module returns the named module as a *Class. If the module is invalid, NameError is triggered within your program and SIGABRT is sent to the application.

func (*GRuby) NilValue

func (g *GRuby) NilValue() Value

NilValue returns "nil"

func (*GRuby) ObjectClass

func (g *GRuby) ObjectClass() *Class

ObjectClass returns the Object top-level class.

func (*GRuby) Run

func (g *GRuby) Run(v Value, self Value) (Value, error)

Run executes the given value, which should be a proc type.

If you're looking to execute code directly a string, look at LoadString.

If self is nil, it is set to the top-level self.

func (*GRuby) RunWithContext

func (g *GRuby) RunWithContext(v Value, self Value, stackKeep int) (int, Value, error)

RunWithContext is a context-aware parser (aka, it does not discard state between runs). It returns a magic integer that describes the stack in place, so that it can be re-used on the next call. This is how local variables can traverse ruby parse invocations.

Otherwise, it is very similar in function to Run()

func (*GRuby) SetGlobalVariable

func (g *GRuby) SetGlobalVariable(name string, value Value)

SetGlobalVariable sets the value of the global variable by the given name.

func (*GRuby) TopSelf

func (g *GRuby) TopSelf() Value

TopSelf returns the top-level `self` value.

func (*GRuby) TrueValue

func (g *GRuby) TrueValue() Value

TrueValue returns a Value for "true"

func (*GRuby) Yield

func (g *GRuby) Yield(block Value, args ...Value) (Value, error)

Yield yields to a block with the given arguments.

This should be called within the context of a Func.

type GValue

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

GValue is a "value" internally in gruby. A "value" is what mruby calls basically anything in Ruby: a class, an object (instance), a variable, etc.

func (*GValue) CValue

func (v *GValue) CValue() C.mrb_value

CValue returns underlying mrb_value.

func (*GValue) Call

func (v *GValue) Call(method string, args ...Value) (Value, error)

Call calls a method with the given name and arguments on this value.

func (*GValue) CallBlock

func (v *GValue) CallBlock(method string, args ...Value) (Value, error)

CallBlock is the same as call except that it expects the last argument to be a Proc that will be passed into the function call. It is an error if args is empty or if there is no block on the end.

func (*GValue) Class

func (v *GValue) Class() *Class

Class returns the *Class of a value.

func (*GValue) GCProtect

func (v *GValue) GCProtect()

GCProtect protects this value from being garbage collected.

func (*GValue) GRuby

func (v *GValue) GRuby() *GRuby

GRuby returns the GRuby state for this value.

func (*GValue) GetInstanceVariable

func (v *GValue) GetInstanceVariable(variable string) Value

GetInstanceVariable gets an instance variable on this value.

func (*GValue) IsDead

func (v *GValue) IsDead() bool

IsDead tells you if an object has been collected by the GC or not.

func (*GValue) SetInstanceVariable

func (v *GValue) SetInstanceVariable(variable string, value Value)

SetInstanceVariable sets an instance variable on this value.

func (*GValue) SetProcTargetClass

func (v *GValue) SetProcTargetClass(c *Class)

SetProcTargetClass sets the target class where a proc will be executed when this value is a proc.

func (*GValue) SingletonClass

func (v *GValue) SingletonClass() *Class

SingletonClass returns the singleton class (a class isolated just for the scope of the object) for the given value.

func (*GValue) String

func (v *GValue) String() string

String returns the "to_s" result of this value.

func (*GValue) Type

func (v *GValue) Type() ValueType

Type returns the ValueType of the GValue. See the constants table.

type Hash

type Hash struct {
	Value
}

Hash represents an GValue that is a Hash in Ruby.

A Hash can be obtained by calling the Hash function on GValue.

func (*Hash) Delete

func (h *Hash) Delete(key Value) Value

Delete deletes a key from the hash, returning its existing value, or nil if there wasn't a value.

func (*Hash) Get

func (h *Hash) Get(key Value) Value

Get reads a value from the hash.

func (*Hash) Keys

func (h *Hash) Keys() Values

Keys returns the array of keys that the Hash has as Values.

func (*Hash) Set

func (h *Hash) Set(key, val Value)

Set sets a value on the hash

type MethodType

type MethodType = int

type Mutator

type Mutator func(*GRuby) error

Mutator is function that is supposed to be passed to New. New will call mutators one after another. They can be used to register classes and functions provided by external packages.

type Parser

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

Parser is a parser for Ruby code.

func NewParser

func NewParser(grb *GRuby) *Parser

NewParser initializes the resources for a parser.

Make sure to Close the parser when you're done with it.

func (*Parser) Close

func (p *Parser) Close()

Close releases any resources associated with the parser.

func (*Parser) GenerateCode

func (p *Parser) GenerateCode() Value

GenerateCode takes all the internal parser state and generates executable Ruby code, returning the callable proc.

func (*Parser) Parse

func (p *Parser) Parse(code string, cctx *CompileContext) ([]*ParserMessage, error)

Parse parses the code in the given context, and returns any warnings or errors from parsing.

The CompileContext can be nil to not set a context.

type ParserError

type ParserError struct {
	Errors []*ParserMessage
}

ParserError is an error from the parser.

func (ParserError) Error

func (p ParserError) Error() string

func (ParserError) String

func (p ParserError) String() string

type ParserMessage

type ParserMessage struct {
	Col     int
	Line    int
	Message string
}

ParserMessage represents a message from parsing code: a warning or error.

type SupportedComparables

type SupportedComparables interface {
	comparable
	bool | string | int | float32 | float64
}

type SupportedTypes

type SupportedTypes interface {
	SupportedComparables | Hash | Values
}

TODO: make sure all supported types covered in functions.

type Value

type Value interface {
	String() string

	GRuby() *GRuby
	CValue() C.mrb_value

	Type() ValueType
	IsDead() bool
	Class() *Class
	SingletonClass() *Class

	SetInstanceVariable(variable string, value Value)
	GetInstanceVariable(variable string) Value

	Call(method string, args ...Value) (Value, error)
	CallBlock(method string, args ...Value) (Value, error)
}

Value is an interface that should be implemented by anything that can be represents as an mruby value.

func MustToRuby

func MustToRuby[T SupportedTypes](grb *GRuby, value T) Value

func ToRuby

func ToRuby[T SupportedTypes](grb *GRuby, value T) (Value, error)

type ValueMap

type ValueMap map[Value]Value

type ValueType

type ValueType uint32

ValueType is an enum of types that a Value can be and is returned by Value.Type().

type Values

type Values []Value

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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