Scriptable interpreter written in golang

Overview

Anko

GoDoc Reference Build Status Financial Contributors on Open Collective Coverage Go Report Card

Anko is a scriptable interpreter written in Go.

(Picture licensed under CC BY-SA 3.0, photo by Ocdp)

Usage Example - Embedded

package main

import (
	"fmt"
	"log"

	"github.com/mattn/anko/env"
	"github.com/mattn/anko/vm"
)

func main() {
	e := env.NewEnv()

	err := e.Define("println", fmt.Println)
	if err != nil {
		log.Fatalf("Define error: %v\n", err)
	}

	script := `
println("Hello World :)")
`

	_, err = vm.Execute(e, nil, script)
	if err != nil {
		log.Fatalf("Execute error: %v\n", err)
	}

	// output: Hello World :)
}

More examples are located in the GoDoc:

https://godoc.org/github.com/mattn/anko/vm

Usage Example - Command Line

Building

go get github.com/mattn/anko
go install github.com/mattn/anko

Running an Anko script file named script.ank

./anko script.ank

Anko Script Quick Start

// declare variables
x = 1
y = x + 1

// print using outside the script defined println function
println(x + y) // 3

// if else statement
if x < 1 || y < 1 {
	println(x)
} else if x < 1 && y < 1 {
	println(y)
} else {
	println(x + y)
}

// slice
a = []interface{1, 2, 3}
println(a) // [1 2 3]
println(a[0]) // 1

// map
a = map[interface]interface{"x": 1}
println(a) // map[x:1]
a.b = 2
a["c"] = 3
println(a["b"]) // 2
println(a.c) // 3

// struct
a = make(struct {
	A int64,
	B float64
})
a.A = 4
a.B = 5.5
println(a.A) // 4
println(a.B) // 5.5

// function
func a (x) {
	println(x + 1)
}
a(5) // 6

Please note that the master branch is not stable

The master branch language and API may change at any time.

To mitigate breaking changes, please use tagged branches. New tagged branches will be created for breaking changes.

Author

