Giter VIP home page Giter VIP logo

tre's Introduction

tre

A LLVM backed Go compiler.

tre is built in Go and can compile a subset of Go code to LLVM IR. Clang is used to compile the IR to an executable.

Building

# Build tre and run a test program
go build ./cmd/tre && ./tre -d ./compiler/testdata/fib.go && ./fib

Example

Example program that calculates the fibonacci sequence.

func fib(num int) int {
    if num < 2 {
        return num
    }

    return fib(num-2) + fib(num-1)
}

func main() {
    printf("%d\n", fib(34))
}

More examples of what's possible can be found in the compiler testdata.

Features

Types

  • int
  • string
  • struct
  • array
  • slice
  • map
  • bool
  • func
  • chan

Language features

Dependencies

tre's People

Contributors

bors[bot] avatar dependabot-preview[bot] avatar dependabot-support avatar mewmew avatar prologic avatar zegl 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  avatar  avatar  avatar

tre's Issues

Negative numbers issue

I tried to compile the following program:

package main

import "external"

func main() {
	foo := -4
	external.Printf("foo is = %d\n", foo)
}

It failed with the following panic

2019/03/23 19:40:45 unable to handle default: 16 - {Type:OPERATOR, Val:-, Line:6}
panic: unable to handle default: 16 - {Type:OPERATOR, Val:-, Line:6}

type: string

Allow to use string as a type identifier.

Add basic string manipulation functions, such as concatenation, substringing, and getting the length of a string.

  • Custom string type #22
  • len() #22
  • Concatenation #23
  • Substringing

Arithmetic should be prioritized left to right

Program:

package main

import "external"

func main() {
	a := 17
	b := a * 4 / 9
	external.Printf("%d\n", b)
}

Generated IR:

target triple = "x86_64-apple-macosx10.13.0"

%string = type { i64, i8* }

@str.0 = constant [1 x i8] c"\00"
@str.1 = constant [4 x i8] c"%d\0A\00"

declare i32 @printf(i8*, ...)

define i32 @main() {
block-0:
	%a-1 = alloca i64
	store i64 17, i64* %a-1
	%0 = sdiv i64 4, 9
	%1 = load i64, i64* %a-1
	%2 = mul i64 %1, %0
	%b-2 = alloca i64
	store i64 %2, i64* %b-2
	%3 = alloca %string
	%4 = getelementptr %string, %string* %3, i32 0, i32 0
	store i64 3, i64* %4
	%5 = getelementptr %string, %string* %3, i32 0, i32 1
	%6 = getelementptr [4 x i8], [4 x i8]* @str.1, i64 0, i64 0
	store i8* %6, i8** %5
	%7 = load %string, %string* %3
	%8 = extractvalue %string %7, 1
	%9 = load i64, i64* %b-2
	%10 = call i32 (i8*, ...) @printf(i8* %8, i64 %9)
	ret i32 0
}

Output: 0
Expected output: 7

invalid callee type; expected *types.FuncType, got *types.PointerType

The following program parses correctly, but the compilation to LLVM IR fails:

package main

import (
	"external"
)

func main() {
	var f1 func(int) int

	f1 = func(a int) int {
		return a + 1
	}

	external.Printf("%d\n", f1(2))
}
2020/01/03 16:16:32 invalid callee type; expected *types.FuncType, got *types.PointerType

Internal compiler stacktrace:
goroutine 1 [running]:
runtime/debug.Stack(0xc0000ea500, 0x1, 0x1)
	/Users/gustav/src/go/src/runtime/debug/stack.go:24 +0x9d
github.com/zegl/tre/compiler/compiler.(*Compiler).Compile.func1(0xc0000ebba8)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:139 +0x175
panic(0x1198260, 0xc000096bb0)
	/Users/gustav/src/go/src/runtime/panic.go:679 +0x1b2
