Coder Social home page Coder Social logo

ozanh / ugo Goto Github PK

View Code? Open in Web Editor NEW
106.0 2.0 10.0 1.51 MB

Script Language for Go

License: MIT License

Makefile 0.11% Go 99.73% Shell 0.16%
golang scripting-language go embedded-language ugo virtual-machine compiler bytecode script-language

ugo's Introduction

The uGO Language

Go Reference Go Report Card uGO Test uGO Dev Test Maintainability

uGO is a fast, dynamic scripting language to embed in Go applications. uGO is compiled and executed as bytecode on stack-based VM that's written in native Go.

uGO is actively used in production to evaluate Sigma Rules' conditions, and to perform compromise assessment dynamically.

To see how fast uGO is, please have a look at fibonacci benchmarks (not updated frequently).

Play with uGO via Playground built for WebAssembly.

Fibonacci Example

param arg0

var fib

fib = func(x) {
    if x == 0 {
        return 0
    } else if x == 1 {
        return 1
    }
    return fib(x-1) + fib(x-2)
}
return fib(arg0)

Features

  • Written in native Go (no cgo).
  • Supports Go 1.15 and above.
  • if else statements.
  • for and for in statements.
  • try catch finally statements.
  • param, global, var and const declarations.
  • Rich builtins.
  • Pure uGO and Go Module support.
  • Go like syntax with additions.
  • Call uGO functions from Go.
  • Import uGO modules from any source (file system, HTTP, etc.).
  • Create wrapper functions for Go functions using code generation.

Why uGO

uGO name comes from the initials of my daughter's, wife's and my name. It is not related with Go.

I needed a faster embedded scripting language with runtime error handling.

Quick Start

go get github.com/ozanh/ugo@latest

uGO has a REPL application to learn and test uGO scripts.

go install github.com/ozanh/ugo/cmd/ugo@latest

./ugo

repl-gif

This example is to show some features of uGO.

https://play.golang.org/p/1Tj6joRmLiX

package main

import (
    "fmt"

    "github.com/ozanh/ugo"
)