Yasuhiro Matsumoto (a.k.a mattn)

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Issues
  • Add context so we can interrupt channels

    Add context so we can interrupt channels

    Problem: When you have a script that ends with "receive from chan", the script get stuck there forever, and vm.Interrupt(env) is unable to cancel the execution of that script. Example:

    ch = make(chan string)
    <-ch
    

    Solution: I added an optional (e *Env) SetContext(context.Context) *Env function. When you give a context to this function, it will change how it interrupt the code inside the VM. There is 2 main differences

    • The main loop will check for each statement if there is a context, and if it should exit the loop.
    • The channels will now "select" between the ctx.Done() and the channel, instead of just waiting forever on the ch.Recv()

    If there is no context, none of the above apply, the code execute as it was before.

    The test TestInterruptChannelWithContext will break the current master

    opened by alaingilbert 22
  • Added Copy() function on vm.Env

    Added Copy() function on vm.Env

    I need this function to clone a VM in the NeON build tool. As vm.Env fields are not public, I have to fork Anko project to implement this Copy() function. This would be great if this was integrated in the Anko project.

    opened by c4s4 17
  • **Breaking change for types** plus more

    **Breaking change for types** plus more

    Breaking change for types

    Make arrays last two args now optional Changed type to be an expression Type expression converts to string for type lookup DefineType is now local scope Added DefineReflectType Added DefineGlobalType & DefineGlobalReflectType Added make multidimensional array support Improved multidimensional array support Added AddPackage

    opened by MichaelS11 17
  • panic vm.Error instead of plain string

    panic vm.Error instead of plain string

    convertVMFunctionToType panics strings if any error happens, which blocks invokers form acquiring the position where errors occur. If we could panic the raw vm.Error, the invoker will be able to report the line and column of the error. IDEs and programmers will benefit from the change. Thanks. :)

    opened by Berailitz 14
  • goroutine crash silently

    goroutine crash silently

    Any idea how we could make a crash in a goroutine stop the VM ? eg:

    time = import("time")
    for {
      go func() {
        println("before")
        This should stop the VM
        println("will never print")
      }()
      time.Sleep(time.Second)
    }
    

    This program will not crash and will just keep running as if everything is fine. It would be nice to stop the VM in such case, and get back the error.

    My workaround right now is to define a Go function

    ctx, cancel := context.WithCancel(context.Background())
    
    _ = myvm.Define("Go", func(fn func()) {
      go func() {
        defer func() {
          if r := recover(); r != nil {
            println(r)
            cancel()
          }
        }()
        fn()
      }()
    })
    
    myscript := `
    time = import("time")
    for {
      Go(func() {
        println("before")
        This will stop the VM
        println("will never print")
      })
      time.Sleep(time.Second)
    }`
    
    myvm.ExecuteContext(ctx, myscript)
    

    But I have to edit the original anko code to prevent the use of the go keyword.

    opened by alaingilbert 14
  • Nil coalescing operator

    Nil coalescing operator

    Added 'if invalid' operator similar to Swift's nil coalescing operator, adapted for scripting. This can be extremely useful in eliminating unnecessarily lengthy code.

    The difference being that instead of checking for nil the operator checks to see if the left side is valid (error, empty slice, empty map or zero value).

    opened by geseq 14
  • channel types and other typing problems

    channel types and other typing problems

    Apologies if this veers a little... philosophical.

    Anko comprehends a bunch of types, but the way things are implemented means you don't have to think about types until you REALLY NEED TO think about types, and then you're stuck.

    I can define a channel of bytes:

    > c = make(chan byte, 1)
    (chan uint8)(0xc420070070)
    

    Having done that, one might think I could do this:

    > c <- 10
    panic: reflect.Value.Send: value of type int64 is not assignable to type uint8
    

    Instead, the only thing I've been able to figure out is:

    > a = make([]byte, 1)
    []byte{0x0}
    > a[0] = 0xa
    10
    > c <- a[0]
    <nil>
    > <-c
    0xa
    

    I thought I might be able to trick it, but no:

    > a = make(byte)
    0x0
    > typeOf(a)
    "uint8"
    > a = 10
    10
    > typeOf(a)
    "int64"
    

    Basically, this issue is me griping about inconsistencies in Anko's handling of types. You can define typed arrays and channels using make, but you cannot define a scalar or map of a particular type.

    Of course, this might go completely against what @mattn intends for the project, and I'll accept that. In that case, though, it feels like all arrays should be []interface and all chans should be channels of interface.

    opened by floren 14
  • Scoping question

    Scoping question

    I'm not particularly good with dynamic scoping, I've pretty much never used it, so I've got some questions about how I should be writing my code. Basically, any variables I use in functions are now "off-limits" from using elsewhere... here's a simplified example:

    var strconv = import("strconv")
    func parseBase10(s) {
      r, _ = strconv.ParseInt(s, 10, 64)
      return r
    }
    r = ["5", "4", "3"]
    for i = 0; i < len(r); i++ {
      println(parseBase10(r[i])
    }
    

    The call to parseBase10 changes r from a slice of strings to an int64. Whoops! I thought I might do this:

     func parseBase10(s) {
      var r, err = strconv.ParseInt(s, 10, 64)
      return r
    }
    

    But that doesn't work quite right:

    > parseBase10("5")
    []interface {}{5, interface {}(nil)}
    

    What do I do in this situation? Start using more unique variable names? Or is there a correct way to use 'var' in that sort of multiple assignment situation?

    opened by floren 13
  • 1 line counts as 2

    1 line counts as 2

    Sample script with a syntax error:

    #!anko
    
    func fib(n) {
      a, b = 1, 1
      f = []
      for i in range n {
        f += a
        b += a
        a = b - a
      }
      return f
    }
    
    println(fib(20))
    

    You get this output:

    
    $ ./anko fib-for.ank
    fib-for.ank:11: syntax error: unexpected IDENT
    

    The reported line is incorrect, the error is on line 6. The correct line can be found by doing (l.pos.Line-1)/2+1... but that just masks the underlying problem - somewhere a new line is double counted.

    opened by dhiltonp 12
  • Method overriding in custom structs

    Method overriding in custom structs

    Hello,

    I am developing a project in need of function overriding. I already developed some on my fork, but I was wondering if you would be interested in merging my commits to the master branch. Let me show you some examples so you can have a better idea of what I am trying to do:

    Having:

    type C interface {
      Set(interface{})
      Get(k string) interface{}
    }
    
    type A struct {
      v int64  
    }
    
    func (a *A) Get(k string) interface{} {
    ...
    }
    
    func (a *A) Set(v interface{}) {
     ...
    }
    

    I want to call A from the script in a transparent way by using:

    # asume `obj` is `A` type
    v = obj["key"]
    v = 20
    

    That should call:

    v = obj.Get("key")
    v.Set(20)
    

    That's already implemented in my fork, and you can try it out with your custom structures. I'll wait for your comments and suggestions.

    Thanks.

    opened by dgrr 11
  • panic in LetsStmt

    panic in LetsStmt

    we saw a panic come out of a system that is running scripts in a customer system. I haven't yet been able to get a script sample with the data that can cause the panic, but it happened multiple times. It appears that the code isn't validating the size of the slice.

    The offending piece of code is runInfo.rv = rvs[len(rvs)-1]

    here is the backtrace snippet:

    panic: runtime error: index out of range
    
    goroutine 85 [running]:
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:161
    +0x5d0e
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:61
    +0x2ec2
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:367
    +0x23ce
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:61
    +0x2ec2
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:205
    +0x4d09
    vendor/github.com/mattn/anko/vm.(*runInfoStruct).runSingleStmt(0xc000020690)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:61
    +0x2ec2
    vendor/github.com/mattn/anko/vm.RunContext(0xab6dc0,
    0xc00002a800, 0xaafe40, 0xc0002ee750, 0xc000220500, 0x600, 0x1,
    0xc00004efa8, 0x6ffc46)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/vmStmt.go:19
    +0x107
    vendor/github.com/mattn/anko/vm.(*Env).ExecuteContext(0xc000220500,
    0xab6dc0, 0xc00002a800, 0xc0002e7200, 0x58e, 0xc00011dda0, 0x0, 0x1,
    0x0)
            /home/user/mygo/src/vendor/github.com/mattn/anko/vm/env.go:388 +0x15e
    main.runScript.func1(0xc00000d8c0, 0xab6dc0, 0xc00002a800,
    0xc000216280, 0xc00006eea0)
    

    Anyone have any ideas on a script snippet that could invoke this piece of the interpreter code? I am still trying to generate a test case.

    opened by traetox 11
  • Methods definition

    Methods definition

    In Go, a method defined on a pointer like this:

    func (u *User) SayHello() {...}
    

    May be called on a pointer or on an instance:

    user1 := &User{Name: "Michel"}
    user1.SayHello()
    user2 := User{Name: "Michel"}
    user2.SayHello()
    

    But this is not the case in Anko, as following example demonstrates:

    package main
    
    import (
    	"fmt"
    	"log"
    
    	"github.com/mattn/anko/env"
    	"github.com/mattn/anko/vm"
    )
    
    type User struct {
    	Name string
    }
    
    func (u *User) SayHello() {
    	fmt.Printf("Hello %s!\n", u.Name)
    }
    
    func main() {
    	e := env.NewEnv()
    	user := User{Name: "Michel"}
    	user.SayHello()
    	err := e.Define("user", user)
    	if err != nil {
    		log.Fatalf("Define error: %v\n", err)
    	}
    	_, err = vm.Execute(e, nil, "user.SayHello()")
    	if err != nil {
    		log.Fatalf("Execute error: %v\n", err)
    	}
    }
    

    Which prints:

    $ go run main.go 
    Hello Michel!
    2022/01/12 18:42:13 Execute error: no member named 'SayHello' for struct
    exit status 1
    
    opened by c4s4 0
  • add GetValueSymbols and GetTypeSymbols

    add GetValueSymbols and GetTypeSymbols

    I've been using anko for my music player and I wanted to implement auto completion. By adding GetValueSymbols and GetTypeSymbols, I will be able to easily fetch symbols of the current scope. This will also help others with the same use case.

    opened by issadarkthing 1
  • when

    when "new" and "make" structure, field will not be zero value.

    test code:

    type FooStruct struct {
    	function  func(string)
    	Pointer   *int
    	Slice     []string
    	Map       map[string]string
    	Channel   chan string
    	Function  func(string)
    	Interface interface{}
    	Transport http.RoundTripper
    	Str2      FooStruct2
    	Str2p     *FooStruct2
    }
    
    type FooStruct2 struct {
    	Pointer *int
    }
    
    // Println is used to check structure fields are Zero Value.
    func (f *FooStruct) Println() {
    	fmt.Println("func(unexported):", f.function == nil)
    	fmt.Println("pointer:", f.Pointer == nil)
    	fmt.Println("slice:", f.Slice == nil)
    	fmt.Println("map:", f.Map == nil)
    	fmt.Println("chan:", f.Channel == nil)
    	fmt.Println("func:", f.Function == nil)
    	fmt.Println("interface{}:", f.Interface == nil)
    	fmt.Println("interface:", f.Transport == nil)
    	fmt.Println("str2:", f.Str2.Pointer == nil)
    	fmt.Println("str2p:", f.Str2p == nil)
    	fmt.Println()
    }
    
    func TestAnkoMakeStruct(t *testing.T) {
    	// Zero Value
    	fs1 := new(FooStruct)
    	fs1.Println()
    	fs2 := FooStruct{}
    	fs2.Println()
    
    	// some fields not Zero Value
    	e := env.NewEnv()
    	err := e.DefineType("FooStruct", reflect.TypeOf(fs1).Elem())
    	require.NoError(t, err)
    	src := `
    fs1 = new(FooStruct)
    fs1.Println()
    
    fs2 = make(FooStruct)
    fs2.Println()
    `
    	stmt, err := parser.ParseSrc(src)
    	require.NoError(t, err)
    	_, err = vm.Run(e, nil, stmt)
    	require.NoError(t, err)
    }
    

    output:

    func(unexported): true
    pointer: true
    slice: true
    map: true
    chan: true
    func: true
    interface{}: true
    interface: true
    str2: true
    str2p: true
    
    func(unexported): true
    pointer: true
    slice: true
    map: true
    chan: true
    func: true
    interface{}: true
    interface: true
    str2: true
    str2p: true
    
    func(unexported): true
    pointer: true
    slice: false
    map: false
    chan: false
    func: false
    interface{}: true
    interface: true
    str2: true
    str2p: true
    
    func(unexported): true
    pointer: true
    slice: false
    map: false
    chan: false
    func: false
    interface{}: true
    interface: true
    str2: true
    str2p: true
    
    slice, map, chan and func will not be set zero value, but pointer is zero value.
    it will occur some package panic like net/http.Client
    
    // code in src/net/http
    func (c *Client) checkRedirect(req *Request, via []*Request) error {
        fn := c.CheckRedirect
        if fn == nil {       // [error] in anko, this if is unexpected.
            fn = defaultCheckRedirect
        }
        return fn(req, via)
    }
    
    func TestAnkoMakeHTTPClient(t *testing.T) {
    	e := env.NewEnv()
    
    	src := `
    http = import("net/http")
    
    // must 302
    url = "http://example.com/302"
    req, err = http.NewRequest(http.MethodGet, url, nil)
    if err != nil {
        return false, err
    }
    client = new(http.Client)
    resp, err = client.Do(req) // will return a nil pointer error
    if err != nil {
        return false, err
    }
    
    println(client.CheckRedirect == nil) // false
    println(client.CheckRedirect) // invalid function
    
    // ok
    client.CheckRedirect = nil
    resp, err = client.Do(req)
    if err != nil {
        return false, err
    }
    `
    	stmt, err := parser.ParseSrc(src)
    	require.NoError(t, err)
    	_, err = vm.Run(e, nil, stmt)
    	require.NoError(t, err)
    }
    
    

    file anko/vm/vm.go:

    line 394:
    
    func makeValue(t reflect.Type) (reflect.Value, error) {
    	switch t.Kind() {
    	case reflect.Chan:
    		return reflect.MakeChan(t, 0), nil
    	case reflect.Func:
    		return reflect.MakeFunc(t, nil), nil
    	case reflect.Map:
    		// note creating slice as work around to create map
    		// just doing MakeMap can give incorrect type for defined types
    		value := reflect.MakeSlice(reflect.SliceOf(t), 0, 1)
    		value = reflect.Append(value, reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem())))
    		return value.Index(0), nil
    	case reflect.Ptr:
    		ptrV := reflect.New(t.Elem())
    		v, err := makeValue(t.Elem())
    		if err != nil {
    			return nilValue, err
    		}
    		
    		ptrV.Elem().Set(v)
    		return ptrV, nil
    	case reflect.Slice:
    		return reflect.MakeSlice(t, 0, 0), nil
    	case reflect.Struct:
    		 structV := reflect.New(t).Elem()
    		 for i := 0; i < structV.NumField(); i++ {
                            // here Pointer will be zero value, but other type is not
    		 	if structV.Field(i).Kind() == reflect.Ptr {
    		 		continue
    		 	}
    		 	v, err := makeValue(structV.Field(i).Type())
    			if err != nil {
    				return nilValue, err
    			}
    			if structV.Field(i).CanSet() {
    				structV.Field(i).Set(v)
    			}
    		 }
    		 return structV, nil
    
    	
    	        // only this code is ok
    		// return reflect.New(t).Elem(), nil
    	}
    	return reflect.New(t).Elem(), nil
    }
    
    opened by For-ACGN 0
  • Crashed by invalid input

    Crashed by invalid input

    Found in fuzz test with go-fuzz

    input: "\ue031"

    package main
    
    import "github.com/mattn/anko/parser"
    
    func main() {
    	_, err := parser.ParseSrc("\ue031")
    	if err != nil {
    		panic(err)
    	}
    }
    
    $ go run ./main.go
    signal: killed
    

    fuzz code

    package parser
    
    import "github.com/mattn/anko/parser"
    
    func Fuzz(data []byte) int {
    	_, err := parser.ParseSrc(string(data))
    	if err != nil {
    		return 0
    	}
    	return 1
    }
    

    crash log

    program hanged (timeout 10 seconds)
    
    SIGABRT: abort
    PC=0x45e721 m=0 sigcode=0
    
    goroutine 0 [idle]:
    runtime.futex(0x5efec8, 0x80, 0x0, 0x0, 0x7f5800000000, 0x0, 0xc000118000, 0x7ffc00000001, 0x7ffcaf2e6e68, 0x40a28f, ...)
    	runtime/sys_linux_amd64.s:567 +0x21
    runtime.futexsleep(0x5efec8, 0x7f5800000000, 0xffffffffffffffff)
    	runtime/os_linux.go:45 +0x46
    runtime.notesleep(0x5efec8)
    	runtime/lock_futex.go:151 +0x9f
    runtime.stopm()
    	runtime/proc.go:1834 +0xc0
    runtime.exitsyscall0(0xc000000180)
    	runtime/proc.go:3268 +0x111
    runtime.mcall(0x0)
    	runtime/asm_amd64.s:318 +0x5b
    
    goroutine 1 [runnable]:
    github.com/mattn/anko/parser.yylex1(0x538220, 0xc00037d8b0, 0xc000164500, 0xe031, 0x33)
    	/home/heijo/go/pkg/mod/github.com/mattn/[email protected]/parser/parser.go:1042 +0x466
    github.com/mattn/anko/parser.(*yyParserImpl).Parse(0xc000164500, 0x538220, 0xc00037d8b0, 0x0)
    	/home/heijo/go/pkg/mod/github.com/mattn/[email protected]/parser/parser.go:1129 +0x161db
    github.com/mattn/anko/parser.yyParse(...)
    	/home/heijo/go/pkg/mod/github.com/mattn/[email protected]/parser/parser.go:1078
    github.com/mattn/anko/parser.Parse(0xc000101650, 0xc000101650, 0x3, 0xc0003b38c8, 0x1)
    	/home/heijo/go/pkg/mod/github.com/mattn/[email protected]/parser/lexer.go:591 +0xef
    github.com/mattn/anko/parser.ParseSrc(0xc000420e78, 0x3, 0x3, 0x3, 0xc000420e78, 0x3)
    	/home/heijo/go/pkg/mod/github.com/mattn/[email protected]/parser/lexer.go:612 +0xb9
    github.com/johejo/go-fuzz-contrib/github.com/mattn/anko/parser.Fuzz(0x7f583a827000, 0x3, 0x3, 0x3)
    	/home/heijo/ghq/github.com/johejo/go-fuzz-contrib/github.com/mattn/anko/parser/fuzz.go:6 +0x7d
    go-fuzz-dep.Main(0xc000420f70, 0x1, 0x1)
    	go-fuzz-dep/main.go:36 +0x1ad
    main.main()
    	github.com/johejo/go-fuzz-contrib/github.com/mattn/anko/parser/go.fuzz.main/main.go:15 +0x52
    
    rax    0xca
    rbx    0x5efd80
    rcx    0x45e723
    rdx    0x0
    rdi    0x5efec8
    rsi    0x80
    rbp    0x7ffcaf2e6e30
    rsp    0x7ffcaf2e6de8
    r8     0x0
    r9     0x0
    r10    0x0
    r11    0x286
    r12    0x5debc0
    r13    0x5ddda0
    r14    0x5d85c0
    r15    0x4
    rip    0x45e721
    rflags 0x286
    cs     0x33
    fs     0x0
    gs     0x0
    exit status 2
    
    opened by johejo 0
