Skip to content

Commit

Permalink
Merge pull request #62 from d5/v1prep
Browse files Browse the repository at this point in the history
v1 release prep
  • Loading branch information
d5 authored Jan 30, 2019
2 parents fdc52a0 + 64d9980 commit f7b0cd8
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 139 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bin/
dist/
15 changes: 15 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/tengo/main.go
goos:
- darwin
- linux
- windows
archive:
files:
- none*
checksum:
name_template: 'checksums.txt'
changelog:
sort: asc
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ install:

script:
- make test

deploy:
- provider: script
skip_cleanup: true
script: curl -sL https://git.io/goreleaser | bash
on:
tags: true
41 changes: 10 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ s := sum("", [1, 2, 3]) // == "123"
| | fib(35) | fibt(35) | Type |
| :--- | ---: | ---: | :---: |
| Go | `58ms` | `4ms` | Go (native) |
| [**Tengo**](https://github.com/d5/tengo) | `4,334ms` | `5ms` | VM on Go |
| Lua | `1,740ms` | `3ms` | Lua (native) |
| [go-lua](https://github.com/Shopify/go-lua) | `5,229ms` | `5ms` | Lua VM on Go |
| [GopherLua](https://github.com/yuin/gopher-lua) | `5,486ms` | `5ms` | Lua VM on Go |
| Python | `3,116ms` | `27ms` | Python (native) |
| [starlark-go](https://github.com/google/starlark-go) | `15,414ms` | `5ms` | Python-like Interpreter on Go |
| [gpython](https://github.com/go-python/gpython) | `17,754ms` | `6ms` | Python Interpreter on Go |
| [goja](https://github.com/dop251/goja) | `6,843ms` | `6ms` | JS VM on Go |
| [otto](https://github.com/robertkrimen/otto) | `86,542ms` | `13ms` | JS Interpreter on Go |
| [Anko](https://github.com/mattn/anko) | `98,962ms` | `26ms` | Interpreter on Go |
| [**Tengo**](https://github.com/d5/tengo) | `4,180ms` | `5ms` | VM on Go |
| Lua | `1,695ms` | `3ms` | Lua (native) |
| [go-lua](https://github.com/Shopify/go-lua) | `5,163ms` | `5ms` | Lua VM on Go |
| [GopherLua](https://github.com/yuin/gopher-lua) | `5,525ms` | `5ms` | Lua VM on Go |
| Python | `3,097ms` | `27ms` | Python (native) |
| [starlark-go](https://github.com/google/starlark-go) | `15,307ms` | `5ms` | Python-like Interpreter on Go |
| [gpython](https://github.com/go-python/gpython) | `17,656ms` | `5ms` | Python Interpreter on Go |
| [goja](https://github.com/dop251/goja) | `6,876ms` | `5ms` | JS VM on Go |
| [otto](https://github.com/robertkrimen/otto) | `81,886ms` | `12ms` | JS Interpreter on Go |
| [Anko](https://github.com/mattn/anko) | `97,517ms` | `14ms` | Interpreter on Go |

_* [fib(35)](https://github.com/d5/tengobench/blob/master/code/fib.tengo): Fibonacci(35)_
_* [fibt(35)](https://github.com/d5/tengobench/blob/master/code/fibtc.tengo): [tail-call](https://en.wikipedia.org/wiki/Tail_call) version of Fibonacci(35)_
Expand All @@ -72,24 +72,3 @@ _* See [here](https://github.com/d5/tengobench) for commands/codes used_
- [Interoperability](https://github.com/d5/tengo/blob/master/docs/interoperability.md)
- [Tengo CLI](https://github.com/d5/tengo/blob/master/docs/tengo-cli.md)
- [Standard Library](https://github.com/d5/tengo/blob/master/docs/stdlib.md)

## Roadmap

### v0. _(Current)_

Things are experimental, and, the focus is on the **core language features**, **stability**, **basic interoperability**, and the **performance optimization**.

### [v1. Tengo as a Script Language](https://github.com/d5/tengo/labels/v1.0)

This will be the first _versioned_ release, and, the main goal for v1 is to make Tengo as a _fast_ embeddable script language for Go, which means Tengo will be comparable to other Go-based script languages such as [Starlark](https://github.com/google/starlark-go), [Lua](https://github.com/Shopify/go-lua) [VM](https://github.com/yuin/gopher-lua)s, and [other](https://github.com/robertkrimen/otto) [interpreter](https://github.com/mattn/anko)s.

- Interoperability with Go code
- Sandbox environment
- More language features

### v2. Tengo as a Standalone Language

- Language-level concurrency support
- Tengo Standard Libraries
- Native executables compilation
- More language features
51 changes: 30 additions & 21 deletions cmd/tengo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,32 @@ const (
)

var (
compile bool
showHelp bool
outputFile = flag.String("o", "", "Output file")
compileOutput string
showHelp bool
showVersion bool
version = "dev"
)

func init() {
flag.BoolVar(&showHelp, "help", false, "Show help")
flag.BoolVar(&compile, "compile", false, "Compile input file")
flag.BoolVar(&compile, "c", false, "Compile input file")
flag.StringVar(&compileOutput, "o", "", "Compile output file")
flag.BoolVar(&showVersion, "version", false, "Show version")
flag.Parse()
}

func main() {
if showHelp {
doHelp()
os.Exit(2)
} else if showVersion {
fmt.Println(version)
return
}

inputFile := flag.Arg(0)
if inputFile == "" {
// REPL
doRepl(os.Stdin, os.Stdout)
runREPL(os.Stdin, os.Stdout)
return
}

Expand All @@ -56,18 +60,18 @@ func main() {
os.Exit(1)
}

if compile {
if err := doCompile(inputData, inputFile, *outputFile); err != nil {
if compileOutput != "" {
if err := compileOnly(inputData, inputFile, compileOutput); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
} else if filepath.Ext(inputFile) == sourceFileExt {
if err := doCompileRun(inputData, inputFile, *outputFile); err != nil {
if err := compileAndRun(inputData, inputFile); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
} else {
if err := doRun(inputData, inputFile, *outputFile); err != nil {
if err := runCompiled(inputData); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
Expand All @@ -81,27 +85,32 @@ func doHelp() {
fmt.Println()
fmt.Println("Flags:")
fmt.Println()
fmt.Println(" -c/-compile compile the input and produce bytecode file")
fmt.Println(" -o output")
fmt.Println(" -o compile output file")
fmt.Println(" -version show version")
fmt.Println()
fmt.Println("Examples:")
fmt.Println()
fmt.Println(" tengo")
fmt.Println(" : Start Tengo REPL")
fmt.Println()
fmt.Println(" Start Tengo REPL")
fmt.Println()
fmt.Println(" tengo myapp.tengo")
fmt.Println(" : Compile and execute source file (myapp.tengo)")
fmt.Println()
fmt.Println(" tengo -c myapp myapp.tengo")
fmt.Println(" : Compile source file (myapp.tengo) and produce bytecode file (myapp)")
fmt.Println(" Compile and run source file (myapp.tengo)")
fmt.Println(" Source file must have .tengo extension")
fmt.Println()
fmt.Println(" tengo -o myapp myapp.tengo")
fmt.Println()
fmt.Println(" Compile source file (myapp.tengo) into bytecode file (myapp)")
fmt.Println()
fmt.Println(" tengo myapp")
fmt.Println(" : Execute bytecode file (myapp)")
fmt.Println()
fmt.Println(" Run bytecode file (myapp)")
fmt.Println()
fmt.Println()
}

func doCompile(data []byte, inputFile, outputFile string) (err error) {
func compileOnly(data []byte, inputFile, outputFile string) (err error) {
bytecode, err := compileSrc(data, filepath.Base(inputFile))
if err != nil {
return
Expand Down Expand Up @@ -133,7 +142,7 @@ func doCompile(data []byte, inputFile, outputFile string) (err error) {
return
}

func doCompileRun(data []byte, inputFile, _ string) (err error) {
func compileAndRun(data []byte, inputFile string) (err error) {
bytecode, err := compileSrc(data, filepath.Base(inputFile))
if err != nil {
return
Expand All @@ -149,7 +158,7 @@ func doCompileRun(data []byte, inputFile, _ string) (err error) {
return
}

func doRun(data []byte, _, _ string) (err error) {
func runCompiled(data []byte) (err error) {
bytecode := &compiler.Bytecode{}
err = bytecode.Decode(bytes.NewReader(data))
if err != nil {
Expand All @@ -166,7 +175,7 @@ func doRun(data []byte, _, _ string) (err error) {
return
}

func doRepl(in io.Reader, out io.Writer) {
func runREPL(in io.Reader, out io.Writer) {
stdin := bufio.NewScanner(in)

fileSet := source.NewFileSet()
Expand Down
17 changes: 5 additions & 12 deletions compiler/ast/return_stmt.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package ast

import (
"strings"

"github.com/d5/tengo/compiler/source"
)

// ReturnStmt represents a return statement.
type ReturnStmt struct {
ReturnPos source.Pos
Results []Expr
Result Expr
}

func (s *ReturnStmt) stmtNode() {}
Expand All @@ -21,21 +19,16 @@ func (s *ReturnStmt) Pos() source.Pos {

// End returns the position of first character immediately after the node.
func (s *ReturnStmt) End() source.Pos {
if n := len(s.Results); n > 0 {
return s.Results[n-1].End()
if s.Result != nil {
return s.Result.End()
}

return s.ReturnPos + 6
}

func (s *ReturnStmt) String() string {
if len(s.Results) > 0 {
var res []string
for _, e := range s.Results {
res = append(res, e.String())
}

return "return " + strings.Join(res, ", ")
if s.Result != nil {
return "return " + s.Result.String()
}

return "return"
Expand Down
1 change: 1 addition & 0 deletions compiler/bytecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,5 @@ func init() {
gob.Register(&objects.MapIterator{})
gob.Register(&objects.ArrayIterator{})
gob.Register(&objects.Time{})
gob.Register(&objects.CompiledModule{})
}
6 changes: 3 additions & 3 deletions compiler/bytecode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,20 @@ func TestBytecode(t *testing.T) {
compiler.MakeInstruction(compiler.OpAdd),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpAdd),
compiler.MakeInstruction(compiler.OpReturnValue, 1)),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 2),
compiler.MakeInstruction(compiler.OpSetLocal, 0),
compiler.MakeInstruction(compiler.OpGetFree, 0),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpClosure, 4, 2),
compiler.MakeInstruction(compiler.OpReturnValue, 1)),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 1),
compiler.MakeInstruction(compiler.OpSetLocal, 0),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpClosure, 5, 1),
compiler.MakeInstruction(compiler.OpReturnValue, 1)))))
compiler.MakeInstruction(compiler.OpReturnValue)))))
}

func testBytecodeSerialization(t *testing.T, b *compiler.Bytecode) {
Expand Down
11 changes: 4 additions & 7 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,17 +426,14 @@ func (c *Compiler) Compile(node ast.Node) error {
return fmt.Errorf("return statement outside function")
}

switch len(node.Results) {
case 0:
if node.Result == nil {
c.emit(OpReturn)
case 1:
if err := c.Compile(node.Results[0]); err != nil {
} else {
if err := c.Compile(node.Result); err != nil {
return err
}

c.emit(OpReturnValue, 1)
default:
return fmt.Errorf("multi-value return not implemented")
c.emit(OpReturnValue)
}

case *ast.CallExpr:
Expand Down
Loading

0 comments on commit f7b0cd8

Please sign in to comment.