Giter Site home page Giter Site logo

gofu's Introduction

gofu

a scripting language toolkit in Go

intro

gofu aims to provide a flexible toolkit for creating custom scripting languages in Go.

functions

Functions have a name, an argument list, a result list and a body.

p := gofu.Pos("Test", -1, -1)

add := gofu.Func("+", []gofu.Type{types.Int(), types.Int()}, []gofu.Type{types.Int()},
	func(pos gofu.TPos, thread *gofu.TThread, _func *gofu.TFunc, pc *int) error {
		stack := thread.Stack()
		stack.Push(types.Int(), stack.Pop().Value().(int) + stack.Pop().Value().(int))
		return nil
	})

scope := gofu.Scope()	
scope.BindSlot("+", types.Func(), add)

block := gofu.Block()
c := forms.Call(p, forms.Id(p, "+"), forms.Literal(p, types.Int(), 35), forms.Literal(p, types.Int(), 7))
c.Compile(scope, block)
block.Emit(ops.Stop())

thread := gofu.Thread(scope)
block.Run(thread, 0)

The same thing could be accomplished by manually emitting operations.

block.Emit(ops.Push(types.Int(), 35))
block.Emit(ops.Push(types.Int(), 7))
block.Emit(ops.Call(p, add))
block.Emit(ops.Stop())

fimps.Compile may be used to compile function bodies.

fimp, err := fimps.Compile(forms.Literal(p, []gofu.Type{types.Int()}, 42), block)
fortyTwo := gofu.Func("fortyTwo", nil, []gofu.Type{types.Int()}, fimp)
scope.BindSlot("fortyTwo", types.Func(), f)

multiple dispatch

The following example will dispatch to the right function based on the argument and push "Bool!" on the stack.

f1 := gofu.Func("foo", []gofu.Type{types.Bool()}, []gofu.Type{types.Int()},
    func(pos gofu.TPos, thread *gofu.TThread, _func *gofu.TFunc, pc *int) error {
	    stack := thread.Stack()
	    stack.Pop()
	    stack.Push(types.String(), "Bool!")
	    return nil
    })

f2 := gofu.Func("foo", []gofu.Type{types.Int()}, []gofu.Type{types.Int()},
    func(pos gofu.TPos, thread *gofu.TThread, _func *gofu.TFunc, pc *int) error {
	    stack := thread.Stack()
	    stack.Pop()
	    stack.Push(types.String(), "Int!")
	    return nil
    })

m := gofu.Multi("foo", 1, f1, f2)
block.Emit(ops.Push(types.Bool(), true))
block.Emit(ops.Call(p, m))
block.Emit(ops.Stop())	

macros

Macros are called at compile time and may emit different code depending on arguments.

scope.BindSlot("reset",
	types.Macro(),
	gofu.Macro("reset", 0,
		func(pos gofu.TPos, args []gofu.Form, scope *gofu.TScope, block *gofu.TBlock) error {
			block.Emit(ops.Reset())
			return nil
		}))

types

The following list of types are provided but optional, anything implementing gofu.Type may be used as a type.

  • Any: Any - Anything
  • Bool: Any - t/f
  • Char: Any - Characters
  • Func: Any Target - Functions
  • Int: Any Num - Integers
  • Maybe[T]: Any - Contains T or Nil
  • Meta: Any - The type of types
  • Multi: Any Target - Multimethods
  • Nil - Nothing, it's only value being _
  • Num: Any - Parent of all numbers
  • Seq[T]: Any - Parent of all sequences
  • Stack[T]: Any Seq[T] - Stacks of values
  • String: Any Seq[Char] - Strings
  • Target: Any - Callable values

repl

A primitive REPL is provided, it reads one form at a time and prints the stack after each evaluation.

$ cd bin
$ ./mk
$ ./repl
gofu v1
  +(35 7)
[42]

Parens may be used to group forms.

  (1 2 3)
[1 2 3]

The stack may be directly modified using d and reset.

  (1 2 3)
[1 2 3]
  d
[1 2]
  reset
[]

Code may be executed conditionally using if.

  if(t 1 2)
[1]
  if(f 3 4)
[1 4]

Functions may be called by suffixing names with argument lists.

  +(35 7)
[42]

New functions may be defined using func.

  func(foo () (Int) 42)
[]
  foo
[42]

Values may be bound to identifiers using bind.

  bind(foo 42)
[]
  foo
[42]

The REPL is heavily parameterized and assumes very little about the actual language.

scope := gofu.Scope()
block := gofu.Block()
thread := gofu.Thread(scope)
utils.Repl(scope, parsers.Any(), block, thread)

gofu's People

Watchers

 avatar

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.