Owner
mattn
Long-time Golang user&contributor, Google Dev Expert for Go, and author of many Go tools, Vim plugin author. Windows hacker C#/Java/C/C++
mattn
Esprima-Go: A high performance JavaScript parser written in Go

Esprima-Go is a JavaScript parser written in Go. Esprima is a JavaScript parser written in TypeScript, it's widely used in javascript-realt

CHEN Yuan 0 Jan 9, 2022
PHP bindings for the Go programming language (Golang)

PHP bindings for Go This package implements support for executing PHP scripts, exporting Go variables for use in PHP contexts, attaching Go method rec

Alex Palaistras 868 Aug 10, 2022
Expression evaluation in golang

Gval Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions. Evaluate Gval can evaluate expressio

null 520 Aug 4, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Aug 1, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Aug 1, 2022
Interpreter - The Official Interpreter for the Infant Lang written in Go

Infant Lang Interpreter Infant Lang Minimalistic Less Esoteric Programming Langu

Infant Lang 2 Jan 10, 2022
Instant messaging platform. Backend in Go. Clients: Swift iOS, Java Android, JS webapp, scriptable command line; chatbots

Tinode Instant Messaging Server Instant messaging server. Backend in pure Go (license GPL 3.0), client-side binding in Java, Javascript, and Swift, as

