Giter VIP home page Giter VIP logo

wrengo's People

Contributors

crazyinfin8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

wrengo's Issues

Bug in ListHandle.Get(index)

Consider this simple example where I'm trying to pass a list from Wren to Go:

/* list_trial.wren */
class Lst {
    foreign static send(a)
}

var a = (1..10).toList
var b = Lst.send(a)
System.print(b)
/* list_trial.go */
package main
 
import (
    "fmt"
    wren "github.com/crazyinfin8/WrenGo"
)
  
func send(vm *wren.VM, parameters []any) (any, error) {
    handle := parameters[1].(*wren.ListHandle)
    count, _ := handle.Count()
    fmt.Println("The list count is", count)
    n := 1  // seg faults if this is changed to 2
    for i := 0; i < n; i++ {
        ifc, _ := handle.Get(i)
        fmt.Println(ifc)
    }
    handle.Free()
    return nil, nil
}

func main() {
    vm := wren.NewVM()
    fileName := "list_trial.wren"
    methodMap := wren.MethodMap{"static send(_)": send}
    classMap := wren.ClassMap{"Lst": wren.NewClass(nil, nil, methodMap)}
    module := wren.NewModule(classMap)
    vm.SetModule(fileName, module)
    vm.InterpretFile(fileName)
    vm.Free()
}

When run as it stands (Go 1.18.2, Ubuntu 22.04, AMD64), the output is:

The list count is 10
1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

but, if I change the variable 'n' to 2, it seg faults after printing '1' on line 473 of vm.go.
The code for the ListHandle.Get(index) method which contains that line is:

// Get tries to return the value in the Wren list at the index `index`
func (h *ListHandle) Get(index int) (interface{}, error) {
	handle := h.Handle()
	if handle.handle == nil {
		return nil, &NilHandleError{}
	}
	vm := h.VM()
	C.wrenEnsureSlots(vm.vm, 2)
	vm.setSlotValue(handle, 0)
	if index < 0 || index >= int(C.wrenGetListCount(vm.vm, C.int(index))) {  // line 473
		return nil, &OutOfBounds{List: h, Index: index}
	}
	C.wrenGetListElement(vm.vm, 0, C.int(index), 1)
	return vm.getSlotValue(1), nil
}

So the problem appears to be that C.wrenGetListCount is trying to find the list in slot 'index' when it is in fact in slot 0.

However, I've no idea why my send method is returning the full list rather than null. Perhaps I could leave @CrazyInfin8 to figure that one out.

Nums passed to foreign methods.

One other thing I've just noticed is that Nums passed as arguments to Wren foreign methods are coming across to Go as float32's rather than float64's which is losing accuracy.

This seems to be as a result of this function in vm.go:

func (vm *VM) getSlotValue(slot int) (value interface{}) {
	cSlot := C.int(slot)
	switch C.wrenGetSlotType(vm.vm, C.int(cSlot)) {
	//...
	case C.WREN_TYPE_NUM:
		return float32(C.wrenGetSlotDouble(vm.vm, cSlot))
	//...
	}
}

I don't understand why this is necessary when Nums are essentially float64's and slots can handle doubles just fine.

Some minor issues

Firstly, thanks for creating this which is a useful adjunct for those of us who like to program in Go :)

Just three minor issues I've encountered so far.

Firstly, when I'm using Wren-cli, if I import a library module like this:

import "/someModule" for SomeClass

then Wren-cli would look for the file "./someModule.wren" and find it because I always copy such modules to the same directory as the startup script.

However, that's not happening with WrenGo. Either I have to use the library's full name (which is awkward if that in turn imports other modules) or I need to change the configuration like so:

cfg := wren.NewConfig()
cfg.LoadModuleFn = func(vm *wren.VM, name string) (string, bool) {
    if !strings.HasPrefix(name, ".") {
        name = "." + name
    }
    if !strings.HasSuffix(name, ".wren") {
        name += ".wren"
    }
    return wren.DefaultModuleLoader(vm, name)
}
vm := cfg.NewVM()

Although this is not a big problem, it would be nice if the DefaultModuleLoader function could do it for us.

Secondly, I've noticed that when I set up a Go function to represent a static foreign method in Wren, 'parameters' includes an extra parameter (the first one) which is a *wren.Handle and is possibly a meta-class reference or similar. This had me puzzled for a while and it would be useful if there could be a mention in the docs about the extra parameter being passed.

Finally, I couldn't figure out how to wire up a foreign property in Wren i.e. one with no following parentheses. Again no big problem as I can always add the parentheses but if there is a way to do it perhaps you could elucidate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.