github.com/llir/llvm/ir.(*InstCall).Sig(0xc0000f00e0, 0xc0000f00e0)
	/Users/gustav/go/pkg/mod/github.com/llir/[email protected]/ir/inst_other.go:420 +0x1a0
github.com/llir/llvm/ir.(*InstCall).Type(...)
	/Users/gustav/go/pkg/mod/github.com/llir/[email protected]/ir/inst_other.go:350
github.com/llir/llvm/ir.NewCall(0x12151a0, 0xc0000d25b0, 0xc000096ba0, 0x1, 0x1, 0x0)
	/Users/gustav/go/pkg/mod/github.com/llir/[email protected]/ir/inst_other.go:336 +0x9e
github.com/llir/llvm/ir.(*Block).NewCall(...)
	/Users/gustav/go/pkg/mod/github.com/llir/[email protected]/ir/block_other.go:59
github.com/zegl/tre/compiler/compiler.(*Compiler).compileCallNode(0xc0000ce000, 0xc000099170, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/func.go:533 +0x901
github.com/zegl/tre/compiler/compiler.(*Compiler).compileValue(0xc0000ce000, 0x1213f60, 0xc000099170, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:286 +0x459
github.com/zegl/tre/compiler/compiler.(*Compiler).compileCallNode(0xc0000ce000, 0xc0000991a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/func.go:463 +0x1620
github.com/zegl/tre/compiler/compiler.(*Compiler).compileValue(0xc0000ce000, 0x1213f60, 0xc0000991a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:286 +0x459
github.com/zegl/tre/compiler/compiler.(*Compiler).compile(0xc0000ce000, 0xc0000d0800, 0x3, 0x4)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:220 +0x127
github.com/zegl/tre/compiler/compiler.(*Compiler).compileDefineFuncNode(0xc0000ce000, 0xc0000d4100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/func.go:229 +0x1255
github.com/zegl/tre/compiler/compiler.(*Compiler).compile(0xc0000ce000, 0xc0000d0840, 0x3, 0x4)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:183 +0x1da
github.com/zegl/tre/compiler/compiler.(*Compiler).Compile(0xc0000ce000, 0xc0000a66c0, 0x1, 0x1, 0x11d43e9, 0x4, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:151 +0x196
github.com/zegl/tre/cmd/tre/build.compilePackage(0xc0000ce000, 0x7ffeefbffa41, 0x22, 0xc0000ebf30, 0x2, 0x2, 0x11d43e9, 0x4, 0x19, 0xc000052e68)
	/Users/gustav/src/tre/cmd/tre/build/build.go:164 +0x2e4
github.com/zegl/tre/cmd/tre/build.Build(0x7ffeefbffa41, 0x22, 0xc0000dbf30, 0x2, 0x2, 0x7ffeefbffa53, 0xd, 0xc000050001, 0x19, 0xc0000c0320)
	/Users/gustav/src/tre/cmd/tre/build/build.go:24 +0xac
main.main()
	/Users/gustav/src/tre/cmd/tre/main.go:52 +0x327

compiler: reduce amount of load and alloca instructions

The following short program:

func fib(num i64) i64 {
    if num < 2 {
        return num
    }

    return fib(num-2) + fib(num-1)
}

func main() i64 {
    printf("%d\n", fib(40))
    return 0
}

Is compiled into the following LLVM IR:

target triple = "x86_64-apple-macosx10.13.0"

@str.0 = constant [4 x i8] c"%d\0A\00"

declare i32 @printf(i8*, ...)

define i64 @fib(i64 %num-parameter) {
block-0:
	%0 = alloca i64
	%num = alloca i64
	store i64 %num-parameter, i64* %num
	%1 = alloca i64
	%2 = load i64, i64* %num
	store i64 %2, i64* %1
	%3 = alloca i64
	store i64 2, i64* %3
	%4 = alloca i64
	%5 = load i64, i64* %3
	store i64 %5, i64* %4
	%6 = load i64, i64* %1
	%7 = load i64, i64* %4
	%8 = icmp slt i64 %6, %7
	br i1 %8, label %block-3-true, label %block-4-false
block-1-return:
	%9 = load i64, i64* %0
	ret i64 %9
block-2-after:
	%10 = alloca i64
	store i64 2, i64* %10
	%11 = load i64, i64* %num
	%12 = load i64, i64* %10
	%13 = alloca i64
	%14 = sub i64 %11, %12
	store i64 %14, i64* %13
	%15 = load i64, i64* %13
	%16 = alloca i64
	%17 = call i64 @fib(i64 %15)
	store i64 %17, i64* %16
	%18 = alloca i64
	store i64 1, i64* %18
	%19 = load i64, i64* %num
	%20 = load i64, i64* %18
	%21 = alloca i64
	%22 = sub i64 %19, %20
	store i64 %22, i64* %21
	%23 = load i64, i64* %21
	%24 = alloca i64
	%25 = call i64 @fib(i64 %23)
	store i64 %25, i64* %24
	%26 = load i64, i64* %16
	%27 = load i64, i64* %24
	%28 = alloca i64
	%29 = add i64 %26, %27
	store i64 %29, i64* %28
	%30 = load i64, i64* %28
	store i64 %30, i64* %0
	br label %block-1-return
block-3-true:
	%31 = load i64, i64* %num
	store i64 %31, i64* %0
	br label %block-1-return
block-4-false:
	br label %block-2-after
}

define i64 @main() {
block-5:
	%0 = alloca i64
	%1 = getelementptr [4 x i8], [4 x i8]* @str.0, i64 0, i64 0
	%2 = alloca i64
	store i64 40, i64* %2
	%3 = load i64, i64* %2
	%4 = alloca i64
	%5 = call i64 @fib(i64 %3)
	store i64 %5, i64* %4
	%6 = load i64, i64* %4
	%7 = alloca i32
	%8 = call i32 (i8*, ...) @printf(i8* %1, i64 %6)
	store i32 %8, i32* %7
	%9 = alloca i64
	store i64 0, i64* %9
	%10 = load i64, i64* %9
	store i64 %10, i64* %0
	br label %block-6-return
block-6-return:
	%11 = load i64, i64* %0
	ret i64 %11
}

Clang with -03 will optimize the code above into:

; ModuleID = 'tre-ll/fib.ll'
source_filename = "tre-ll/fib.ll"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.13.0"

@str.0 = constant [4 x i8] c"%d\0A\00"

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #0

; Function Attrs: nounwind readnone
define i64 @fib(i64 %num-parameter) local_unnamed_addr #1 {
block-0:
  %0 = icmp slt i64 %num-parameter, 2
  br i1 %0, label %block-1-return, label %block-4-false

block-1-return:                                   ; preds = %block-0
  ret i64 %num-parameter

block-4-false:                                    ; preds = %block-0
  %1 = add i64 %num-parameter, -2
  %2 = tail call i64 @fib(i64 %1)
  %3 = add i64 %num-parameter, -1
  %4 = tail call i64 @fib(i64 %3)
  %5 = add i64 %4, %2
  ret i64 %5
}

; Function Attrs: nounwind
define i64 @main() local_unnamed_addr #0 {
block-5:
  %0 = tail call i64 @fib(i64 40)
  %1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str.0, i64 0, i64 0), i64 %0)
  ret i64 0
}

attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }

If the code generated by tre would be smarter, clang wouldn't have to work as hard to generate fast code.


Progress

The -O3 generated version is 29 lines long (when comments and attributes has been removed), and would be considered the most optimal solution. I don't have a goal, but reducing the amount of instructions by 50%, to 45, would be a great start.

Change Rows of generated code (~amount of instructions)
Original 89
Raw int constants: #16 74
Fewer condition instructions: #17 69
Fewer call and operation instructions: #18 49
Function setup and return: #19 29 ๐ŸŽ‰

Long form variable declaration and assignment

The following program fails:

package main

import (
	"external"
)

func main() {
	var i int = 10
	external.Printf("%d\n", i)
}

Trace:

2019/12/26 21:06:33 unable to handle default: 21 - {Type:OPERATOR, Val:=, Line:8}
panic: unable to handle default: 21 - {Type:OPERATOR, Val:=, Line:8}

goroutine 1 [running]:
log.Panicf(0x11c79dd, 0x22, 0xc00011f588, 0x2, 0x2)
	/Users/gustav/src/go/src/log/log.go:345 +0xc0
github.com/zegl/tre/compiler/parser.(*parser).parseOneWithOptions(0xc00011fb28, 0x10101, 0xc0000b2060, 0xc0000f8040)
	/Users/gustav/src/tre/compiler/parser/parser.go:589 +0x2508
github.com/zegl/tre/compiler/parser.(*parser).parseOne(0xc00010fb28, 0x1, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:49 +0x3c
github.com/zegl/tre/compiler/parser.(*parser).parseUntilEither(0xc00011fb28, 0xc00011f728, 0x1, 0x1, 0x0, 0x8, 0x20300000000000, 0xc0000b2030, 0xc0000f4070, 0xc000052748, ...)
	/Users/gustav/src/tre/compiler/parser/parser.go:966 +0x16f
github.com/zegl/tre/compiler/parser.(*parser).parseUntil(0xc000052b28, 0x5, 0x11c0a3a, 0x1, 0x0, 0x20300000000000, 0x16fffff, 0xc000052810)
	/Users/gustav/src/tre/compiler/parser/parser.go:942 +0x97
github.com/zegl/tre/compiler/parser.(*parser).parseOneWithOptions(0xc00011fb28, 0x10101, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:447 +0xec3
github.com/zegl/tre/compiler/parser.(*parser).parseOne(0xc000052b28, 0xc0000b2001, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:49 +0x3c
github.com/zegl/tre/compiler/parser.(*parser).parseUntilEither(0xc00011fb28, 0xc00011fab0, 0x1, 0x1, 0xc000052af0, 0x8402b31d, 0xbbcd90b3491ffdd5, 0x100d648, 0xbb000000011855c0, 0xc000106001, ...)
	/Users/gustav/src/tre/compiler/parser/parser.go:966 +0x16f
github.com/zegl/tre/compiler/parser.(*parser).parseUntil(0xc000052b28, 0xc000106006, 0x0, 0x0, 0x0, 0x18, 0xc0000f41fa, 0xc0000f4280)
	/Users/gustav/src/tre/compiler/parser/parser.go:942 +0x97
github.com/zegl/tre/compiler/parser.Parse(0xc000104000, 0x59, 0x80, 0x1, 0x80, 0x109, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:44 +0x2e6
github.com/zegl/tre/cmd/tre/build.parseFile(0x7ffeefbffa99, 0x1a, 0x11ff9a0, 0xc0000b4f70, 0x0)
	/Users/gustav/src/tre/cmd/tre/build/build.go:177 +0xbc
github.com/zegl/tre/cmd/tre/build.compilePackage(0xc0000e2140, 0x7ffeefbffa99, 0x1a, 0xc0000c2020, 0x19, 0x11c0d00, 0x4, 0x19, 0xc000052e80)
	/Users/gustav/src/tre/cmd/tre/build/build.go:103 +0xbc
github.com/zegl/tre/cmd/tre/build.Build(0x7ffeefbffa99, 0x1a, 0xc0000c2020, 0x19, 0x7ffeefbffaab, 0x5, 0x1, 0xc000052f10, 0x19)
	/Users/gustav/src/tre/cmd/tre/build/build.go:24 +0x9f
main.main()
	/Users/gustav/src/tre/cmd/tre/main.go:48 +0x2fd

feature: First class functions

  • Assign a func to a variable
  • Execute func from variable
  • Clojures (variables outside the func are available inside the func)

slice: Tests are failing on Mac OS

    --- FAIL: TestAllPrograms/slice_append_assign.go (0.07s)
    	compiler_test.go:89: Expected:
    		---
    		'2
    		2
    		3
    		3
    		1 2 4
    		1 2 3'
    		---
    		Result:
    		---
    		'2
    		2
    		3
    		3
    		1 2 4
    		1 2 1'
    		---

only create the same string once

It's not uncommon that the compiler creates code that looks like this

@str.1 = constant [4 x i8] c"%s\0A\00"

@str.2 = constant [48 x i8] c"runtime panic: Substring start larger than len\0A\00"

@str.3 = constant [4 x i8] c"%s\0A\00"

@str.4 = constant [48 x i8] c"runtime panic: Substring start larger than len\0A\00"

@str.5 = constant [4 x i8] c"%s\0A\00"

@str.6 = constant [48 x i8] c"runtime panic: Substring start larger than len\0A\00"

AllocMulti from two consts fails

package main

import "external"

func main() {
	a, b := 1, 2
	external.Printf("%d", a)
	external.Printf("%d", b)
}
aheadParse: {Type:EOL, Val:, Line:16} - *parser.DefineFuncNode func+n main([]) [] {
	allocMulti(vars([var(n:a t:%!s(<nil>)) var(n:b t:%!s(<nil>))])) = const(1)
	const(2)
	CallNode: load(var(n:external t:%!s(<nil>)) . Printf)([%d var(n:a t:%!s(<nil>))])
	CallNode: load(var(n:external t:%!s(<nil>)) . Printf)([%d var(n:b t:%!s(<nil>))])
}
2019/02/24 14:50:39 undefined variable: a

Internal compiler stacktrace:
goroutine 1 [running]:
runtime/debug.Stack(0xc0000b83f8, 0x1, 0x1)
	/usr/local/Cellar/go/1.11.5/libexec/src/runtime/debug/stack.go:24 +0xa7
github.com/zegl/tre/compiler/compiler.(*Compiler).Compile.func1(0xc0000b9c10)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:132 +0x172
panic(0x113b5e0, 0xc00004e810)
	/usr/local/Cellar/go/1.11.5/libexec/src/runtime/panic.go:513 +0x1b9
github.com/zegl/tre/compiler/compiler.(*Compiler).varByName(0xc000094000, 0x12839e1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:249 +0x45d
github.com/zegl/tre/compiler/compiler.(*Compiler).compileValue(0xc000094000, 0x119b6e0, 0xc00000a4c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:272 +0xcd5

Set correct length of substring

// Save length of the string
lenItem := safeBlock.NewGetElementPtr(alloc, constant.NewInt(llvmTypes.I32, 0), constant.NewInt(llvmTypes.I32, 0))
lenItem.SetName(name.Var("len"))
safeBlock.NewStore(constant.NewInt(llvmTypes.I64, 100), lenItem) // TODO

init() functions

Extend the existing initGlobalsFunc call additional user defined init() funcs.

In which order should inits() be called?

feature: range

  • for k, v := range []int{10, 20, 30}
  • for k := range []int{10, 20, 30}
  • for range []int{10, 20, 30}
  • for _, v := range []int{10, 20, 30}
  • for k, v := range []int{10, 20, 30}[1:]
  • for k, v := range map
  • for k, v := range array
  • for k, v := range fn()

feature: integer type detection

var a int8
a = 100

currently generates the following IR:

define i32 @main() {
block-0:
	%a = alloca i8
	store i8 0, i8* %a
	store i64 100, i8* %a
	ret i32 0
}

Unable to assign pointer to struct

This program does not compile, but it should:

package main

import "external"

type mytype struct{
	a int
}

func main() {
	var foo *mytype
	foo = &mytype{}
	foo.a = 100
	external.Printf("%d\n", foo.a) // 100
}
/var/folders/j8/bql3r25941g50x70qxhsjtcw0000gn/T/tre055838261/main.ll:42:21: error: store operand must be a pointer
        store %mytype* %2, %mytype %1
                           ^
1 error generated.

https://play.golang.org/p/OZqGGLQezNZ

Compilation of func in struct fails

package main

import "external"

type a struct {
	fn func(int) int
}

func main() {
	v := a {
		fn: func(a int) int {
			return a + 1
		},
	}

	external.Printf("%+d\n", v.fn(2))
}
FileNode:
	DeclarePackageNode(main)
	import (external)
	defineType a = StructTypeNode([func([type(int)])([type(int)])])
	func+n main([]) [] {
	alloc([v]) = [InitializeStructNode-type(a){map[fn:func+v ([var(n:a t:type(int))]) [var(n: t:type(int))] {
	return([OP(var(a) + const(1))])
}]}] (escapes: false)
	CallNode: load(var(external).Printf)([%+d
 CallNode: load(var(v).fn)([const(2)])])
}
2020/01/03 16:19:42 runtime error: invalid memory address or nil pointer dereference

Internal compiler stacktrace:
goroutine 1 [running]:
runtime/debug.Stack(0xc0000cec50, 0x1, 0x1)
	/Users/gustav/src/go/src/runtime/debug/stack.go:24 +0x9d
github.com/zegl/tre/compiler/compiler.(*Compiler).Compile.func1(0xc0000cfba8)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:139 +0x175
panic(0x119a6c0, 0x132ada0)
	/Users/gustav/src/go/src/runtime/panic.go:679 +0x1b2
github.com/zegl/tre/compiler/compiler.(*Compiler).compileCallNode(0xc0000b4000, 0xc000013230, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/func.go:498 +0xe67
github.com/zegl/tre/compiler/compiler.(*Compiler).compileValue(0xc0000b4000, 0x1213f60, 0xc000013230, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:286 +0x459
github.com/zegl/tre/compiler/compiler.(*Compiler).compile(0xc0000b4000, 0xc00000e5a0, 0x2, 0x2)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:220 +0x127
github.com/zegl/tre/compiler/compiler.(*Compiler).compileDefineFuncNode(0xc0000b4000, 0xc0000b8100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/func.go:229 +0x1255
github.com/zegl/tre/compiler/compiler.(*Compiler).compile(0xc0000b4000, 0xc0000228c0, 0x4, 0x4)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:183 +0x1da
github.com/zegl/tre/compiler/compiler.(*Compiler).Compile(0xc0000b4000, 0xc00000e7c0, 0x1, 0x1, 0x11d43e9, 0x4, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/compiler/compiler.go:151 +0x196
github.com/zegl/tre/cmd/tre/build.compilePackage(0xc0000b4000, 0x7ffeefbffa41, 0x22, 0xc0000cff30, 0x2, 0x2, 0x11d43e9, 0x4, 0x19, 0xc000057e68)
	/Users/gustav/src/tre/cmd/tre/build/build.go:164 +0x2e4
github.com/zegl/tre/cmd/tre/build.Build(0x7ffeefbffa41, 0x22, 0xc0000bff30, 0x2, 0x2, 0x7ffeefbffa53, 0xd, 0xc000050001, 0x19, 0xc0000a6320)
	/Users/gustav/src/tre/cmd/tre/build/build.go:24 +0xac
main.main()
	/Users/gustav/src/tre/cmd/tre/main.go:52 +0x327

feature: Interfaces

  • Empty interfaces
  • Type casting from empty interfaces
  • Interfaces with required methods
  • Call methods on interface
  • Method / value receivers

feature: package variables

  • get/set
  • zero initializing
  • initialize with constant value (var name string = "foo")
  • init from call (var name = f())

Parsing type from other package fails

The following program does not parse, which should be possible, even if sub does not exist.

package main

import (
	"sub"
)

func main() {
	var f sub.Foo
}
2020/01/03 16:23:50 unable to handle default: 26 - {Type:OPERATOR, Val:., Line:12}
panic: unable to handle default: 26 - {Type:OPERATOR, Val:., Line:12}

goroutine 1 [running]:
log.Panicf(0x11db137, 0x22, 0xc0000e34e0, 0x2, 0x2)
	/Users/gustav/src/go/src/log/log.go:345 +0xc0
github.com/zegl/tre/compiler/parser.(*parser).parseOneWithOptions(0xc0000e3a88, 0x10101, 0xc000092870, 0xc000084840)
	/Users/gustav/src/tre/compiler/parser/parser.go:598 +0x25f5
github.com/zegl/tre/compiler/parser.(*parser).parseOne(0xc0000e3a88, 0x11d4001, 0x1, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:49 +0x3c
github.com/zegl/tre/compiler/parser.(*parser).parseUntilEither(0xc0000e3a88, 0xc0000e3680, 0x1, 0x1, 0x0, 0x3, 0x400, 0xc0000a2320, 0xc0000ac30a, 0xc0000e36a0, ...)
	/Users/gustav/src/tre/compiler/parser/parser.go:975 +0x16f
github.com/zegl/tre/compiler/parser.(*parser).parseUntil(0xc0000e3a88, 0x4, 0x11d40fc, 0x1, 0x0, 0x400, 0x1507600, 0x20300000000000)
	/Users/gustav/src/tre/compiler/parser/parser.go:951 +0x97
github.com/zegl/tre/compiler/parser.(*parser).parseOneWithOptions(0xc0000e3a88, 0x10101, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:456 +0xec0
github.com/zegl/tre/compiler/parser.(*parser).parseOne(0xc0000e3a88, 0xc000092801, 0x0, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:49 +0x3c
github.com/zegl/tre/compiler/parser.(*parser).parseUntilEither(0xc0000e3a88, 0xc0000e3a10, 0x1, 0x1, 0xc0000e3a50, 0xe6684204, 0xe7b67620e3df949d, 0x100d648, 0xe700000001197680, 0xc000095001, ...)
	/Users/gustav/src/tre/compiler/parser/parser.go:975 +0x16f
github.com/zegl/tre/compiler/parser.(*parser).parseUntil(0xc0000e3a88, 0xc000095005, 0x0, 0x0, 0x0, 0x18, 0xc0000e3a28, 0xc0000ac3e4)
	/Users/gustav/src/tre/compiler/parser/parser.go:951 +0x97
github.com/zegl/tre/compiler/parser.Parse(0xc0000ea000, 0x35, 0x40, 0x1, 0x40, 0xa2, 0x0)
	/Users/gustav/src/tre/compiler/parser/parser.go:44 +0x2e6
github.com/zegl/tre/cmd/tre/build.parseFile(0x7ffeefbffa39, 0x27, 0x1, 0xc000097a00, 0x0)
	/Users/gustav/src/tre/cmd/tre/build/build.go:183 +0x12f
github.com/zegl/tre/cmd/tre/build.compilePackage(0xc0000c8000, 0x7ffeefbffa39, 0x27, 0xc0000e3f30, 0x2, 0x2, 0x11d43e9, 0x4, 0x19, 0xc000052e68)
	/Users/gustav/src/tre/cmd/tre/build/build.go:105 +0x144
github.com/zegl/tre/cmd/tre/build.Build(0x7ffeefbffa39, 0x27, 0xc0000d3f30, 0x2, 0x2, 0x7ffeefbffa59, 0x4, 0xc000050001, 0x19, 0xc0000ba320)
	/Users/gustav/src/tre/cmd/tre/build/build.go:24 +0xac
main.main()
	/Users/gustav/src/tre/cmd/tre/main.go:52 +0x327

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.