Tinode 9.1k Aug 12, 2022
🏛 A scriptable financial ledger, designed to make it easy to model complex financial transactions

Numary Ledger Numary is a programmable financial ledger that wants to make building financial apps safe, fun and cheap. Building financial software is

Numary 359 Aug 12, 2022
BackEndForEverything a scriptable reverse proxy

BEFE the BackEnd For Everything BEFE is a scriptable reverse proxy. It simplifies checking, rewriting and transforming incoming request through the he

MBIct 2 Nov 8, 2021
A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Steve Kemp 280 Jul 14, 2022
A simple virtual machine - compiler & interpreter - written in golang

go.vm Installation Build without Go Modules (Go before 1.11) Build with Go Modules (Go 1.11 or higher) Usage Opcodes Notes The compiler The interprete

Steve Kemp 236 Aug 10, 2022
A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Steve Kemp 281 Aug 8, 2022
A toy language parser, lexer and interpreter written in Golang

Monkey - A toy programming language Monkey is a toy programming language used to learn how to write a lexer, parser and interpreter. The language is i

Adam Petrovic 1 Nov 16, 2021
A sed interpreter written in Golang

A sed interpreter written in Golang. Most behaviors of this program is implemented follow GNU-sed, except all those operations related to external fil

kozz.gaof 1 Dec 15, 2021
interpreter for the basic language written in golang