func main() {
    script := `
param ...args

mapEach := func(seq, fn) {

    if !isArray(seq) {
        return error("want array, got " + typeName(seq))
    }

    var out = []

    if sz := len(seq); sz > 0 {
        out = repeat([0], sz)
    } else {
        return out
    }

    try {
        for i, v in seq {
            out[i] = fn(v)
        }
    } catch err {
        println(err)
    } finally {
        return out, err
    }
}

global multiplier

v, err := mapEach(args, func(x) { return x*multiplier })
if err != undefined {
    return err
}
return v
`

    bytecode, err := ugo.Compile([]byte(script), ugo.DefaultCompilerOptions)
    if err != nil {
        panic(err)
    }
    globals := ugo.Map{"multiplier": ugo.Int(2)}
    ret, err := ugo.NewVM(bytecode).Run(
        globals,
        ugo.Int(1), ugo.Int(2), ugo.Int(3), ugo.Int(4),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println(ret) // [2, 4, 6, 8]
}

Roadmap

Examples for best practices (2023).

Better Playground (2023).

More standard library modules (2023).

Configurable Stdin, Stdout and Stderr per Virtual Machine (2023).

Deferring function calls (2024).

Concurrency support (2024).

Documentation

LICENSE

uGO is licensed under the MIT License.

See LICENSE for the full license text.

Acknowledgements

uGO is inspired by script language Tengo by Daniel Kang. A special thanks to Tengo's creater and contributors.

ugo's People

Contributors

ozanh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ugo's Issues

code formatter

Upcoming parser changes brings comments into AST. This enables to write a uGO code formatter. Although it is not urgent to have a code formatter for now, this issue should stay until a basic code formatter is developed.

PS: I wrote a simple code formatter but comments inlined into expressions become messy.

constant propagation in optimizer

As const declarations were introduced to uGO language, constant values should be propagated to expressions they are used in until they are shadowed. Optimizer does not create symbol tables but simple scopes which may help to propagate until a redefinition is encountered. Normally, users tend to avoid shadowing variables so constant value can be propagated most of the time.
This feature requires changes in both optimizer and compiler, and it should not extend the compilation process.

Optimizer and builtin functions

uGO allows to shadow builtin symbols, but this causes optimizer, that has no symbol table, to evaluate builtin function calls as if they are not shadowed as shown in the example;

string := func() { /* ... */ }
a := string(1)
println(a)

Result:

Bytecode
Modules:0
Constants:
   0: CompiledFunction
	Params:0 Variadic:false Locals:0
	Instructions:
	0000 RETURN          0
	SourceMap:map[0:0]
   1: "1"|string
Params:0 Variadic:false Locals:2
Instructions:
0000 CONSTANT        0
0003 SETLOCAL        0
0005 CONSTANT        1
0008 SETLOCAL        1
0010 GETBUILTIN      19
0012 GETLOCAL        1
0014 CALL            1    0
0017 POP
0018 RETURN          0

Output:
"1"

"1" is not the expected output. Either disable evaluating builtins or throw a meaningful error.

function declarations

Currently, uGO compiled functions are anonymous. This will prevent forward declaration of variables assigned to functions which has tail call. This feature requires to introduce a name getter for compiled function.

Would like to call function from a ugo.Function

I tried getting this to work on tengo, there was a mention of it possibly working on ugo. Problem is with ugo, re-entering the VM is deadlocked due to the lock. Here's the code I want to run:

package meta_ugo

import (
"errors"
"github.com/ozanh/ugo"
"testing"
)

func TestReenterUgo(t *testing.T) {

script := `

  var abc = [123,456,789]

  arr := [123,456,789]
  
  global filter
     
  smalls := filter( arr, func(item){ 
         printf("my lambda.... %s", item)
         return item < 500
      })
     
  printf("smalls=%v", smalls)

`

tfiltSetVM, tfilter := makeUgoFilter()

igm := ugo.Map{"filter": &ugo.Function{Value: tfilter}}

if c, err := ugo.Compile([]byte(script), ugo.DefaultCompilerOptions); err != nil {

	t.Error(err)

} else if vm := ugo.NewVM(c); false {

} else if tfiltSetVM(vm); false {

} else if res, err := vm.Run(igm); err != nil {

	t.Error(err)

} else {

	t.Logf("res = %v", res)
}

}

type ugoFilter struct {
vm *ugo.VM
}

func makeUgoFilter() (func(*ugo.VM), func(...ugo.Object) (ugo.Object, error)) {

tf := &ugoFilter{}

return func(mv *ugo.VM) {
		tf.vm = mv
		return
	},
	func(args ...ugo.Object) (reg ugo.Object, err error) {
		requreMsg := "Requires an array and a callable func"
		if len(args) != 2 {
			err = errors.New(requreMsg)
			return
		}

		if a, arrOk := args[0].(ugo.Array); !arrOk {

			err = errors.New(requreMsg)
			return
		} else if c, callbackOk := args[1].(*ugo.CompiledFunction); !callbackOk {

			err = errors.New(requreMsg)
			return
		} else {

			result := ugo.Array{}

			for _, x := range a {
				if res, err := tf.vm.RunCompiledFunction(c, nil, x); err != nil {
					return nil, err
				} else if !res.IsFalsy() {

					result = append(result, x)
				}

			}
		}

		return

	}

}

IMPORTANT: new uGO

Current implementation cause so much interface allocation in loops due to new interface creation in binary operations although uGO is faster than many alternatives in some respects. I am not satisfied with current performance and project structure as well. Due to historical reasons, it had to be like this because uGO was supposed to evaluate expressions and call Go functions only at the beginning. Sorry for the inconvenience but this must be done before releasing a stable version. New version will be developed at different branch and current implementation will be fixed at v0.1 after new uGO is ready.
Most probably syntax will be the same but types and interfaces will be changed as a result API will change significantly. If I don't see any significant improvement, I will let you know.

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.