jirachi interpreter for the basic language written in golang The plan supports the following functions: Arithmetic Operations (+, -, *, /, ^) Comparis

菜菜 4 Jul 9, 2022
A POSIX-compliant AWK interpreter written in Go

GoAWK: an AWK interpreter written in Go AWK is a fascinating text-processing language, and somehow after reading the delightfully-terse The AWK Progra

Ben Hoyt 1.6k Aug 12, 2022
Mini lisp interpreter written in Go.

Mini Go Lisp Mini lisp interpreter written in Go. It is implemented with reference to the d-tsuji/SDLisp repository written in Java. Support System Fu

Tsuji Daishiro 16 Nov 25, 2020
gpython is a python interpreter written in go "batteries not included"

gpython gpython is a part re-implementation / part port of the Python 3.4 interpreter to the Go language, "batteries not included". It includes: runti

go-python 605 Aug 3, 2022
◻️ A Whitespace interpreter written in Go.

whitespace-go A Whitespace interpreter written in Go. Whitespace is a esoteric programming language made up entirely of spaces, tabs, and newlines. Th

Sam Pratt 4 May 18, 2022
🧠 A Brainfuck interpreter written in Go

brainfuck-go A Brainfuck interpreter written in Go. How Brainfuck works Brainfuck is an esoteric programming language designed to have the simplest co

Sam Pratt 7 May 18, 2022
A little brainfuck interpreter written in Go

Brainfuck_go_interpreter A little brainfuck interpreter written in Go from what I've done in coding game Usage $ go build brainfuck.go $ ./brainfuck P

Axel Vanzaghi 0 Dec 13, 2021
An interpreter written in go for a brainfuck-based language called €*

eurostar-go-interpreter This is an interpreter written in go for a brainfuck-bas

null 8 May 22, 2022
Autogo - An AutoIt interpreter written in Go

AutoGo An AutoIt interpreter and cross-platform runtime package WARNING: AutoGo

null 32 Jun 24, 2022
Simple-lisp - A Simple Lisp Interpreter written in Go

Simple Lisp A simple Lisp interpreter written in Go. The fixed-precision-numbers

Oxygen 5 Jun 21, 2022
Bf - A brainfuck interpreter written in Go while the programmer was drunk

BF A (not well tested) brainfuck interpreter written in Go while the programmer

Paulo 1 Feb 17, 2022
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Robert Krimen 6.8k Aug 12, 2022
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Robert Krimen 6.8k Aug 9, 2022
A Golang SSA Interpreter

A Golang SSA Interpreter

GoPlus 56 Aug 5, 2022
Golisp-wtf - A lisp interpreter (still just a parser) implementation in golang. You may yell "What the fuck!?.." when you see the shitty code.

R6RS Scheme Lisp dialect interpreter This is an implementation of a subset of R6RS Scheme Lisp dialect in golang. The work is still in progress. At th

Vladimir Novikov 0 Jan 7, 2022